> ## Documentation Index
> Fetch the complete documentation index at: https://meepa.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error response format, HTTP status codes, and common error messages

All API errors use a consistent JSON envelope. The HTTP status code indicates the category of failure; the `error` field provides a human-readable description.

## Response format

Every error response has this shape:

```json theme={null}
{
  "error": "message describing what went wrong"
}
```

Successful responses use the same envelope with a `data` field instead:

```json theme={null}
{
  "data": { ... }
}
```

The `error` and `data` fields are mutually exclusive — only one will be present.

## HTTP status codes

### 4xx Client errors

| Code  | Name              | When it occurs                                                                  |
| ----- | ----------------- | ------------------------------------------------------------------------------- |
| `400` | Bad Request       | Invalid request body, missing required fields, or validation failure            |
| `401` | Unauthorized      | Missing or invalid session cookie / bot token                                   |
| `403` | Forbidden         | Valid credentials but insufficient permissions for the resource                 |
| `404` | Not Found         | Requested resource does not exist or is not visible to the caller               |
| `409` | Conflict          | Creating a resource would violate a uniqueness constraint                       |
| `410` | Gone              | Resource existed but is intentionally no longer available (e.g. expired invite) |
| `429` | Too Many Requests | Rate limit exceeded                                                             |

### 5xx Server errors

| Code  | Name                  | When it occurs                 |
| ----- | --------------------- | ------------------------------ |
| `500` | Internal Server Error | Unexpected server-side failure |

## Common error messages

### 400 Bad Request

```json theme={null}
{ "error": "invalid request body" }
{ "error": "message must be 1-4000 characters" }
{ "error": "channel name must be 1-64 characters" }
{ "error": "file too large" }
{ "error": "missing file" }
{ "error": "cannot DM yourself" }
```

### 401 Unauthorized

Returned when a protected endpoint is accessed without a valid session or token.

```json theme={null}
{ "error": "unauthorized" }
```

### 403 Forbidden

```json theme={null}
{ "error": "must be a server member" }
{ "error": "only owners and admins can perform this action" }
{ "error": "not your upload" }
```

### 404 Not Found

```json theme={null}
{ "error": "server not found" }
{ "error": "channel not found" }
{ "error": "message not found" }
{ "error": "user not found" }
{ "error": "invite not found" }
```

### 409 Conflict

```json theme={null}
{ "error": "username already taken" }
{ "error": "channel name already exists in this server" }
{ "error": "group name already taken" }
```

### 410 Gone

Returned for invite links that are no longer valid. Unlike 404, this means the resource once existed but is intentionally unavailable.

```json theme={null}
{ "error": "this invite has been revoked" }
{ "error": "this invite has expired" }
{ "error": "this invite has reached its maximum uses" }
```

### 429 Too Many Requests

Rate limit exceeded. The response includes a `Retry-After: 1` header.

```json theme={null}
{ "error": "rate limit exceeded" }
```

See [Rate Limiting](/meepachat/rate-limiting) for limits and retry strategies.

### 500 Internal Server Error

```json theme={null}
{ "error": "failed to create server" }
{ "error": "failed to send message" }
{ "error": "failed to save file" }
```

## Handling errors

| Status | Action                                                       |
| ------ | ------------------------------------------------------------ |
| 400    | Fix the request — do not retry as-is                         |
| 401    | Re-authenticate, then retry                                  |
| 403    | Do not retry — user lacks permission                         |
| 404    | Do not retry — resource does not exist                       |
| 409    | Resolve the conflict (e.g. pick a different name)            |
| 410    | Do not retry — resource is permanently gone                  |
| 429    | Wait then retry with exponential backoff (start at 1 second) |
| 500    | Retry with exponential backoff                               |

The `error` string is safe to display directly in a UI. For internationalization, match specific error strings to localized messages.

<CodeGroup>
  ```typescript TypeScript theme={null}
  async function apiRequest<T>(url: string, options?: RequestInit): Promise<T> {
    const res = await fetch(url, {
      ...options,
      headers: { 'Content-Type': 'application/json', ...options?.headers },
    });

    const body = await res.json();

    if (!res.ok) {
      const err = new Error(body.error ?? 'Unknown error') as any;
      err.status = res.status;
      throw err;
    }

    return body.data;
  }
  ```
</CodeGroup>
