# API conventions

Ids, dates, pages, retries, rate limits, versions and errors, the same on every endpoint.

```txt
https://api.rizamo.com/v1
```

JSON in, JSON out, with your API key as a bearer token ([Authentication](/authentication)). [openapi.json](/openapi.json) describes every endpoint, with its errors and an example of each call, and names the objects it returns (`Post`, `Account`, `Error`...) so an SDK generator makes one type of each.

## Ids [#ids]

Every id starts with its type. Treat the rest as an opaque string.

| Prefix | Object |
| --- | --- |
| `prof_` | Profile |
| `acc_` | Account |
| `conn_` | Login, an account's `connectionId` |
| `post_` | Post |
| `med_` | Media |
| `upr_` | Request for files ([Media](/media#ask-a-person-for-files)) |
| `npost_` | Post on a network |
| `thr_` | Inbox thread |
| `msg_` | Inbox message |
| `lnk_` | Short link |
| `cauto_` | Comment automation |
| `carun_` | Comment automation run |
| `ev_` | Event |
| `wh_` | Webhook endpoint |
| `whd_` | Webhook delivery |
| `user_` | Person, such as a thread's assignee |
| `req_` | Request, in `requestId` and the `Request-Id` header |

A custom field is named by its `key`, and a post's place on a network by `networkId`.

## Dates and time zones [#dates-and-time-zones]

- Times are ISO 8601 strings, answered in UTC: `2026-11-03T09:00:00.000Z`.
- Send them in UTC or with an offset. A post's `scheduledAt` may also be a local time ([Publishing](/publishing#time-zones)).
- Days, such as analytics days, are dates like `2026-11-03`. Each answer or field says which time zone its days are in.
- A time zone is a name such as `Europe/Lisbon`. An offset such as `+01:00` is not one: it ignores summer time.

## Pages [#pages]

| List | Next page | Page size |
| --- | --- | --- |
| `GET /profiles` | One page |  |
| `GET /accounts` | `cursor`, from `nextCursor` | Every item, or `limit` up to 200 |
| `GET /accounts/{id}/music` | One page |  |
| `GET /fields` | One page |  |
| `GET /posts` | `cursor`, from `nextCursor` | 100, up to 200 |
| `GET /network-posts` | `cursor`, from `nextCursor` | 50, up to 100 |
| `GET /links` | `cursor`, from `nextCursor` | 100, up to 200 |
| `GET /inbox/threads` | `cursor`, from `nextCursor` | 200, up to 200 |
| `GET /inbox/posts` | `cursor`, from `nextCursor` | 100, up to 100 |
| `GET /members` | One page |  |
| `GET /comment-automations` | `cursor`, from `nextCursor` | Every item, or `limit` up to 100 |
| `GET /comment-automations/{id}/runs` | `cursor`, from `nextCursor` | 50, up to 100 |
| `GET /analytics/posts` | `offset`, with `total` | 25, up to 100 |
| `GET /events` | `cursor`, from `nextCursor` | 50, up to 200 |
| `GET /webhooks` | One page |  |
| `GET /webhooks/deliveries` | `cursor`, from `nextCursor` | 50, up to 100 |

- **`cursor`:** pass the answer's `nextCursor` as `cursor`, with the same filters and `order`, for the next page. `nextCursor` is `null` on the last page.
- **`offset`:** the next page starts at `offset` plus `limit`; `total` is how many there are in all.
- **One page:** the whole list in one answer.
- **A thread's messages:** `GET /inbox/threads/{id}` answers every message, or with `limit` the newest ones and a `nextCursor`: pass it as `before` for the ones before them.

Every list answers its items in `items`.

## Retries [#retries]

Send an `Idempotency-Key` header on every `POST`, a new one for each request (a UUID). For 24 hours, the same request with the same key gets the first answer, with `Idempotent-Replayed: true`, instead of running again. [Errors](/errors#retries) has every rule. Over MCP, tools that change something take it as an `idempotencyKey` argument.

## Rate limits [#rate-limits]

Each team makes up to 600 calls a minute, 120 of them writes, through the API and MCP together. [Limits](/limits) says which calls count as writes. Over a limit, the answer is `429` with a `Retry-After` header and a `RateLimit-Policy` header; no header says how many calls are left.

## Versions [#versions]

- The version is in the path: `/v1`.
- A breaking change, such as a field removed or renamed or a new required field, ships only in a new version, after a deprecation with a date and at least 90 days' notice, unless a network, the law or a security issue forces a shorter period ([Terms](https://rizamo.com/legal/terms/), section 6).
- Within `v1`, Rizamo adds endpoints, fields, values and event types. Ignore those your code does not know.
- The names of the objects in [openapi.json](/openapi.json) stay as they are within `v1`, and every change to it is checked against the last one for breaking changes before it ships.
- The [changelog](/changelog) lists every change, and marks the ones you must act on.

## Errors [#errors]

Every error answers a matching HTTP status and the same shape: `{ "error": { "code": "...", "message": "..." }, "requestId": "req_..." }`. Branch on `code`, show `message` to people. [Errors](/errors) lists the codes.

## Status and support [#status-and-support]

- [Status page](https://status.rizamo.com): incidents and maintenance.
- [hi@rizamo.com](mailto:hi@rizamo.com): questions. Send the `requestId` of a call that failed.
