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

# Standings

> GET /v1/competitions/standings: the ranking of a competition with score and trading stats per participant, recomputed every 5 minutes and final after the end.

The ranking of a [competition](https://docs.cabalspy.xyz/cabalspy-id/competitions.md): the ranked traders first, by rank, then the participants below the minimums. Each entry has the score and the trading stats during the competition.

Standings are recomputed every 5 minutes while the competition runs and once more at the end. After the end `final` is true and the standings are the results.

## Query Parameters

**id** `string` *required*

The competition id.

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

Entries per page, 1 to 1,000.

**offset** `integer` (default: 0)

How many to skip. Instead of offset you can pass `pagination.next_cursor` as `cursor`; it is null on the last page.

**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/competitions/standings?id=9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f&limit=50" \
  -H "Authorization: Bearer YOUR_KEY"
```

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

d = requests.get("https://api-id.cabalspy.xyz/v1/competitions/standings",
                 params={"id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f", "limit": 50},
                 headers={"Authorization": "Bearer YOUR_KEY"}).json()["data"]
print(d["status"], "final" if d["final"] else "as of " + str(d["updated_at"]))
for s in d["standings"]:
    print(s["rank"], s["external_id"], s["score"], s["trades"])
```

```javascript JavaScript theme={null}
const p = new URLSearchParams({ id: "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f" });
const res = await fetch(`https://api-id.cabalspy.xyz/v1/competitions/standings?${p}`, {
  headers: { Authorization: "Bearer YOUR_KEY" },
});
const { data } = await res.json();
data.standings.filter(s => s.ranked).forEach(s => console.log(s.rank, s.external_id, s.score));
```

## Response

**data** `object`

**data**

**competition\_id** `string`

The competition id.

**status** `string`

The competition's status.

**metric** `string`

The metric the score is in.

**rules\_version** `integer`

The current rules version.

**updated\_at** `string`

When the standings were computed, or null before the first computation.

**final** `boolean`

True once the competition ended.

**standings** `array`

**entry**

**rank** `integer`

Position, starting at 1. Null below the minimums.

**ranked** `boolean`

Whether the participant is ranked.

**external\_id** `string`

Your id of the participant.

**csid\_id** `string`

Their CabalSpy ID account id.

**score** `number`

The value of the competition's metric.

**pnl, pnl\_usd** `number`

Sells minus buys during the competition, native and USD.

**volume, volume\_usd** `number`

Buy plus sell volume, native and USD.

**trades, buys, sells** `integer`

Number of trades, buys and sells.

**win\_count, closed\_count** `integer`

Winning and closed positions.

**win\_rate** `number`

Winning closed positions in percent.

**tokens** `integer`

Tokens traded.

**wallets** `integer`

Wallets the participant competed with.

**pagination** `object`

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

```json Response theme={null}
{
  "success": true,
  "data": {
    "competition_id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
    "status": "running",
    "metric": "pnl_usd",
    "rules_version": 1,
    "updated_at": "2026-11-02T09:15:00Z",
    "final": false,
    "standings": [
      {
        "rank": 1,
        "ranked": true,
        "external_id": "user_8412",
        "csid_id": "3f9a1c2e-5b7d-4e8f-a1b2-c3d4e5f60718",
        "score": 3968.6,
        "pnl": 48.2,
        "pnl_usd": 3968.6,
        "volume": 408.7,
        "volume_usd": 33649.8,
        "trades": 40,
        "buys": 22,
        "sells": 18,
        "win_count": 14,
        "closed_count": 18,
        "win_rate": 77.78,
        "tokens": 21,
        "wallets": 2
      },
      {
        "rank": null,
        "ranked": false,
        "external_id": "user_8413",
        "csid_id": "8e2b4d6f-1a3c-4e5f-9b7d-0c2e4a6b8d10",
        "score": 12.4,
        "pnl": 0.15,
        "pnl_usd": 12.4,
        "volume": 0.9,
        "volume_usd": 74.1,
        "trades": 2,
        "buys": 1,
        "sells": 1,
        "win_count": 1,
        "closed_count": 1,
        "win_rate": 100.0,
        "tokens": 1,
        "wallets": 1
      }
    ]
  },
  "pagination": { "limit": 50, "total": 2, "has_more": false, "next_cursor": null },
  "meta": {
    "request_id": "req_5162c7cf7f87",
    "cached": false,
    "cache_age_seconds": 0,
    "version": "v1",
    "timestamp": "2026-11-02T09:16:02Z"
  }
}
```

## Errors

| Status | Code | Meaning |
| - | - | - |
| 400 | missing\_parameter | id missing. |
| 400 | invalid\_parameter | id, limit or offset invalid. |
| 401 | missing\_api\_key | API key missing. |
| 403 | invalid\_api\_key | API key invalid or not enabled for CabalSpy ID. |
| 404 | competition\_not\_found | No competition with this id in your instance. |
| 429 | rate\_limit\_exceeded | Rate limit exceeded. |

See [Errors](https://docs.cabalspy.xyz/cabalspy-id/errors.md) for the full list.


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