# Callback APIs

{% hint style="success" %}
Checkout structure for different type of transaction actions [here](https://docs.shyft.to/solana-apis/transactions/parsed-transaction-structure)
{% 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>](https://docs.shyft.to/solana-apis/transactions#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](https://docs.shyft.to/solana-apis/transactions#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>](https://docs.shyft.to/solana-apis/transactions/parsed-transaction-structure)
{% 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="
        }
    }
}
```


---

# 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.shyft.to/callbacks/callback-apis.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.
