# API errors

The agents API answers every refused request with an HTTP status and a JSON error body. The body has a `code`, and the `doc_url` in the body links to the section of this page for that code.

## The error body

```json
{
  "error": {
    "message": "no such agent config",
    "type": "not_found",
    "code": "agent_config_not_found",
    "doc_url": "https://getstream.io/agents/docs/api/errors/#agent_config_not_found"
  }
}
```

- `message`: what went wrong, for a person to read. Its wording can change.
- `type`: the kind of failure. The type sets the HTTP status.
- `code`: what went wrong, for a program. Branch on this field.
- `doc_url`: the section of this page for the code.

New codes can be added. Handle a code that you do not know by its `type`.

## Types and statuses

When no more specific code applies, a failure has the default code of its type.

| `type`                   | Status | Default code             |
| ------------------------ | ------ | ------------------------ |
| `invalid_request`        | 400    | `invalid_request`        |
| `authentication`         | 401    | `unauthenticated`        |
| `permission`             | 403    | `forbidden`              |
| `not_found`              | 404    | `not_found`              |
| `method_not_allowed`     | 405    | `method_not_allowed`     |
| `not_acceptable`         | 406    | `not_acceptable`         |
| `conflict`               | 409    | `conflict`               |
| `gone`                   | 410    | `gone`                   |
| `payload_too_large`      | 413    | `payload_too_large`      |
| `unsupported_media_type` | 415    | `unsupported_media_type` |
| `rate_limited`           | 429    | `rate_limited`           |
| `internal`               | 500    | `internal_error`         |
| `unavailable`            | 503    | `unavailable`            |
| `timeout`                | 504    | `timeout`                |

## Invalid request (400)

### `invalid_request`

The request is not valid, for the reason that the message gives. Correct the request, then send it again.

### `validation_failed`

The request does not match the API schema: a field is missing, has the wrong type or is out of range. The message names each field. Correct those fields, then send the request again.

### `not_configured`

This deployment does not offer the feature that the request uses. The message names the feature. Sending the request again does not help.

### `missing_organization`

The request names no organization. Send the `X-Stream-Organization-Id` header, or use an API key that belongs to an organization.

### `invalid_timezone`

A timezone in the request is not a timezone that the router knows. Use an IANA name, such as `Europe/Amsterdam`.

### `carded_session_to_native`

The session started with the person's episode cards, so it cannot move to a speech-to-speech model. Start a new session to use that model.

### `phone_number_needs_address`

The phone number needs a verified address, and the router does not support verified addresses. Choose a number in the US or Canada, or contact support.

### `no_oauth_client`

The consent for a connection cannot start: the router has no OAuth client for the connector, or the provider refused to register one. The message names each way to give the connector a client. The ways come from the connector's `client.registration`:

- `customer`: put your own OAuth client with `PUT /v1/agents/connectors/{id}/oauth-client`. Give its `client_id` and `client_secret`, or only its `client_id` for a public client. A connector whose events are verified with your app's own secret also needs `provider_app_id` and `signing_secret`. The client must list the connector's redirect URI, which is `redirect_uri` in `GET /v1/agents/connectors/{id}`.
- `managed`: let the router create the app with `PUT /v1/agents/connectors/{id}/provider-app`. Give the app's `name` and the `config_refresh_token`, the refresh token of a Slack app configuration token. A workspace admin generates that token in Slack's app settings. The message names this way only when the deployment can create the app for this connector.

When the connector has a client, start the consent again.

### `invalid_config`

The agent config that a run names cannot start a session, or the run has images and the agent cannot look at them. Correct the agent config, then start the run again.

### `image_unavailable`

The router could not use an image that the run was given. The router could not fetch it, the image is larger than 5 MB, or it is not a JPEG, PNG, WebP or GIF. For the size and the format, sending the same image again does not help: send another image. If the router could not fetch the image, check that its URL is reachable, then start the run again.

### `invalid_schedule`

The schedule of a scheduled task does not parse. For example, it gives both `at` and `in` or neither, a date, time or duration does not parse, or it has `until` without `repeat`. The message says which. Correct the schedule.

### `schedule_in_past`

The time that the schedule names has passed, or the schedule has no occurrence left. Give a time in the future.

### `schedule_too_far`

A one-time schedule, or an `in` duration, is more than one year ahead. A task can be at most one year ahead. Give an earlier time.

### `timezone_unknown`

The request gives no timezone, and neither the user nor the agent config has one. Give a `timezone` in the schedule.

### `invalid_repeat`

The router does not accept the `repeat` rule of the schedule. The message names the part that it refused. Correct the rule.

### `interval_too_short`

A run was moved to less than 15 minutes from now, and to earlier than the run that it replaces. Move it to 15 minutes from now or later. When a run is pending and not yet due, you can also move it to the time of that run or later.

## Authentication (401)

### `unauthenticated`

The request is not authenticated as its route needs. For example, a webhook delivery has no valid signature. The message says what is missing.

### `missing_customer`

The router cannot tell which app sent the request: its credentials are missing or the router did not accept them. Send the request with your app's credentials.

## Permission (403)

### `forbidden`

The caller is authenticated, but it may not do this. The message says why.

### `server_side_only`

A client-side caller sent an operation, or a field such as the `instructions` of a scheduled task, that is server-side only. Call the operation from your backend with the header `Stream-Auth-Type: server` and a token that carries `server: true`. From a client, leave the field out.

### `budget_exceeded`

The app or its organization has spent its budget. The message says which, and when the budget resets. The router refuses each retry before that time.

### `telephony_suspended`

The telephony of this app is suspended. Contact Stream support.

## Not found (404)

### `not_found`

The thing that the request names does not exist. The message says what it is.

### `modality_not_routed`

This deployment does not route the modality that the request names. The message names the modality. Use a modality that this deployment routes.

### `agent_config_not_found`

The caller has no agent config with this id. Check the id. When you resume a scheduled task, the agent config of the task was deleted: cancel the task with `DELETE /v1/agents/scheduled-tasks/{id}` and schedule a new one.

### `call_not_found`

The caller has no call with this id. Check the id.

### `campaign_not_found`

The caller has no campaign with this id. Check the id.

### `channel_account_not_found`

The caller has no channel account with this id. Check the id.

### `command_not_found`

The conversation has no command with this id that the caller can see. Check the id.

### `connection_not_found`

The caller has no connection with this id. Check the id.

### `knowledge_document_not_found`

The caller has no knowledge document with this id. Check the id.

### `knowledge_url_not_found`

The caller has no knowledge URL with this id. Check the id.

### `model_not_found`

The caller has no custom model with this id. Check the id.

### `plugin_not_found`

No plugin has this id. Check the id.

### `router_config_not_found`

The caller has no router config with this id. Check the id.

### `scheduled_task_not_found`

The caller has no scheduled task with this id. Check the id.

### `session_not_found`

The caller has no session with this id. Check the id.

### `simulation_not_found`

The caller has no simulation with this id. Check the id.

### `simulation_run_not_found`

The caller has no simulation run with this id. Check the id.

### `skill_not_found`

The caller has no skill with this id. Check the id.

### `voice_not_found`

The caller has no voice with this id. Check the id.

### `telephony_not_suspended`

The telephony of this app is not suspended, so there is no suspension to read or lift. Send no request about a suspension.

## Method not allowed (405)

### `method_not_allowed`

The route does not serve this HTTP method. Use a method that the route serves.

## Conflict (409)

### `conflict`

The request conflicts with the current state of what it names. The message says what to do.

### `name_taken`

Another agent config, router config, custom model or voice of the app already has this name, or another skill of the same agent config has it. Use a different name.

### `role_taken`

Another live agent config of the app already has this role. Only one live agent config can have a role. Leave the role out of this agent config, or delete the other agent config that has it.

### `channel_connection_taken`

Another live agent config binds this channel connection as fixed, and only one agent answers the messages of a channel connection. The message names that agent config. Remove the binding from that agent config, or bind this agent to a different connection.

### `unsynced_changes`

The sync would write over changes made since the last sync. The message lists those changes. Read `GET /v1/agents/configs/{id}/changes`, then sync again with `base_change` set to the `last_change` value of that response, to say that you have seen the changes. The sync then writes over them.

### `too_many_tasks`

The user already has the maximum number of active scheduled tasks that the agent allows. Cancel or pause a task first.

## Gone (410)

### `gone`

What the request asks for is not available any more. The message says why.

## Payload too large (413)

### `payload_too_large`

The request body is larger than the route accepts. Send a smaller body.

## Unsupported media type (415)

### `unsupported_media_type`

The route does not accept the content type or the encoding of the request body. Send the body in a content type that the route accepts.

## Rate limited (429)

### `rate_limited`

The request went over a limit, such as the daily quota of an end user, a limit of a provider, or a limit on direct calls to a connector. Wait, then send the request again. When the response has a `Retry-After` header, wait that number of seconds.

### `concurrency_limited`

The app has the maximum number of runs in flight. Start the run again after the number of seconds in the `Retry-After` header.

## Internal (500)

### `internal_error`

The router failed, and the cause is not the request. The message says only "something went wrong". To find the cause, quote the `X-Request-Id` header of the response.

## Unavailable (503)

### `unavailable`

A service that the request needs is not available now. Send the request again later.

### `memory_unavailable`

The memory store could not delete what the request asked. A session delete keeps the session, stopped. Send the same request again later.

### `model_failed`

The model failed, or the agent gave no answer. Start the run again.

### `phone_vendor_failed`

The phone vendor could not complete the request, or it did not confirm a call. Try again, and contact support if it keeps failing. If the vendor did not confirm a call, the call can still ring, so do not place it again at once.

## Timeout (504)

### `timeout`

The run did not finish within its timeout. Start it again, or give it a longer `timeout_ms`.

---

For the most recent version of this documentation, visit [https://getstream.io/agents/docs/api/errors/](https://getstream.io/agents/docs/api/errors/).