# Your positions

> All the account's positions with catalogue (the kinds and their legs, every condition with its unit, default threshold and range, the label counts and the alert defaults); with id, one position.

Source: https://firmtape.com/docs/developers/orders/positions

All the account's positions with `catalogue` (the kinds and their legs, every condition with its unit, default threshold and range, the label counts and the alert defaults); with `id`, one position.

`GET /api/positions`

Plan ORDERS · Key scope orders · Limit 20,000 calls a day on Orders API, 100,000 on Orders Team, per account · Version 1.0.0 · Since 2026-10-04

**This endpoint serves:** [ORDERS: POSITIONS panel and editor](https://firmtape.com/docs/orders#positions-panel). **Plan:** [ORDERS](https://firmtape.com/features/orders). Free on every finished session. Today's ledger, live, and the live POSITIONS check are the ORDERS plan.

## Parameters

| Name | What it does | Default | Error |
| --- | --- | --- | --- |
| `id` query, string | One position, `p_...`. |  | not_found |

## Response

`{ positions, max, catalogue }`, or `{ position }` with `id`.

| Field | Meaning | Unit |
| --- | --- | --- |
| `positions` (array) | Up to `max`. |  |
| `positions[].id` (string) | `p_...`, given by `add`. |  |
| `positions[].kind` (condor \| strangle \| put_spread \| call_spread) | `condor`, `strangle`, `put_spread` or `call_spread`. |  |
| `positions[].legs` (object) | The strikes, rising, as the kind needs them. |  |
| `positions[].legs.lp` (number) | Long put. |  |
| `positions[].legs.sp` (number) | Short put. |  |
| `positions[].legs.sc` (number) | Short call. |  |
| `positions[].legs.lc` (number) | Long call. |  |
| `positions[].entry` (string) | Entry minute, `HH:MM` ET. |  |
| `positions[].conditions` (array) | `[{ id, on, threshold }]`: which conditions count, and where they switch on. |  |
| `positions[].label` (object) | `{ caution, skip }`: how many conditions on make each label. |  |
| `positions[].alert` (object) | `{ channel: telegram \| email \| webhook \| off, url, before }`: where the alerts go and how many minutes before entry they start. |  |
| `positions[].session` (string) | `YYYY-MM-DD`: the session the strikes were set against. |  |
| `max` (integer) | Positions an account may keep (5). |  |
| `catalogue` (object) | Kinds, conditions, label counts and alert defaults. |  |
| `position` (object) | A short options position: `kind` (`condor`, `strangle`, `put_spread`, `call_spread`), `legs` (`lp`, `sp`, `sc`, `lc`, rising), `entry` (`HH:MM` ET) and optionally `conditions`, `label`, `alert` (`{ channel: telegram \| email \| webhook \| off, url, before }`) and `session`. |  |
| `position.id` (string) | `p_...`, given by `add`. |  |
| `position.kind` (condor \| strangle \| put_spread \| call_spread) | `condor`, `strangle`, `put_spread` or `call_spread`. |  |
| `position.legs` (object) | The strikes, rising, as the kind needs them. |  |
| `position.legs.lp` (number) | Long put. |  |
| `position.legs.sp` (number) | Short put. |  |
| `position.legs.sc` (number) | Short call. |  |
| `position.legs.lc` (number) | Long call. |  |
| `position.entry` (string) | Entry minute, `HH:MM` ET. |  |
| `position.conditions` (array) | `[{ id, on, threshold }]`: which conditions count, and where they switch on. |  |
| `position.label` (object) | `{ caution, skip }`: how many conditions on make each label. |  |
| `position.alert` (object) | `{ channel: telegram \| email \| webhook \| off, url, before }`: where the alerts go and how many minutes before entry they start. |  |
| `position.session` (string) | `YYYY-MM-DD`: the session the strikes were set against. |  |

## Errors

| Status | Code | What to do |
| --- | --- | --- |
| 401 | `no_key` | No key, or a revoked one. Send `Authorization: Bearer <key>` with a key of the product's scope. |
| 403 | `plan` | The account is not on the Orders API or Team plan. Move to the Orders API or Team plan. |
| 404 | `not_found` | No position with this id on this account. Check the path or the id. |
| 429 | `rate` | The day's calls are spent. Wait for midnight ET, when the count resets. |

## Request

```sh
curl \
  -H "Authorization: Bearer $FIRMTAPE_ORDERS_KEY" \
  "https://firmtape.com/api/positions"
```

```python
import os, requests

H = {"Authorization": f"Bearer {os.environ['FIRMTAPE_ORDERS_KEY']}"}
r = requests.get("https://firmtape.com/api/positions", headers=H)
print(r.status_code, r.text[:500])
```

```js
const r = await fetch("https://firmtape.com/api/positions", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.FIRMTAPE_ORDERS_KEY}` },
});
console.log(r.status, await r.text());
```

## Example response

```json
{
  "error": {
    "code": "no_key",
    "message": "No key was sent (Orders: no key, or one that is unknown or revoked)."
  }
}
```

## Changes

- 2026-10-04: Added.
