> For the complete documentation index, see [llms.txt](https://docs.shyft.to/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.shyft.to/callbacks/callback-apis.md).

# Callback APIs

{% hint style="success" %}
Checkout structure for different type of transaction actions [here](/solana-apis/transactions/parsed-transaction-structure.md)
{% endhint %}

## List Callbacks

### <mark style="color:green;">GET</mark> /sol/v1/callback/list

Returns a list of all the callbacks registered for a user

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "<api-key>");

var requestOptions = {
  method: 'GET',
  headers: myHeaders,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/list", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks for current user",
    "result": [
        {
            "_id": "641d65b4b15af234f421a7cb",
            "events": [
                "NFT_MINT"
            ],
            "callback_url": "https://api.my-sample-server.xyz/watch-shyft",
            "network": "devnet",
            "addresses": [
                "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNk"
            ],
            "api_key": "63bcfe92a7f28c5b98a3910f"
        },
        {
            "_id": "641d65b4b15af234f421a7d1",
            "events": [
                "ANY"
            ],
            "callback_url": "https://webhook.site/1df95ebe-9c5f-473b-96f6-7e5c2c9a5274",
            "network": "devnet",
            "addresses": [
                "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj"
            ],
            "api_key": "63bcfe92a7f28c5b98a3910f"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Register a callback

### <mark style="color:blue;">POST</mark> /sol/v1/callback/create

Create a callback for addresses you are interested to monitor. Once this API is triggered, callbacks are created asynchronously and may take a minute to start sending data to the specified callback URL.

{% hint style="info" %}
You can specify `type` and create CALLBACKS (transactions), ACCOUNT and DISCORD callbacks.
{% endhint %}

#### Body

* **network**:  Solana blockchain environment (devnet / mainnet-beta).
* **addresses**: Array of addresses to watch.&#x20;
* **callback\_url**: The URL on which transaction callbacks should be sent to.
* **events** (**optional**): Array of Transaction types you are interested in. Default is `any`. Valid values for events are given [<mark style="color:red;">here</mark>](/solana-apis/transactions.md#parsed-transaction-types).
* **enable\_raw** (**optional**): Includes raw transaction information along with parsed data.
* **enable\_events** (**optional**): Includes parsed anchor events emitted in the transaction if an IDL is provided.
* **type** (**optional**): <mark style="color:yellow;">DISCORD</mark>, <mark style="color:yellow;">CALLBACK</mark> or <mark style="color:yellow;">ACCOUNT</mark>.&#x20;
* **encoding** (**optional**): <mark style="color:yellow;">RAW</mark> and <mark style="color:yellow;">PARSED</mark>. Applicable for account callbacks only. When `PARSED` is specified for programs whose IDL is present on <mark style="color:red;">T</mark>[ranslator](https://translator.shyft.to/), the callback will contain parsed information as per the IDL. If IDL is not present it will send base64 encoded data. In case of `RAW` the account data will always be in base64 format. Default is `RAW`.

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "<api-key>");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
  "network": "devnet",
  "addresses": [
    "mv3ekLzLbnVPNxjSKvqBpU3ZeZXPQdEC3bp5MDEBG68",
    "TLPv2tuSVvn3fSk8RgW3yPddkp5oFivzZV3rA9hQxtX"
  ],
  "callback_url": "YOUR-CALLBACK-URL",
  "events": [
    "NFT_MINT"
  ]
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/create", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks started for the given address",
    "result": {
        "id": "6438d74d5ef8acebadebf62e",
        "network": "devnet",
        "addresses": [
            "mv3ekLzLbnVPNxjSKvqBpU3ZeZXPQdEC3bp5MDEBG68",
            "TLPv2tuSVvn3fSk8RgW3yPddkp5oFivzZV3rA9hQxtX"
        ],
        "callback_url": "https://api.my-sample-server.xyz/watch-shyft",
        "events": [
            "NFT_MINT"
        ]
    }
}
```

{% endtab %}
{% endtabs %}

## Remove a callback

Use the following API to stop listening on existing addresses. Once this API is triggered, callbacks are removed asynchronously and may take a minute to stop.

{% hint style="info" %}
You can specify id as \* to stop all callbacks related to you API key.
{% endhint %}

### <mark style="color:red;">DEL</mark> /sol/v1/callback/remove

#### Body

* **id**: ID of the registered callback by user. Can be obtained from list callbacks API

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "<api-key>");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    "id": "6437cb12044174e8098d3b40"
});

var requestOptions = {
  method: 'DELETE',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/remove", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks stopped for the given address",
    "result": {
        "id": "6437cb12044174e8098d3b40"
    }
}
```

{% endtab %}
{% endtabs %}

## Pause a callback

Use the following API to pause created callbacks. Once this API is triggered, callbacks are paused asynchronously and may take a minute to pause.\
Pausing callbacks is the smart way to maximize your credits. With no credits being consumed during the pause, you can save big.

{% hint style="info" %}
You can specify id as \* to pause all callbacks related to your API key.
{% endhint %}

### <mark style="color:blue;">POST</mark> /sol/v1/callback/pause

#### Body

* **id**: ID of the registered callback by the user. Can be obtained from list callbacks API

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "<api-key>");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    "id": "6437cb12044174e8098d3b40"
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/pause", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks paused for the given address",
    "result": {
        "id": "6437cb12044174e8098d3b40"
    }
}
```

{% endtab %}
{% endtabs %}

## Resume a callback

Use the following API to resume paused callbacks. Once this API is triggered, callbacks are resumed asynchronously and may take a minute to resume.\
Upon resuming callbacks, please be aware that credit consumption will resume accordingly.

{% hint style="info" %}
You can specify id as \* to resume all callbacks related to your API key.
{% endhint %}

### <mark style="color:blue;">POST</mark> /sol/v1/callback/resume

#### Body

* **id**: ID of the registered callback by the user. Can be obtained from list callbacks API

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "<api-key>");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    "id": "6437cb12044174e8098d3b40"
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/resume", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks resumed for the given address",
    "result": {
        "id": "6437cb12044174e8098d3b40"
    }
}
```

{% endtab %}
{% endtabs %}

## Update Callback

### <mark style="color:blue;">POST</mark> /sol/v1/callback/update

#### Body

* **id**: ID of the callback which has be updated. Can be found from list callbacks API.
* **addresses**: (**optional**) Array of public keys of accounts which should be watched.
* **events**: (**optional**) Array of valid events to watch for. Valid values for events are given [here](/solana-apis/transactions.md#parsed-transaction-types)
* **callback\_url**: (**optional**) New callback url.
* **enable\_raw** (**optional**): Option to include raw transaction information along with parsed data in callback.
* **enable\_events** (**optional**): Option to include parsed anchor events emitted in the transaction.
* **encoding** (**optional**): Option to change encoding format of account callbacks. Ignored if callback type is not `ACCOUNT`

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "<api-key>");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({ 
    "id": "64182a72e6c61e348f33de93",
    "addresses": ["RqP3BfJWnM56CHaXs5QKqFqcc5gvxYiL7AEox8WHStC"],
    "events": ["NFT_TRANSFER"]
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/update", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks updated",
    "result": {
        "id": "64182a72e6c61e348f33de93",
        "addresses": [
            "RqP3BfJWnM56CHaXs5QKqFqcc5gvxYiL7AEox8WHStC"
        ],
        "network": "devnet",
        "events": [
            "NFT_TRANSFER"
        ]
    }
}
```

{% endtab %}
{% endtabs %}

## Add Addresses in Callback

### <mark style="color:blue;">POST</mark> /sol/v1/callback/add-addresses

Once you add addresses to your callback, we start monitoring them instantly, without any latency.

#### Body

* **id:** (string) Callback id which has to be updated
* **addresses**: (Array\<string>) List of addresses which should be added in existing callback

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "<api-key>");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
  "id": "64a820e36112eecd8e0f2126",
  "addresses": [
    "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj"
  ]
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/add-addresses", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks updated",
    "result": {
        "id": "64a820e36112eecd8e0f2126",
        "addresses": [
            "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY",
            "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj"
        ],
        "network": "devnet",
        "events": [
            "ANY"
        ]
    }
}
```

{% endtab %}
{% endtabs %}

## Remove Addresses from callback

### <mark style="color:blue;">POST</mark> /sol/v1/callback/remove-addresses

Removing addresses from a callback can take few seconds to reflect.

#### Body

* **id**: (String) Callback Id which has to be updated
* **addresses**: (Array\<string>) List of addresses which should be removed from the callback

{% tabs %}
{% tab title="JS" %}

```javascript
var myHeaders = new Headers();
myHeaders.append("x-api-key", "E8TQAxxDZKsnh_nm");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
  "id": "64a820e36112eecd8e0f2126",
  "addresses": [
    "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj"
  ]
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("https://api.shyft.to/sol/v1/callback/remove-addresses", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "success": true,
    "message": "Callbacks updated",
    "result": {
        "id": "64a820e36112eecd8e0f2126",
        "addresses": [
            "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY"
        ],
        "network": "devnet",
        "events": [
            "ANY"
        ]
    }
}
```

{% endtab %}
{% endtabs %}

## Callback Response Structure

{% hint style="success" %}
Checkout response structure for all supported transaction types [<mark style="color:yellow;">here</mark>](/solana-apis/transactions/parsed-transaction-structure.md)
{% endhint %}

Every callback will be a Shyft parsed transaction along with some additional values of raw transaction information and account details. This callback is sent to the specified callback url as a POST request.

* Callbacks include `x-api-key` header which is the users api key so that a user can verify that the request is being sent from Shyft's server directly.
* Callbacks contain extra raw field which includes raw transaction info if `enable_raw` option is provided while creating the callback
* Callbacks contains accounts field which includes list of accounts which might have been changed in the transaction. The accounts data contains the following fields: account address as base58 encoded string , account owner as base58 encoded string, lamports balance as number and custom account data as hex formatted string.

Below is a sample transaction callback for SOL transfer between 2 accounts.&#x20;

```json
{
    "timestamp": "2023-04-19T07:16:07.000Z",
    "fee": 0.000005,
    "fee_payer": "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY",
    "signers": [
        "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY"
    ],
    "signatures": [
        "Bhd9f9RT6ifPmcw5HJVvoBSUBQ9hXvreeZ6JJLek5MftWWr6uMEyb7PQBCBDbJpj1qre7Yhs2td46qWqzba21dh"
    ],
    "protocol": {
        "address": "11111111111111111111111111111111",
        "name": "System Program"
    },
    "type": "SOL_TRANSFER",
    "status": "Success",
    "actions": [
        {
            "info": {
                "sender": "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY",
                "receiver": "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj",
                "amount": 0.0002
            },
            "source_protocol": {
                "address": "11111111111111111111111111111111",
                "name": "System Program"
            },
            "type": "SOL_TRANSFER"
        }
    ],
    "raw": {
        "blockTime": 1681888567,
        "meta": {
            "computeUnitsConsumed": 0,
            "err": null,
            "fee": 5000,
            "innerInstructions": [],
            "logMessages": [
                "Program 11111111111111111111111111111111 invoke [1]",
                "Program 11111111111111111111111111111111 success"
            ],
            "postBalances": [
                8967322360,
                8006870240,
                1
            ],
            "postTokenBalances": [],
            "preBalances": [
                8967527360,
                8006670240,
                1
            ],
            "preTokenBalances": [],
            "rewards": [],
            "status": {
                "Ok": null
            }
        },
        "slot": 210095276,
        "transaction": {
            "message": {
                "accountKeys": [
                    {
                        "pubkey": "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY",
                        "signer": true,
                        "source": "transaction",
                        "writable": true
                    },
                    {
                        "pubkey": "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj",
                        "signer": false,
                        "source": "transaction",
                        "writable": true
                    },
                    {
                        "pubkey": "11111111111111111111111111111111",
                        "signer": false,
                        "source": "transaction",
                        "writable": false
                    }
                ],
                "addressTableLookups": null,
                "instructions": [
                    {
                        "parsed": {
                            "info": {
                                "destination": "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj",
                                "lamports": 200000,
                                "source": "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY"
                            },
                            "type": "transfer"
                        },
                        "program": "system",
                        "programId": "11111111111111111111111111111111"
                    }
                ],
                "recentBlockhash": "C832wWgEZb6DM6K5RCqjYdt9btupiGtdF8wy8jMC3uuh"
            },
            "signatures": [
                "Bhd9f9RT6ifPmcw5HJVvoBSUBQ9hXvreeZ6JJLek5MftWWr6uMEyb7PQBCBDbJpj1qre7Yhs2td46qWqzba21dh"
            ]
        },
        "version": "legacy",
        "parsed": {
            "timestamp": "2023-04-19T07:16:07.000Z",
            "fee": 0.000005,
            "fee_payer": "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY",
            "signers": [
                "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY"
            ],
            "signatures": [
                "Bhd9f9RT6ifPmcw5HJVvoBSUBQ9hXvreeZ6JJLek5MftWWr6uMEyb7PQBCBDbJpj1qre7Yhs2td46qWqzba21dh"
            ],
            "protocol": {
                "address": "11111111111111111111111111111111",
                "name": "System Program"
            },
            "type": "SOL_TRANSFER",
            "status": "Success",
            "actions": [
                {
                    "info": {
                        "sender": "7iviPE2HZ15QCvHHCm8QzYdXKt9qReeT5P4aqSRAp7oY",
                        "receiver": "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj",
                        "amount": 0.0002
                    },
                    "source_protocol": {
                        "address": "11111111111111111111111111111111",
                        "name": "System Program"
                    },
                    "type": "SOL_TRANSFER"
                }
            ]
        }
    },
    "accounts": [
        {
            "address": "Apeng15Pm8EjpAcaAXpNUxZjS2jMmGqikfs281Fz9hNj",
            "owner": 11111111111111111111111111111111,
            "lamports": 9837472332,
            "data": null,
        }
    ]
}
```

## Below is an example of sample parsed account callback

```json
{
    "account": "TCMPhJdwDryooaGtiocG1u3xcYbRpiJzb283XfCZsDp",
    "accountInfo": {
        "slot": 225433098,
        "pubkey": "2BkYBWCQFjzAvozSMc8AfgKUrUA1tcoVeTbGBLWaFizV8y",
        "lamports": 6355840,
        "owner": "68CzaqYybwkrfskTsyBDg6d2HM6z1bGWk1TABiwAnMyb",
        "data": {
            "version": 1,
            "bump": [
                255
            ],
            "owner": "BcVHRoZEuEvei3nDvCVbWpL4mf7G5WnSjXuzPVrNaUF5",
            "assetId": "piccGd7zoyGuE8W147ayMwqJ5bVVRur9WP46icpPPgr",
            "amount": "016694e0",
            "currency": null,
            "expiry": "67141cb8",
            "privateTaker": null,
            "makerBroker": null,
            "raw": "TvJZiqHdsEsB/52sLXMQDxcV5ePWN7WWYX7bqSIJXlZd1IYO6ixCAkoUDDlZ3mxLiKR6T15/Uqb6/4WktYIXun6QbQ43fYc1/B/glGYBAAAAAAC4HBRnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
        }
    }
}
```
