# Errors



> Non-2xx responses carry stable error codes and plain-language messages. This guide explains how to log errors, avoid message matching, map status codes to user or system actions, and retry only when the same request may succeed later.



- Human page: https://mailrith.com/developers/errors

- Category: API Concepts

- Reading time: 6 min read



## What this guide covers

Read Mailrith error envelopes, map status codes to behavior, and decide when a retry is safe.



## Rely on the Error Envelope

Every non-2xx Mailrith response uses a consistent error envelope. Look for the top-level `error` object and then read `type`, `code`, and `message`.

`message` is written for people and can be shown in logs or support screens. `code` is written for software and should drive your retry, alerting, and user-correction behavior.

Do not build logic by matching the full message text. Messages may become clearer over time, but the code is the stable value your integration can depend on.

1. Check the HTTP status code first so you know the broad class of failure.
2. Read `error.type` and `error.code` from the response body.
3. Log the status, code, request path, workspace or integration name, and job ID if one exists.
4. Show `error.message` to an operator when a human needs to correct input or credentials.
5. Retry only when the status and code represent a temporary condition.
6. Use [Idempotency](https://mailrith.com/developers/idempotency.md) before retrying async job creation.

- `type` groups the error into a broad category such as authentication, validation, conflict, or not found.
- `code` identifies the exact problem in a way your integration can branch on.
- `message` explains the problem in plain language for logs, dashboards, and humans troubleshooting the request.
- A successful response uses `data`; an unsuccessful response uses `error`. Handle those paths separately.

**Validation Error Response**

```json
{
  "error": {
    "type": "invalid_request",
    "code": "invalid_body",
    "message": "Request body is invalid."
  }
}
```

## Map Status Codes to Caller Behavior

HTTP status codes tell your integration the broad class of problem. Mailrith's error code tells your integration what to do next.

Do not treat every failed production request the same way. Some failures need corrected input, some need a new credential, some need a missing resource to be recreated, and some can be retried later.

Always log the status code, Mailrith error code, request path, and integration job name together. That gives the person debugging the issue enough context without exposing the full API key or private subscriber data.

- `400` means the request shape or values are invalid. Fix the request before retrying.
- `401` means the key is missing, malformed, revoked, or unknown. Replace the credential before retrying.
- `404` means the target resource does not exist in the authenticated workspace. Check the ID and workspace key.
- `409` means the request conflicts with current state. Correct the state or payload before retrying.
- `429` means the caller is sending requests too quickly. Back off before trying again.
- `500` and other server-side errors can usually be retried with backoff, but keep the original error details for troubleshooting.

## Decide When to Retry

Retries are useful only when the same request may succeed later. A timeout, a temporary network failure, or a server-side problem can be retried. A malformed request body or invalid API key should not be retried until something changes.

For background jobs and syncs, use exponential backoff so one failure does not turn into hundreds of repeated requests. For user-triggered actions, show a clear error and let the user try again after the problem is fixed.

When a create operation is safe to retry only once, use the idempotency guidance in these docs. Idempotency lets Mailrith recognize that a retry is the same logical request instead of new duplicate work.

**Simple Retry Decision Table**

```text
Retry later:
- Network timeout
- 429 rate limit response
- 500-level temporary server error

Do not retry until fixed:
- 400 invalid request body
- 401 invalid API key
- 404 wrong resource id or wrong workspace key
- 409 conflicting state
```



## Related Guides

- [Authentication](https://mailrith.com/developers/authentication.md): Every protected `v1` request resolves through a workspace-scoped API key. This page covers the header shape, workspace scoping behavior, and authentication failure handling.

- [Idempotency](https://mailrith.com/developers/idempotency.md): Import and export job creation endpoints accept idempotency keys so network retries do not queue duplicate work. This guide explains when to use a key, how to choose one, and how to store it with your own job record.

- [Import and Export Jobs](https://mailrith.com/developers/jobs.md): Imports and exports are asynchronous in `v1`. This guide explains when to queue a job, how import mappings and export filters work at a high level, how to use idempotency, and how to monitor final results without confusing queued work with completed work.
