> ## 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.

# Callouts

> Let your users publicly call tokens. CabalSpy ID stamps the price and market cap at the call, tracks the token like the CabalSpy call statistics, and gives you stats, a leaderboard, a live stream, webhooks and callout competitions.

> [!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).

A **callout** is a user of your platform publicly calling a token: "this one goes up". CabalSpy ID stamps the token's price and market cap at that moment and tracks how the token performs from there, the same way CabalSpy scores its own calls. You get each callout's current and peak multiple, statistics per user, a leaderboard of your callers, a live stream, webhooks and [callout competitions](https://docs.cabalspy.xyz/cabalspy-id/competitions-callouts.md).

A key only reaches the callouts of its own instance. [GET /v1/me](https://docs.cabalspy.xyz/cabalspy-id/me.md) lists `"callouts"` in `features` when they are switched on for your instance.

## Who can make a callout

You make a callout from your backend, in the name of one of your users:

* a [platform user](https://docs.cabalspy.xyz/cabalspy-id/white-label.md), by `external_id` or `csid_id`,
* or a person who signed in to your app with CabalSpy ID and granted the scope `thesis`, by `csid_id`.

To read the callouts or stats of a person who signed in with CabalSpy ID (not a platform user), the `thesis` scope is not needed: it is enough that they use your app.

Your instance's [callout settings](https://docs.cabalspy.xyz/cabalspy-id/callouts-settings.md) decide the rest:

| Setting | Default | Effect |
| - | - | - |
| `who` | `all` | `all`: every user can call. `kol_only`: only users with the KOL badge. |
| `require_holding` | `true` | The user must hold the token in one of their wallets that count on its chain. |
| `cooldown_minutes` | `360` | Minutes a user waits between two callouts, 0 to 10,080 (7 days). 0 switches the cooldown off. |

Independent of the settings, a user can call the same token only **once per 24 hours**: a new callout on that token is possible once the first day of the previous one is over. Users paused from writing theses cannot make callouts either.

## How a callout is tracked

**1. At the call**

The current price and market cap of the token are stamped on the callout (`at_call`). A token without a market price cannot be called (`no_price`).

**2. First 24 hours**

The price is read **every minute**. Each read updates the current multiple (`now.x`) and, when it is a new high, the peak (`peak`). Milestones are announced as they are reached.

**3. First day scored**

About five minutes after the first 24 hours, the day is scored on price candles, like the CabalSpy call statistics, and `callout.scored` is sent. From now on the multiples are measured against the candle entry.

**4. While the token is active**

The price is read **every 5 minutes**, and once a day the highest high of that day's 5-minute candles is added to the peak, so a spike between two reads still counts.

**5. Tracking stops**

When the token's market cap stays **below \$10,000 for 24 hours in a row**, or the token has no price at all for 24 hours in a row, tracking stops, the callout's `status` becomes `final` and `callout.final` is sent. Its score stays as it was.

The 24-hour clock for an inactive token starts at the first read below $10,000 after the first day, or at the end of the first day if the token is below $10,000 then. A token the market data provider no longer prices counts as below $10,000. Any read at $10,000 or more resets the clock. A temporary error at the provider changes nothing. `tracking.below_10k_since` shows when the current clock started.

`tracking.stop_reason` says why tracking stopped: `inactive` when the last read before the stop had a market cap below \$10,000, `no_price` when the token had no price. While a callout is in its first day it is never stopped.

All callouts on the same token share one price read per round, however many users called it.

## Scoring

The score of a callout is its **peak multiple**:

```text theme={null}
score_x = highest price since the call / entry price
```

**Entry price.** Until the first day is scored, the entry is the price stamped at the call. After that, it is the candle entry, as in the CabalSpy call statistics:

* the close of the 1-minute candle right before the call, so nothing after the call is used;
* if trading only starts in the minute of the call (a fresh token), the close of that candle;
* if the first trade comes at most 2 minutes after the call, the open of that candle.

**Highest price.** Only prices seen **after** the call count: the highest high of the first day's candles (1-minute candles for the first hour, then 5-minute candles), and every price read and the highest high of each later day's 5-minute candles. Only candles that start after the call count. The price stamped at the call is the entry, never the peak.

Right after the call, before any later price was seen, `score_x` and `peak.x` are exactly 1.0. During the first day they rise above 1.0 once a read is higher than the price at the call. Once the first day is scored on candles, the multiples are measured against the candle entry, so `score_x` can move at that moment, and it can be below 1.0 when the token never traded above the entry after the call. After that it only rises, with every new high while the token is tracked.

Price is compared with price, so the token supply does not matter.

Market caps for the current and peak price are the price times the supply known at the call. They are null when the supply is unknown.

### The first day

Once the first day is scored, every callout carries `first_day`:

| Field | Meaning |
| - | - |
| `kind` | `candles`: scored on candles. `live`: no candles were available, the live numbers stand. |
| `entry_price_usd` | The entry price the multiples are measured against. |
| `peak_x` | Highest high of the first 24 hours against the candle entry. Null for `live`. |
| `close_x` | Last close of the first 24 hours against the candle entry. Null for `live`. |
| `minutes_to_peak` | Minutes from the call to the first day's peak candle. |
| `flags` | Notes on the data, see below. |

| Flag | Meaning |
| - | - |
| `STALE_ENTRY` | The last trade before the call was more than 10 minutes earlier. |
| `NO_TRADES_AFTER` | No candles after the call within the first day. The first-day peak is the entry. |
| `NO_TRADES_LAST_6H` | No trades in the last 6 hours of the first day. |
| `EXTREME_MULTIPLE` | The first-day peak is 200x or more. Worth a manual look. |
| `NO_CANDLES_NO_DATA` | No candles at all. Scored `live`. |
| `NO_CANDLES_NO_ENTRY` | No candle to take the entry from. Scored `live`. |
| `CANDLES_UNAVAILABLE`, `NO_CANDLES_ERROR` | Candles could not be loaded after several attempts. Scored `live`. |

## Milestones

When a callout's peak multiple reaches **2x, 3x, 5x, 10x, 20x, 50x or 100x**, a `callout.milestone` event is sent on the [stream](https://docs.cabalspy.xyz/cabalspy-id/callouts-stream.md) and as a [webhook](https://docs.cabalspy.xyz/cabalspy-id/webhooks.md#callout-events), with `milestone_x`. Each milestone is announced once per callout. When the price jumps past several milestones between two reads, only the highest one reached is announced.

## Statuses

| Status | Meaning |
| - | - |
| `tracking` | Being tracked. `tracking.phase` is `first_day` or `extended`. |
| `final` | Tracking stopped because the token became inactive. `tracking.phase` is `stopped`. |

Callouts you [remove](https://docs.cabalspy.xyz/cabalspy-id/callouts-create.md#remove-a-callout) disappear from every list, statistic, leaderboard and competition.

## Statistics and leaderboard

[Stats](https://docs.cabalspy.xyz/cabalspy-id/callouts-stats.md) and the [leaderboard](https://docs.cabalspy.xyz/cabalspy-id/callouts-leaderboard.md) summarize the callouts **made** in a period (6h, 1d, 7d or 30d), each with its current score:

| Value | Meaning |
| - | - |
| `callouts` | Number of callouts. |
| `avg_peak_x` | Average score. |
| `median_peak_x` | Median score. |
| `best_peak_x` | Best score. |
| `sum_peak_x` | Sum of the scores. |
| `hits` | Callouts that reached `hit_x` (2x by default). |
| `hit_rate` | Hits as a percentage of callouts, 0 to 100. |

## Webhooks and stream

| Event | Webhook | Stream | When |
| - | - | - | - |
| `callout.created` | Yes | Yes | A user made a callout. |
| `callout.update` | No | Yes | A new price was read. |
| `callout.milestone` | Yes | Yes | A milestone was reached. |
| `callout.scored` | Yes | Yes | The first day was scored. |
| `callout.final` | Yes | Yes | Tracking stopped. |
| `callout.removed` | No | Yes | You removed a callout. |

The callout webhooks are only offered to instances with callouts switched on. See [Callout events](https://docs.cabalspy.xyz/cabalspy-id/webhooks.md#callout-events) and the [callouts stream](https://docs.cabalspy.xyz/cabalspy-id/callouts-stream.md).

## Dashboard

When callouts are switched on, the instance shows a [Callouts](https://docs.cabalspy.xyz/cabalspy-id/dashboard.md#callouts) tab with the settings, and the Competitions tab can create callout competitions.

## Endpoints

| Method | Path | Description |
| - | - | - |
| POST | [/v1/callouts](https://docs.cabalspy.xyz/cabalspy-id/callouts-create.md) | Make a callout in a user's name. |
| POST | [/v1/callouts/remove](https://docs.cabalspy.xyz/cabalspy-id/callouts-create.md#remove-a-callout) | Remove a callout. |
| GET | [/v1/callouts](https://docs.cabalspy.xyz/cabalspy-id/callouts-list.md) | Callouts, newest first, by token, user or time. Chart markers. |
| GET | [/v1/callouts/item](https://docs.cabalspy.xyz/cabalspy-id/callouts-list.md#get-one-callout) | One callout. |
| GET | [/v1/callouts/stats](https://docs.cabalspy.xyz/cabalspy-id/callouts-stats.md) | One user's stats per period. |
| GET | [/v1/callouts/leaderboard](https://docs.cabalspy.xyz/cabalspy-id/callouts-leaderboard.md) | Your callers ranked. |
| GET, POST | [/v1/callouts/settings](https://docs.cabalspy.xyz/cabalspy-id/callouts-settings.md) | Who may call, holders only, cooldown. |
| WS | [/v1/callouts/stream](https://docs.cabalspy.xyz/cabalspy-id/callouts-stream.md) | Every callout event, live. |
| POST | [/v1/competitions](https://docs.cabalspy.xyz/cabalspy-id/competitions-callouts.md) | Callout competitions with `kind: "callouts"`. |


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