> For the complete documentation index, see [llms.txt](https://portavi.gitbook.io/portavi-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://portavi.gitbook.io/portavi-docs/developers/errors-and-rate-limits.md).

# Errors and rate limits

## Errors

An error answers with an HTTP status and a body like this:

```json
{
  "error": "invalid_value",
  "message": "Invalid value for: limit",
  "correlationId": "4be91c07",
  "params": { "field": "limit" }
}
```

Code against `error`; it doesn't change. `message` is English for whoever is reading the log, and can change. `params` is there when there's more to say, such as which field was wrong. If you contact support, quote the `correlationId`.

| Status | `error`                             | What it means and what to do                                                                                                                                      |
| ------ | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `invalid_value`                     | A query parameter is wrong, or isn't one the address takes. `params.field` names it.                                                                              |
| 401    | `not_authenticated`                 | The token is missing, wrong, expired or revoked. Check the `Authorization` header, or create a new token.                                                         |
| 402    | `plan_limit`                        | The workspace isn't on a plan with API access. It needs Scale or above.                                                                                           |
| 402    | `workspace_locked`, `member_locked` | The workspace, or the token owner's access, is locked, usually over billing. The API answers again once it's unlocked.                                            |
| 403    | `feature_disabled`                  | API access isn't available to this workspace yet.                                                                                                                 |
| 404    | `portfolio_not_found` and similar   | There's no such item, or the token's owner can't see it. Portavi answers the same either way.                                                                     |
| 404    | `feature_disabled`                  | The workspace has portfolios or programmes switched off.                                                                                                          |
| 429    | `rate_limited`                      | Too many requests. See below.                                                                                                                                     |
| 501    | `not_implemented`                   | The [OData feed](/portavi-docs/developers/power-bi.md#what-the-feed-doesnt-do) only: a query option it doesn't support, such as `$orderby`. Leave the option out. |
| 500    | `internal_error`                    | Something went wrong at Portavi's end. Try again shortly; if it persists, contact support with the `correlationId`.                                               |

## Rows left out of a page

Every list answers with a `Portavi-Rows-Omitted` header: how many rows of that page were left out. It's almost always `0`. A row is left out when something in it doesn't match the published format, which is a problem at Portavi's end, so the rest of the page still comes back rather than failing your whole load. Portavi is alerted to each one and fixes it.

Keep paging as usual; the cursor isn't affected. If you see a number above `0` and it doesn't go away, contact support with the address you called.

## Rate limits

| Limit                       | Applies to                            |
| --------------------------- | ------------------------------------- |
| 300 requests a minute       | each token                            |
| 1,200 requests a minute     | each workspace, across all its tokens |
| 30 failed sign-ins a minute | each IP address                       |

Over a limit, you get `429` with a `Retry-After` header: the number of seconds to wait. Wait that long, then carry on where you left off. Your cursor is still good.

To stay well inside the limits, ask for 500 items a page and load only what changed (see [Paging and incremental loads](/portavi-docs/developers/paging-and-incremental-loads.md)) rather than reloading everything.
