---
title: "Errors"
description: "Dravo's error format is built so an AI agent can read a failure and correct its own input. Status codes and per account errors explained."
section: "Core concepts"
url: https://dravo.dev/docs/concepts/errors
---
# Errors

## AI-native errors

Errors are designed to be actionable by an automated client. Instead of an
opaque failure, you get a structured message that names the field or condition to
fix, so an agent can adjust its input and retry without a human in the loop.

There are two layers: errors that reject the request outright, and errors that
happen per account during delivery.

## Request level errors

If the request itself is invalid (missing field, text too long, a scheduled time
in the past), the call fails synchronously with a JSON body:

```json
{ "detail": "scheduled_at must be at least 60 seconds in the future." }
```

Nothing is enqueued in this case. Fix the input and send it again.

## Per account delivery errors

A request can be accepted (`202`) and still fail for some accounts during
delivery. Those outcomes live in the publish history, one result per account:

```json
{
  "account_id": "acc_8f2c1d",
  "provider": "x",
  "status": "failed",
  "platform_post_id": null,
  "error_code": "media_unsupported",
  "error_message": "X media upload requires a re-connected account with media.write.",
  "raw_response": { }
}
```

`error_code` is stable and machine friendly; `error_message` is human readable;
`raw_response` carries the untouched provider payload for debugging. When some
accounts succeed and others fail, the job status is `partial`. See
[handling partial failures](/docs/guides/handling-partial-failures).

## HTTP status codes

| Code | Meaning |
| --- | --- |
| `200` / `201` / `202` / `204` | Success (202 means accepted for async delivery). |
| `400` | Validation error or malformed input. |
| `401` | Missing or invalid API key or JWT. |
| `404` | Resource not found. |
| `409` | Conflict (for example canceling a job already in flight). |
| `413` | Media file too large. |
| `415` | Unsupported media type. |
| `422` | Semantically invalid request. |
| `429` | Rate limited. |
| `502` | Upstream provider or storage failure. |
