> ## 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 and detail

> GET /v1/competitions and GET /v1/competitions/detail: your instance's competitions, newest first, and one competition with its full rules history.

## List competitions

`GET /v1/competitions`

The competitions of your instance, newest first, as [competition objects](https://docs.cabalspy.xyz/cabalspy-id/competitions-create.md#response) without the rules history.

### Query Parameters

**status** `string`

Only competitions in this status: scheduled, waiting, running, ended or cancelled.

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

Competitions per page, 1 to 500.

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

How many to skip.

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

> [!NOTE]
>
> Page with `offset`, or pass `pagination.next_cursor` as `cursor`. `next_cursor` is null on the last page.

### Usage Example

```bash cURL theme={null}
curl "https://api-id.cabalspy.xyz/v1/competitions?status=running" \
  -H "Authorization: Bearer YOUR_KEY"
```

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

r = requests.get("https://api-id.cabalspy.xyz/v1/competitions",
                 params={"limit": 50, "offset": 0},
                 headers={"Authorization": "Bearer YOUR_KEY"}).json()
for c in r["data"]:
    print(c["id"], c["name"], c["status"], c["participants"])
print("total", r["pagination"]["total"])
```

```javascript JavaScript theme={null}
const p = new URLSearchParams({ status: "scheduled" });
const res = await fetch(`https://api-id.cabalspy.xyz/v1/competitions?${p}`, {
  headers: { Authorization: "Bearer YOUR_KEY" },
});
const { data, pagination } = await res.json();
console.log(data.map(c => c.name), pagination.total);
```

```json Response theme={null}
{
  "success": true,
  "data": [
    {
      "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
      "name": "Weekend PnL Cup",
      "chain": "solana",
      "metric": "pnl_usd",
      "status": "running",
      "started_at": "2026-11-01T18:00:00Z",
      "ends_at": "2026-11-03T18:00:00Z",
      "participants": 214,
      "rules_version": 1,
      "standings_updated_at": "2026-11-02T09:15:00Z",
      "...": "the other fields of the competition object"
    }
  ],
  "pagination": { "limit": 50, "total": 1, "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" }
}
```

## Competition detail

`GET /v1/competitions/detail?id=<competition id>`

One competition, as the [competition object](https://docs.cabalspy.xyz/cabalspy-id/competitions-create.md#response) including every rule change.

**id** `string` *required*

The competition id.

```bash cURL theme={null}
curl "https://api-id.cabalspy.xyz/v1/competitions/detail?id=9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f" \
  -H "Authorization: Bearer YOUR_KEY"
```

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

c = requests.get("https://api-id.cabalspy.xyz/v1/competitions/detail",
                 params={"id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f"},
                 headers={"Authorization": "Bearer YOUR_KEY"}).json()["data"]
for ch in c["changes"]:
    print(ch["rules_version"], ch["during"], ch["changes"], ch["note"])
```

```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/detail?${p}`, {
  headers: { Authorization: "Bearer YOUR_KEY" },
});
const { data } = await res.json();
console.log(data.status, data.changed_while_running);
```

### Rules history

**changes** `array`

**change**

**rules\_version** `integer`

The rules version this change created.

**changed\_at** `string`

When it was changed.

**during** `string`

The phase it was changed in: scheduled or running.

**changes** `object`

Per changed field: `from` and `to`. Durations are shown as duration\_hours.

**note** `string`

Your note on the change, or null.

**changed\_while\_running** `boolean`

Whether any rule was changed while the competition ran.

```json Response theme={null}
{
  "success": true,
  "data": {
    "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
    "name": "Weekend PnL Cup",
    "status": "running",
    "duration_hours": 72.0,
    "ends_at": "2026-11-04T18:00:00Z",
    "rules_version": 2,
    "...": "the other fields of the competition object",
    "changes": [
      {
        "rules_version": 2,
        "changed_at": "2026-11-02T10:00:00Z",
        "during": "running",
        "changes": { "duration_hours": { "from": 48.0, "to": 72.0 } },
        "note": "Extended by one day after the outage."
      }
    ],
    "changed_while_running": true
  },
  "meta": { "request_id": "req_5162c7cf7f87", "cached": false, "cache_age_seconds": 0, "version": "v1", "timestamp": "2026-11-02T10:00:05Z" }
}
```

## Errors

| Status | Code | Meaning |
| - | - | - |
| 400 | missing\_parameter | Detail: id missing. |
| 400 | invalid\_parameter | status, limit, offset or id 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.