# Protocols

> Protocols (pre-trade checklists, EOD reviews, etc.) and their recorded responses. Full CRUD on both.
> Source: https://help.tradavity.com/api-docs/protocols
> Category: Resources

---

Pre-trade checklists, EOD reviews, weekly retrospectives. Each protocol has sections and items; recorded responses store per-item answers.

## GET /protocols

**Scope:** `read:protocols`

List protocol templates with section + item counts.

| Param | Type | Description |
| --- | --- | --- |
| `type` | enum | `pre_market`, `pre_trade`, `in_trade`, `post_trade`, `end_of_day`, `weekly`. |
| `active_only` | bool | Default false; pass `1` to exclude inactive templates. |

## GET /protocols/{id}

**Scope:** `read:protocols`

Single protocol with full nested sections + items. Each item carries its `item_type` (`checkbox`, `yes_no_na`, `rating`, `text`, `select`, `number`), label, options, and required flag.

## GET /protocols/{id}/responses

**Scope:** `read:protocols`

Paginated list of recorded responses to this protocol (metadata only).

| Param | Type | Description |
| --- | --- | --- |
| `from` / `to` | datetime | Filter by completed_at. |
| `trade_number` | int | Only responses linked to a specific trade. Copy-trade aware: if the trade is a copy, the response saved on its source trade is also returned (matches the website's protocol reader). |
| `status` | enum | `completed` (default), `draft`, `all`. |
| `limit` / `offset` | int | Pagination. |

## GET /protocols/{id}/responses/{response_id}

**Scope:** `read:protocols`

Single response with all per-item answers (each tied back to its `item_id`, `item_type`, `section_id`, and stored `value`).

---

## POST /protocols

**Scope:** `write:protocols`

Create a protocol (pre-trade checklist, EOD review, etc.) with embedded sections + items in one transaction. Subscription gate: `bill_lim_canAddProtocol` per type; over the cap returns `429 limit_reached`.

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `type` | enum | yes | `pre_market`, `pre_trade`, `in_trade`, `post_trade`, `end_of_day`, `weekly`. |
| `name` | string (1–100) | yes |  |
| `description` | string ≤ 500 | no |  |
| `set_as_default` | bool | no | Only applied when no other active protocol of this type exists for you. |
| `sections` | array (1–8) | yes | Each: `{name, items}`. |

Each section’s `items` array (1–15 items) holds objects:

| Item field | Type | Notes |
| --- | --- | --- |
| `item_type` | enum | `checkbox`, `yes_no_na`, `rating`, `text`, `select`, `number`. |
| `label` | string (1–200) |  |
| `options` | array of strings | Required for `item_type=select`: 2–10 non-empty entries, each ≤ 80 chars. |

```bash
curl -X POST https://app.tradavity.com/api/v1/protocols \
  -H "Authorization: Bearer tvty_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "pre_trade",
    "name": "Pre-Trade Checklist",
    "sections": [
      {
        "name": "Pre-flight",
        "items": [
          {"item_type": "checkbox",  "label": "Charts are loaded"},
          {"item_type": "yes_no_na", "label": "News today?"},
          {"item_type": "select",    "label": "Bias", "options": ["long","short","neutral"]}
        ]
      },
      {
        "name": "Risk",
        "items": [
          {"item_type": "rating", "label": "Conviction (1-5)"},
          {"item_type": "number", "label": "R risk"}
        ]
      }
    ]
  }'
```

## PATCH /protocols/{id}

**Scope:** `write:protocols`

Update `name`, `description`, `is_active`, `is_default`. Sections + items are **not** editable here — create a new protocol if you need to restructure (preserves the original protocol’s response history).

Setting `is_default: true` clears the default flag on every other protocol of the same type for this user. Setting `is_default: false` only clears it on this protocol.

## DELETE /protocols/{id}

**Scope:** `write:protocols`

Hard delete. Sections, items, recorded responses, and per-item answers all cascade-delete.

## POST /protocols/{id}/responses

**Scope:** `write:protocols`

Record a response to a protocol. Optionally link it to a trade.

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `item_values` | object | yes | Map of `item_id` → value. Values: checkbox `"1"`/`"0"`; yes_no_na `"yes"`/`"no"`/`"na"`; rating int 1–5; number `"123.45"`; select one of the configured options; text any string. |
| `trade_number` | int | no | Link to a trade (resolves to source for copies). |
| `status` | enum | no | `completed` (default) or `draft`. Completed responses must include all required items. |

```bash
curl -X POST https://app.tradavity.com/api/v1/protocols/80/responses \
  -H "Authorization: Bearer tvty_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "trade_number": 581,
    "item_values": {
      "640": "1",
      "641": "yes",
      "642": "long",
      "643": 4,
      "644": "1.5"
    }
  }'
```

Cross-protocol `item_id` values are rejected with `400 validation_error` and `error.details.unknown_item_ids`. Required items missing values on a `completed` response return `400` with `error.details.missing`. Per-item type/range failures (rating outside 1–5, non-numeric number, select value not in options) return `400` with `error.details.item_value_errors` mapping `item_id` to the reason.

## PATCH /protocols/{id}/responses/{response_id}

**Scope:** `write:protocols`

Edit a previously-recorded response — useful for promoting a draft to `completed`, fixing a typo, or attaching a trade after the fact. Accepted fields:

| Field | Type | Notes |
| --- | --- | --- |
| `status` | enum | `draft` or `completed`. Transitioning to `completed` stamps `completed_at` if not already set. |
| `trade_number` | int or null | Attach or detach a trade link. Resolves to source for copies, same as POST. |
| `item_values` | object | Replaces the entire per-item answer set. Same validation as POST (type/range, required-when-completed, options-allowlist). |

Returns the full re-read response (same shape as `GET /protocols/{id}/responses/{response_id}`).

## DELETE /protocols/{id}/responses/{response_id}

**Scope:** `write:protocols`

Hard-delete the response and its per-item rows. Returns `204 No Content`. Re-DELETE returns `404 not_found`.
