# Errors and retries

Handle structured errors and distinguish a rejected request from uncertain provider acceptance.

Source: https://docs.ravenrelay.joshlab.site/errors

Agent index: https://docs.ravenrelay.joshlab.site/llms.txt
OpenAPI: https://docs.ravenrelay.joshlab.site/openapi.json

## Error format

Example error

```
{
  "error": {
    "code": "domain_not_verified",
    "message": "The sending domain has not been verified."
  }
}
```

| Code | What to do |
| --- | --- |
| invalid_api_key | Check the key, project and revocation state. |
| production_not_enabled | Request operator review for live sending. |
| domain_not_verified | Check the exact sender domain, DKIM and MAIL FROM. |
| validation_error | Correct request fields; do not retry unchanged. |
| message_too_large | Reduce the message below the size limit. |
| idempotency_conflict | Use the original body for this key. |
| quota_exceeded | Check the shared workspace delivery allowance. |
| test_recipient_not_allowed | Use recipients on exact verified domains connected to the development project, including CC and BCC. |
| rate_limit_exceeded | Back off before retrying the same operation. |

## Request retries

After an API timeout, retry the identical body with the original Idempotency-Key. For an explicit validation or authorization error, fix the cause first. Read the existing message before deliberately creating another send.

## Uncertain sending acceptance

> The underlying delivery API has no idempotency token. A timeout, lost connection or abandoned processing claim may mean the delivery provider accepted the message even though RavenRelay did not receive confirmation.

These messages show failed with delivery_unknown and are never automatically resent. Check the provider before submitting a new copy. Authenticated provider events can later reconcile the outcome without resending.
