> ## Documentation Index
> Fetch the complete documentation index at: https://docs.itoflow.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API conventions

> Access checks, pagination, retries, asynchronous work, status codes and units.

These rules apply across the API. Each endpoint page in the reference gives its exact parameters, schemas and status codes.

## Access

Itoflow works out who you are from your access token, never from the request. Putting a user ID, email, portfolio ID or strategy ID in a body doesn't give you access to it. Knowing an ID doesn't either: every request checks that your account owns the resource or that it has been shared with you.

Shared and public resources are read-only. Some endpoints answer `404` rather than `403` for a resource you can't access, so they don't reveal that it exists.

## Pagination

There is no single paging scheme. Use the fields each endpoint documents:

* Most lists take `limit` and `offset`. `GET /chats` also returns `pagination.hasMore`.
* Shared tables take `page` and `pageSize`.
* Chat workspace listings take `limit` and return a `cursor` for the next page.
* GitHub repository lists take `page` and `perPage` and return `nextPage`.
* Some lists, such as the news feeds, return one page only and say so.

Keep the same filters and page size while you page through a list.

## Retries

On `429`, wait for the number of seconds in `Retry-After`, then try again. Retry other reads that fail with `5xx` a few times, waiting longer each time.

Through MCP, direct `api.*` calls return `{ ok: false, status, body }` for all `4xx` responses and for any `5xx` status listed for the operation in its published OpenAPI document. A whole number of seconds in `Retry-After` adds `retry_after_seconds`; other header forms are omitted. Redirects and undocumented server failures return a generic error.

MCP calls must use the exact path parameter names in the operation. For example, `api.get_chatid({ id: "chat-1" })` uses `id`. Calling it with `{ chat_id: "chat-1" }` throws an error naming the missing `id` parameter before sending a request.

Don't automatically repeat a request that changes something, such as creating a strategy or approving a trade, after you lose its response. It may have worked. Read the current state first, using the ID it returned or the relevant list endpoint. Some writes are safe to repeat and say so:

| Request | Repeating it |
| - | - |
| Run a monitor report | Joins the run already queued or running |
| Delete a monitor or chat | Confirms or finishes the same deletion. A `404` on a repeated monitor delete means it's already gone. |
| Start an MCP research turn with the same `message_id`, message and `model_key` | Counts as the same turn, not a new one |

Running a strategy is not safe to repeat: each `POST /strategies/{id}/execute` queues a new run. Check `active-execution` first.

## Work that finishes later

Reports and strategy runs take minutes. Their endpoints return `202 Accepted` with an ID, and the work continues after the response. Some portfolio changes, such as creating or linking a portfolio, also return `202`. Follow the work with the status or event endpoint for that feature. Research turns through MCP work the same way: the call returns once the turn is accepted. `202` means the work was accepted, not that it succeeded. For trades, an accepted order is not a fill: check the trade's attempts and the portfolio afterward.

## Status codes

| Code | Meaning |
| - | - |
| `200` | Success |
| `201` | Created |
| `202` | Accepted; the work finishes later |
| `204` | Success with no body |
| `400`, `422` | The request is invalid; the body says why |
| `401` | The access token is missing, expired or not an Itoflow access token |
| `403` | Your account may not do this, or your plan doesn't include it |
| `404` | Not found, or not visible to you |
| `409` | Conflicts with the current state, such as a newer version, a duplicate name or a changed proposal |
| `410` | Gone, such as a deleted chat's workspace |
| `413` | The request body is too large |
| `429` | Rate limited |
| `502`, `503` | Temporarily unavailable; retry |

The gateway returns `400` with `error.code: "bad_request"` when the first resource identifier in a route is malformed, including an unfilled placeholder such as `/chat/{id}`. After URL decoding, that identifier must contain 1–256 characters from `A–Z`, `a–z`, `0–9`, `.`, `_`, `:`, and `-`. The body also includes `error.message` and `error.requestId`. Correct the identifier before retrying.

Most errors return a JSON body with a readable `error` message and, where the endpoint defines one, a stable `code`. For example, editing a strategy's mandate without saying why returns `400`:

```json theme={null}
{
  "error": "changeDescription is required when updating strategy behavior fields (strategyContent, allocationGuidance, constraints, rules, universe). Please provide a brief summary of what changed and why.",
  "code": "CHANGE_DESC_REQUIRED"
}
```

Match on `code`, not on the message text, which can change. A few endpoints put the code in `error` instead, such as the monitor news feed's `"error": "NOT_FOUND"`; each endpoint page lists its responses.

## Units and formats

* **Money** is often a decimal string, such as `"10000.50"`; parse it as a decimal, not a float. Some fields are plain numbers. Keep the currency field with each amount. Fields ending in `_usd`, a portfolio's `total_value`, and quote `price` are in US dollars.
* **Cents:** fields ending in `_cents` are whole numbers of the currency's smallest unit.
* **Credits** measure usage. They are not money.
* **Percentages:** some fields take `4` to mean 4%; others take fractions such as `0.04`. The feature guide or field description says which.
* **Times** are usually ISO 8601 strings. Some fields, mostly in billing, are Unix seconds or milliseconds instead. Check the field's schema before you parse it.
* **Schedules** use a local time such as `09:00` plus an IANA time zone such as `America/New_York`, so they follow daylight-saving changes.
* **Symbols** are `TICKER.EXCHANGE`, such as `AAPL.US`. See [Find and resolve symbols](https://docs.itoflow.ai/guides/symbols.md).

Some response objects can contain more fields than the schema lists. Ignore fields you don't recognize.


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