# Webhook Setup

## Introduction

Startbahn offers integration messages on events happening on your Licensed User Wallet via webhooks.

A webhook is an HTTP POST call to an endpoint of your choice. To authenticate the call, Startbahn will send a secret API Key in the HTTP Header ‘x-api-key’. The System expects your endpoint to respond with a success code 2xx.

Note that, in case of no response from the configured endpoint or HTTP error codes such as 4xx and 5xx, the system retries up to a desired number of times (maximum 5). After all of the retries have failed, Startbahn sends an informational email to a configurable admin email address (which can be different from your regular user addresses), containing the data in a CSV format, and will not continue to send the same data again.

You can get subscribed to webhooks. Currently, the webhook subscriptions are not available for self-service, but the Startbahn team can subscribe you to the desired webhook events outlined in the following chapters and configure your API key and URL endpoint.

## Webhook Details

{% hint style="info" %}
Please note that we may add a new field. So make sure that your implementation can support accepting new fields without breaking your implementation. In case we remove the field, we will deprecate it first and let you know beforehand.
{% endhint %}

The following chapters provide details about the webhook events you can subscribe to.

### **Generic Parameter Details**

<mark style="color:red;">`*`</mark> indicates that the field will always exist from Startbahn side.

<table><thead><tr><th width="283">Parameter</th><th width="148">Webhook Type</th><th width="237">Description</th><th width="234">Format</th><th></th></tr></thead><tbody><tr><td>type<mark style="color:red;">*</mark></td><td>All</td><td>The type of the webhook</td><td>ENUM consists of <code>transfer_key</code> , <code>transfer_complete</code>, <code>issue_complete</code></td><td></td></tr><tr><td>version<mark style="color:red;">*</mark></td><td>All</td><td>The version of the webhook.</td><td>number</td><td></td></tr><tr><td>data<mark style="color:red;">*</mark></td><td>All</td><td>The data related to the webhook that client’s need to process.</td><td>Array</td><td></td></tr><tr><td>data[*].groupId<mark style="color:red;">*</mark></td><td>All</td><td>This groupId may not be really important for client. String to identify the grouping. Webhook data payload with same group ID will be sent to client in 1 batch.</td><td>string</td><td></td></tr></tbody></table>

## SRR Related

### Generic SRR Related Parameter

Additional from Generic Parameter Details, these fields exist in webhook payload of all events related to SRR.

{% hint style="warning" %}
**`data[*].metadata` shape change**

`data[*].metadata` is now the **raw SRR metadata JSON** (i.e. the same object you can fetch from the [Startrail IPFS CDN gateway](/subgraph/ipfs-cdn-gateway.md) at `https://cdn.startrail.io/ipfs/<cid>`). It is no longer wrapped in a `{ digest, json, createdAt, updatedAt, cid }` envelope. The CID is conveyed separately via `data[*].srrCid` on `issueComplete`; for `transferReservationComplete` / `transferExecutionComplete`, look the SRR up on the [subgraph](/subgraph/subgraph.md) by `srrId` to get the current `metadataDigest`.
{% endhint %}

<table><thead><tr><th width="283">Parameter</th><th width="148">Webhook Type</th><th width="237">Description</th><th width="234">Format</th></tr></thead><tbody><tr><td>data[*].srrId<mark style="color:red;">*</mark></td><td>All</td><td>SRR Token ID</td><td>string</td></tr><tr><td>data[*].metadata</td><td>All</td><td>Raw SRR metadata JSON. See <a href="/pages/hx1j9Oc1YPYQy3C93RIm">Metadata Schema</a> for the schema.</td><td>Object</td></tr></tbody></table>

### Webhook Event: Issuance of SRR completed

#### Subscription Name

`issueComplete`

#### Trigger

After an SRR has been minted, the subscribed issuer receives this notification

#### Content

An array of data for the issued SRR where each entry consists of the metadata, `srrId` and `srrCid`.<br>

* | Parameter        | Webhook Type  | Description                                                                                                                      | Format |
  | ---------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------ |
  | data\[\*].srrCid | issueComplete | CID of the SRR metadata in IPFS. Refer to [CID Documentation](https://docs.ipfs.tech/concepts/content-addressing/#what-is-a-cid) | string |
* Content Example

  ```json
  {
     "type":"issue_complete",
     "version":1,
     "data":[
        {
           "groupId":"123456789012",
           "srrId":"123456789012",
           "srrCid":"bafkreid6i2u5b26hepprrkcswqoknzpyl2mrvuoy2ewuktj6ye5bxl3mby",
           "metadata":{
              "$schema":"https://api.startrail.io/api/v1/schema/registry-record-metadata.v2.1.schema.json",
              "$schemaIntegrity":"sha256-fff288406b907ee6472585388bf519573628e45592be368f128b5b1e37a947c9",
              "startbahnCertICTagUIDs":[
                 "1234567890abcdef"
              ],
              "title":{
                 "en":"A title",
                 "ja":"タイトル",
                 "zh":"一个标题"
              },
              "size":{
                 "width":200,
                 "height":400,
                 "depth":12.4,
                 "unit":"pixel",
                 "flexibleDescription":{
                    "en":"flexibleDescription comes here",
                    "ja":"自由だーーー"
                 }
              },
              "medium":{
                 "en":"Oil on canvas",
                 "ja":"キャンバスに油彩",
                 "zh":"布面油画"
              },
              "edition":{
                 "uniqueness":"unique work",
                 "proofType":"ED",
                 "number":1,
                 "totalNumber":3,
                 "note":{
                    "en":"some extra notes in 1 or more languages"
                 }
              },
              "contractTerms":{
                 "royaltyRate":15.7,
                 "fileURL":"https://startrail.io/whitepaper/startrail_wp_en_v1.1.pdf"
              },
              "note":{
                 "en":"note",
                 "zh":"注意"
              },
              "thumbnailURL":"https://cdn.startrail.io/ipfs/bafkreigb2wjgin53xgmaiqxvdn4g2iw6cnmp4e3w3nzopmom53sjborque",
              "yearOfCreation":{
                 "en":"around 2010-2020",
                 "ja":"2010年から2020年頃"
              },
              "isDigital":true,
              "digitalDataHash":"sha256-247e4b904322a1dd0b148cd77e8627ec7d391251380880ab4621726ecb945ef5"
           }
        }
     ]
  }
  ```

### Webhook Event: Transfer reservation of SRR completed with Transfer Key

#### Subscription Name

`transferReservationComplete`

#### Trigger

After the start of an SRR Transfer using the `Generate Transfer Key` has been confirmed, the subscribed old owner will receive this notification.

#### Content

An array of data signaling that a transfer was reserved on-chain for one of your SRRs. Currently the payload contains only the generic SRR fields (`groupId`, `srrId`, `metadata`).

{% hint style="info" %}
The legacy `transferCid`, `dataUrl` and `encryptedTransferKey` fields are no longer included in this webhook. If you need the encrypted transfer key, fetch it via the separate transfer-key flow.
{% endhint %}

* **Parameter Details**

  No additional fields beyond the [Generic SRR Related Parameter](#generic-srr-related-parameter) table.
* **Content Example**

  ```json
  {
     "type":"transfer_key",
     "version":1,
     "data":[
        {
           "groupId":"123456789012",
           "srrId":"123456789012",
           "metadata":{
              "$schema":"https://api.startrail.io/api/v1/schema/registry-record-metadata.v2.1.schema.json",
              "title":{ "en":"A title" }
              // ... full SRR metadata JSON, same shape as on the IPFS CDN gateway
           }
        }
     ]
  }
  ```

### Webhook Event: Transfer execution of SRR completed

#### Subscription Name

`transferExecutionComplete`

#### Trigger

After an SRR has been transferred to a new user, the subscribed old owner receives this notification

#### Content

The array of data about a transfer on one of your SRRs to a new owner. Specifically contains the `srrId`, the new owner's Ethereum Address `newOwnerEoa` and the SRR `metadata`.

* **Parameter Details**\ <mark style="color:red;">`*`</mark> indicates that the field will always exist from Startbahn side.<br>

  <table><thead><tr><th width="236">Parameter</th><th width="248">Webhook Type</th><th width="237">Description</th><th>Format</th></tr></thead><tbody><tr><td>data[*].newOwnerEoa<mark style="color:red;">*</mark></td><td>transferExecutionComplete</td><td>The EOA of the SRR's new owner</td><td>string</td></tr></tbody></table>

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>The legacy <code>transferCid</code> field is no longer included on this webhook. If you need the transfer's provenance entry, query it from the <a href="/pages/DEDTJpFrrjYII6dFBDUe">subgraph</a> by <code>srrId</code>.</p></div>
* **Content Example**

  ```json
  {
     "type":"transfer_complete",
     "version":1,
     "data":[
        {
           "groupId":"123456789012",
           "srrId":"123456789012",
           "newOwnerEoa":"0x887C0d2340d2Fa144289C2E2BF835556f5c6C4E0",
           "metadata":{
              "$schema":"https://api.startrail.io/api/v1/schema/registry-record-metadata.v2.1.schema.json",
              "title":{ "en":"A title" }
              // ... full SRR metadata JSON, same shape as on the IPFS CDN gateway
           }
        }
     ]
  }
  ```

## Collection Related

### Generic Collection Related Parameter

Additional to Generic Parameter Details above, these fields exist in webhook payload of all events related to the collection.

<mark style="color:red;">`*`</mark> indicates that the field will always exist from Startbahn side.

| Parameter                                          | Webhook Type | Description              | Format |
| -------------------------------------------------- | ------------ | ------------------------ | ------ |
| data\[\*].name<mark style="color:red;">\*</mark>   | collection   | Name of the collection   | string |
| data\[\*].symbol<mark style="color:red;">\*</mark> | collection   | Symbol of the collection | string |

### Webhook Event: Collection Created

#### Subscription Name

`collectionCreated`

#### Trigger

After a collection is created.

#### Content

Array of data about the creation of collection.

**Parameter Details**\ <mark style="color:red;">`*`</mark> indicates that the field will always exist from Startbahn side.

<table><thead><tr><th width="236">Parameter</th><th width="248">Webhook Type</th><th width="237">Description</th><th>Format</th></tr></thead><tbody><tr><td>data[*].contractAddress</td><td>collectionCreated</td><td>Address of the collection</td><td>string</td></tr><tr><td>data[*].ownerAddress</td><td>collectionCreated</td><td>LUW Address of the owner</td><td>string</td></tr></tbody></table>

**Content Example**

```json
{
   "type":"transfer_complete",
   "version":1,
   "data":[
      {
         "groupId": "0x9f25c0d8eB5f461528ab5E02f1F31C77885d5Dc0collection name",
         "contractAddress": "0x229dbFE303C5706BDB570A42f0BA190621d2D032",
         "ownerAddress": "0x9f25c0d8eB5f461528ab5E02f1F31C77885d5Dc0",
         "name": "collection name",
         "symbol": "TT"
      }
   ]
}
```

### Webhook Event: Collection Create Failed

#### Subscription Name

`collectionCreateFailed`

#### Trigger

After a collection creation transaction failed to be mined.

#### Content

Array of data about failure of collection creation.

**Parameter Details**\
No additional value other than the Generic Collection Related Parameter.

**Content Example**

```json
{
   "type":"transfer_complete",
   "version":1,
   "data":[
      {
         "groupId": "0x9f25c0d8eB5f461528ab5E02f1F31C77885d5Dc0collection name",
         "ownerAddress": "0x9f25c0d8eB5f461528ab5E02f1F31C77885d5Dc0",
         "name": "collection name",
         "symbol": "TT"
      }
   ]
}
```

## Necessary data for Startbahn from our API users to integrate our webhooks into your services

To subscribe to webhooks, the API requires the following data\ <mark style="color:red;">`*`</mark> indicates required.

<table><thead><tr><th width="202">Parameter</th><th width="307">Description</th><th width="548">Format</th></tr></thead><tbody><tr><td>Webhook URL<mark style="color:red;">*</mark></td><td>The URL for API given by client where Startbahn needs to call to send the transfer key using webhook.</td><td>URL example: <code>https://www.your-company.com/srr-integration-webhooks/</code></td></tr><tr><td>API Key<mark style="color:red;">*</mark></td><td><p>Key used in Webhook for Authentication.<br></p><p>Startbahn will put this key in the Webhook authentication header, so that your system can verify incoming API call that are made by Startbahn.<br></p><p>this API key should be different from the one you use for Issue API.</p></td><td><p>Any string matching <code>^[a-zA-Z0-9_+-]{30,100}$</code></p><p>example: <code>e46b1263-e3f5-461d-bfe7-18aff21c5ed3</code></p></td></tr><tr><td>Public Key</td><td><p>RSA Key used to encrypt the Transfer Key in the Webhook.<br></p><p>The Client will hold the private key, so they can decrypt the Transfer Key.<br></p><p>This is only needed when using the transfer key integration.</p></td><td>JSON object describing the key.<br><br>example: <code>{"alg":"RSA-OAEP-256","e":"AQAB","ext":true,"key_ops":["encrypt"],"kty":"RSA","n":"yNtyR6PTWi_7Fabm6YIpLALA5YHqiY7vrjU8mdPdO1sCawbelPoP0VUi52YUFqh-io25YCOdkWNNUagD-wirb1YNFPN4kpYNZUZaJtu__33cVO36hyoPlFDUGepiPMryKjcujhTcbJvtgQQncO6JQ35LzQZR4P4xF7E5Yy1vaim1dPiUpabHBq_ILgyHAirlbVCw7DhWo3TNs0rr3MsbxOnEec2ieIa1nEP3zN60kcn9Ky6Tehr-hUtjQpKB8EftW7zdO3JF8Lz6CTyWgodAj5owrLmA9rmCTXC5o7Fhm5I8R4H5JrBmYFi2saqqtxDUi9LQk6cbQjnyfbO3OqSkRw"}</code><br><br>* You can generate a public/private key pair on this page (<a href="https://codesandbox.io/s/subtlecrypto-rsa-ttql3">https://codesandbox.io/s/subtlecrypto-rsa-ttql3</a> ) or use another solution with the same encryption parameters.</td></tr><tr><td>Number of tries</td><td><p>Number of tries of the webhook that should be made , Integer i with 1 ≤ i ≤ 5<br></p><p>If no value is specified, we will use 1 as default value</p></td><td><p>Number / Integer</p><p>Example</p><p>Value <code>1</code> = One webhook call</p><p>Value <code>2</code> = One webhook call + 1 Retry</p></td></tr><tr><td>Contact email Address</td><td><p>Email address where the email regarding failure of webhook should be sent.<br></p><p>The email will contain the same information as webhook that failed, in a csv file (e.g. for a reservation webhook: SRR ID, Encrypted Transfer Key, dataUrl, Metadata)</p></td><td>Email Address <code>admin@webhook-client.com</code></td></tr><tr><td>Webhook Events you want to subscribe to<mark style="color:red;">*</mark></td><td>Your selected webhooks. You will only receive the events you want to. It is possible to change your subscriptions for future events if needed.</td><td>List of values Subscription Name.</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.startrail.io/issue-transfer-api/issue-and-transfer-srr-nft/webhook-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
