> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cabalspy.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# List callouts

> GET /v1/callouts and GET /v1/callouts/item: your instance's callouts newest first, by token, user or time, with price and market cap at the call, now and at the peak. Use them as markers on a price chart.

> [!NOTE]
>
> Callouts are switched on per instance on request. Contact us ([contact@cabalspy.xyz](mailto:contact@cabalspy.xyz)) to enable them. Without them every endpoint answers 403 [feature\_not\_enabled](https://docs.cabalspy.xyz/cabalspy-id/errors.md#feature_not_enabled).

## List callouts

`GET /v1/callouts`

The [callouts](https://docs.cabalspy.xyz/cabalspy-id/callouts.md) of your instance, newest first. Narrow them to one token, one user or a time range. Removed callouts are never returned.

### Query Parameters

**chain** `string`

Only callouts on this chain. One of solana, bnb, base, eth, rh.

**mint** `string`

Only callouts on this token. Needs chain.

**external\_id** `string`

Only callouts of this user. Alternatively pass csid\_id: a platform user, or a person who signed in to your app with CabalSpy ID (no `thesis` scope needed to read).

**since** `string`

Only callouts made at or after this time, ISO 8601, for example `2026-11-01T00:00:00Z`. Without a time zone UTC is assumed.

**until** `string`

Only callouts made at or before this time, ISO 8601.

**limit** `integer` (default: 50)

Callouts per page, 1 to 200.

**cursor** `string`

Cursor for the next page, the pagination.next\_cursor from the previous response.

**instance** `string`

Your Instance ID. Only needed when your account has several instances.

**api\_key** `string` *required*

Your API key. Alternatively pass it as an Authorization Bearer header.

### Usage Example

```bash cURL theme={null}
curl "https://api-id.cabalspy.xyz/v1/callouts?chain=solana&mint=3Pkrq4MmLvDXyn1fa3sz5MekKRkZkc1iLDcz5AzWpump&limit=50" \
  -H "Authorization: Bearer YOUR_KEY"
```

```python Python theme={null}
import requests

params = {"external_id": "user_8412", "limit": 20}
r = requests.get("https://api-id.cabalspy.xyz/v1/callouts", params=params,
                 headers={"Authorization": "Bearer YOUR_KEY"})
for c in r.json()["data"]:
    print(c["token"]["symbol"], c["called_at"], c["score_x"], c["status"])
```

```javascript JavaScript theme={null}
const p = new URLSearchParams({ since: "2026-11-01T00:00:00Z", limit: "100" });
const res = await fetch(`https://api-id.cabalspy.xyz/v1/callouts?${p}`, {
  headers: { Authorization: "Bearer YOUR_KEY" },
});
const { data, pagination } = await res.json();
data.forEach(c => console.log(c.author.username, c.token.symbol, c.peak.x));
```

### Response

**data** `array`

[Callout objects](#the-callout-object), newest first.

**pagination** `object`

limit, has\_more and next\_cursor (pass it as cursor; null on the last page).

```json Response theme={null}
{
  "success": true,
  "data": [
    {
      "id": "5b0e7c3a-2d4f-4a6b-9c8d-1e2f3a4b5c6d",
      "chain": "solana",
      "mint": "3Pkrq4MmLvDXyn1fa3sz5MekKRkZkc1iLDcz5AzWpump",
      "token": { "name": "invisibull", "symbol": "invisibull", "logo": "https://..." },
      "author": {
        "csid_id": "3f9a1c2e-5b7d-4e8f-a1b2-c3d4e5f60718",
        "external_id": "user_8412",
        "name": "Maze",
        "username": "MazeCCC",
        "avatar_url": "https://cdn.example.com/avatars/8412.png",
        "kol": false
      },
      "note": "Dev still holding, chart is coiling.",
      "called_at": "2026-11-01T18:02:11Z",
      "window_ends_at": "2026-11-02T18:02:11Z",
      "status": "tracking",
      "at_call": { "price_usd": 0.0000412, "market_cap_usd": 41200.0 },
      "now": { "price_usd": 0.0000903, "market_cap_usd": 90300.0, "x": 2.2296, "at": "2026-11-03T09:40:00Z" },
      "peak": { "price_usd": 0.000131, "market_cap_usd": 131000.0, "x": 3.2346, "at": "2026-11-01T19:40:00Z" },
      "score_x": 3.2346,
      "source": "mobula",
      "tracking": {
        "active": true,
        "phase": "extended",
        "next_check_at": "2026-11-03T18:02:11Z",
        "below_10k_since": null,
        "daily_checks": 1,
        "stopped_at": null,
        "stop_reason": null
      },
      "first_day": {
        "kind": "candles",
        "entry_price_usd": 0.0000405,
        "peak_x": 3.2346,
        "close_x": 1.8642,
        "minutes_to_peak": 98,
        "flags": []
      }
    }
  ],
  "pagination": {
    "limit": 50,
    "has_more": false,
    "next_cursor": null
  },
  "meta": {
    "request_id": "req_5162c7cf7f87",
    "cached": false,
    "cache_age_seconds": 0,
    "version": "v1",
    "timestamp": "2026-11-03T09:41:02Z"
  }
}
```

### Errors

| Status | Code | Meaning |
| - | - | - |
| 400 | missing\_parameter | mint was passed without chain. |
| 400 | invalid\_parameter | chain, mint, since, until, limit, cursor or csid\_id invalid. |
| 401 | missing\_api\_key | API key missing. |
| 403 | invalid\_api\_key | API key invalid or not enabled for CabalSpy ID. |
| 403 | [feature\_not\_enabled](https://docs.cabalspy.xyz/cabalspy-id/errors.md#feature_not_enabled) | Callouts are not switched on for your instance. |
| 404 | platform\_user\_not\_found | No platform user with this external\_id, and no user of your app with this csid\_id. |
| 429 | rate\_limit\_exceeded | Rate limit exceeded. |

## Chart markers

To show callouts on a token's price chart, list them by `chain` and `mint`, with `since` and `until` set to the range the chart shows. Put a marker at `called_at` and `at_call.price_usd` for each, and show the author, `note` and `score_x` on hover. Page with `cursor` until `has_more` is false.

```javascript JavaScript theme={null}
async function calloutMarkers(chain, mint, fromIso, toIso) {
  const markers = [];
  let cursor = null;
  do {
    const p = new URLSearchParams({ chain, mint, since: fromIso, until: toIso, limit: "200" });
    if (cursor) p.set("cursor", cursor);
    const res = await fetch(`https://api-id.cabalspy.xyz/v1/callouts?${p}`, {
      headers: { Authorization: "Bearer YOUR_KEY" },
    });
    const { data, pagination } = await res.json();
    for (const c of data) {
      markers.push({
        time: Date.parse(c.called_at) / 1000,
        price: c.at_call.price_usd,
        label: `${c.author.username ?? c.author.external_id}: ${c.score_x}x`,
      });
    }
    cursor = pagination.next_cursor;
  } while (cursor);
  return markers;
}
```

Call this from your backend, which holds the API key. To add new callouts while the chart is open, follow the [callouts stream](https://docs.cabalspy.xyz/cabalspy-id/callouts-stream.md) with the same `chain` and `mint`.

## Get one callout

`GET /v1/callouts/item`

One callout by id, as a [callout object](#the-callout-object).

### Query Parameters

**id** `string` *required*

The callout id.

**api\_key** `string` *required*

Your API key. Alternatively pass it as an Authorization Bearer header.

```bash cURL theme={null}
curl "https://api-id.cabalspy.xyz/v1/callouts/item?id=5b0e7c3a-2d4f-4a6b-9c8d-1e2f3a4b5c6d" \
  -H "Authorization: Bearer YOUR_KEY"
```

### Errors

| Status | Code | Meaning |
| - | - | - |
| 400 | missing\_parameter | id is missing. |
| 400 | invalid\_parameter | id is not a valid id. |
| 403 | [feature\_not\_enabled](https://docs.cabalspy.xyz/cabalspy-id/errors.md#feature_not_enabled) | Callouts are not switched on for your instance. |
| 404 | [callout\_not\_found](https://docs.cabalspy.xyz/cabalspy-id/errors.md#callout_not_found) | No callout with this id in your instance, or it was removed. |

## The callout object

**id** `string`

The callout id.

**chain, mint** `string`

The token's chain and address.

**token** `object`

name, symbol and logo of the token at the call. Any of them can be null.

**author** `object`

**author**

**csid\_id** `string`

The user's CabalSpy ID.

**external\_id** `string`

Your id of the user, or null for users who are not platform users.

**name, username, avatar\_url** `string`

Display name, handle and avatar, if known.

**kol** `boolean`

Whether the user has the KOL badge.

**note** `string`

The user's note, or null.

**called\_at** `string`

When the callout was made.

**window\_ends\_at** `string`

End of the first 24 hours. Until then the user cannot call this token again.

**status** `string`

`tracking` or `final`. See [Statuses](https://docs.cabalspy.xyz/cabalspy-id/callouts.md#statuses).

**at\_call** `object`

price\_usd and market\_cap\_usd stamped at the call.

**now** `object`

The latest price read: price\_usd, market\_cap\_usd, x (against the entry) and at.

**peak** `object`

The highest price seen after the call: price\_usd, market\_cap\_usd, x (against the entry) and at. Until a later price is seen, the entry price with x 1.0 and at the time of the call.

**score\_x** `number`

The callout's score, its peak multiple. See [Scoring](https://docs.cabalspy.xyz/cabalspy-id/callouts.md#scoring).

**source** `string`

The market data source of the prices.

**tracking** `object`

**tracking**

**active** `boolean`

Whether the callout is still tracked.

**phase** `string`

`first_day` (read every minute), `extended` (first day scored, read every 5 minutes) or `stopped`.

**next\_check\_at** `string`

When the next day's candles are added to the peak. Null in the first day and once stopped.

**below\_10k\_since** `string`

Since when the market cap has been below \$10,000 (or the token has had no price) without interruption, or null. Tracking stops 24 hours after this time.

**daily\_checks** `integer`

Days scored so far, counting the first day.

**stopped\_at** `string`

When tracking stopped, or null.

**stop\_reason** `string`

Why tracking stopped: `inactive` (market cap below \$10,000 for 24 hours) or `no_price` (no price for 24 hours). Null while tracked.

**first\_day** `object`

Only once the first day is scored: kind, entry\_price\_usd, peak\_x, close\_x, minutes\_to\_peak and flags. See [The first day](https://docs.cabalspy.xyz/cabalspy-id/callouts.md#the-first-day).

`now.x`, `peak.x` and `score_x` are measured against the entry price: the price at the call during the first day, the candle entry once the first day is scored with `kind: "candles"`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.