# Error Codes

The LVNG API uses standard HTTP status codes and returns structured error responses. Socket.io connections emit error events with their own code set.

## HTTP Error Response Formats

The API uses two error response shapes depending on the endpoint.

### Simple Format

Used by most endpoints. Contains a top-level `error` string, a `message`, and an optional `hint`.

```json
{
  "error": "Bad Request",
  "message": "Missing required field: message",
  "hint": "The 'message' field is required for chat requests."
}
```

### Structured Format

Used by endpoints with field-level validation. Contains a `success` flag, a machine-readable `code`, and a `details` array.

```json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request parameters",
    "details": [
      { "field": "name", "message": "required" },
      { "field": "type", "message": "must be one of: agent, workflow, twin" }
    ]
  }
}
```

## HTTP Status Codes

| Status | Name | Description |
|--------|------|-------------|
| 200 | OK | Request succeeded. Response body contains the requested data. |
| 201 | Created | Resource successfully created. Response body contains the new resource. |
| 400 | Bad Request | The request was malformed or missing required parameters (VALIDATION_ERROR). |
| 401 | Unauthorized | Authentication failed. Missing, invalid, or expired token/API key. |
| 403 | Forbidden | Authenticated but insufficient permissions for the requested action. |
| 404 | Not Found | The requested resource does not exist or is not accessible to your tenant. |
| 409 | Conflict | The resource already exists or the request conflicts with current state (ALREADY_EXISTS). |
| 429 | Too Many Requests | Rate limit exceeded for your plan or endpoint. |
| 500 | Internal Server Error | An unexpected error occurred on the server (DATABASE_ERROR, INTEGRATION_ERROR). |
| 503 | Service Unavailable | The service is temporarily unavailable or undergoing maintenance. |

## HTTP Error Codes

These codes appear in the `error.code` field of structured error responses. Use them for programmatic error handling.

| Code | Description |
|------|-------------|
| VALIDATION_ERROR | Request body or parameters failed validation. Check the details array for specific field errors. |
| NOT_FOUND | The referenced resource does not exist or is not accessible within your tenant scope. |
| ALREADY_EXISTS | A resource with the same unique identifier already exists. |
| DATABASE_ERROR | An internal database operation failed. Usually transient -- retry the request. |
| INTEGRATION_ERROR | A third-party integration or downstream service call failed. |
| PERMISSION_DENIED | Your role does not have permission to perform this action on the resource. |

## Socket.io Error Codes

Socket.io errors are emitted as `error` events on the client connection. Each error contains a `code` and `message`.

```json
{
  "code": "RATE_LIMIT_EXCEEDED",
  "message": "Too many events. Please wait."
}
```

| Code | Description |
|------|-------------|
| RATE_LIMIT_EXCEEDED | Too many socket events in the current window (default: 100 per 60s). |
| INVALID_MESSAGE_CONTENT | Message content is missing, empty, or exceeds the maximum length. |
| MESSAGE_NOT_FOUND | The referenced message does not exist in the channel. |
| REACTION_FAILED | Failed to add or remove a reaction from the message. |
| INVALID_EMOJI | The emoji value is not valid or not supported. |
| PRESENCE_UPDATE_FAILED | Failed to update user presence status. |
| CHANNEL_NOT_FOUND | The specified channel does not exist. |
| CHANNEL_ACCESS_DENIED | You do not have access to the specified channel. |
| CHANNEL_JOIN_FAILED | Failed to join the channel. You may not have permission. |
| CHANNEL_LEAVE_FAILED | Failed to leave the channel. |
| CHANNEL_UPDATE_FAILED | Failed to update channel properties. |
| PERMISSION_DENIED | Insufficient permissions for the requested socket action. |
| INVALID_UPDATE | The update payload is malformed or contains invalid fields. |
| CONVERSATION_JOIN_FAILED | Failed to join the conversation room. |
| CONVERSATION_LEAVE_FAILED | Failed to leave the conversation room. |
| CONVERSATION_REJOIN_FAILED | Failed to rejoin a previously active conversation. |
| INVALID_CONVERSATION_DATA | Conversation payload is missing required fields. |
| SWARM_SUBSCRIBE_ERROR | Failed to subscribe to swarm execution updates. |
| INVALID_SWARM_DATA | Swarm subscription payload is invalid. |
| ACTIVITY_JOIN_ERROR | Failed to join the activity tracking room. |
| INVALID_ACTIVITY_DATA | Activity payload is missing required fields. |
| INVALID_ACTIVITY_ROOM | The activity room identifier is not valid. |
| CALL_JOIN_FAILED | Failed to join the voice/video call session. |
| CALL_LEAVE_FAILED | Failed to leave the call session. |
| INVALID_CALL_DATA | Call payload is missing required fields. |

## Rate Limit Errors

When you exceed your rate limit, the API returns a `429` status with headers indicating when you can retry.

```http
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-03-19T14:31:00.000Z
Retry-After: 60
Content-Type: application/json

{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded",
  "retryAfter": 60
}
```

### Rate Limit Headers

| Header | Description |
|--------|-------------|
| X-RateLimit-Limit | Maximum requests allowed in the current window. |
| X-RateLimit-Remaining | Requests remaining in the current window. |
| X-RateLimit-Reset | ISO 8601 timestamp when the rate limit window resets. |
| Retry-After | Seconds to wait before retrying. Only present on 429 responses. |

## Troubleshooting

| Status | Resolution |
|--------|------------|
| 400 Bad Request | Check that all required fields are present and correctly typed. Validate JSON syntax. |
| 401 Unauthorized | Verify your Authorization header contains a valid JWT or that your x-api-key header contains a valid API key. |
| 403 Forbidden | Check your role and permissions for the resource. Contact your workspace admin if you need elevated access. |
| 404 Not Found | Verify the resource ID is correct and that it belongs to your customer_id scope. |
| 409 Conflict | Check if a resource with the same unique identifier already exists. Use an update operation instead. |
| 429 Too Many Requests | Wait until the Retry-After period has elapsed. See the Rate Limits page for per-endpoint and per-plan limits. |
| 500 Internal Server Error | Retry the request. If the error persists, contact support with the request details. |
| 503 Service Unavailable | Check the status page at lvng.ai/status. Retry with exponential backoff. |
