Guides
Errors
API error format, common codes, and how to handle failures.
All API errors use a consistent envelope:
{
"success": false,
"error": {
"code": "PROFILE_NOT_FOUND",
"message": "Social profile not found."
}
}Some errors include a details object with additional context.
HTTP status codes
| Status | Meaning |
|---|---|
400 | Invalid request body or query parameters |
401 | Missing or invalid API key |
403 | Insufficient scope or permission |
404 | Resource not found |
409 | Conflict (e.g. idempotency in progress) |
422 | Validation failed |
429 | Rate limit exceeded |
500 | Internal server error |
503 | Dependency unavailable (e.g. analytics) |
Common error codes
| Code | Description |
|---|---|
VALIDATION_ERROR | Request body failed schema validation |
INVALID_QUERY_PARAMS | Query string validation failed |
PROFILE_NOT_FOUND | SocialProfile ID does not exist |
POST_NOT_FOUND | Post ID does not exist |
QUEUE_NOT_FOUND | Publish queue ID does not exist |
AUTOMATION_NOT_FOUND | Automation ID does not exist |
MESSAGE_NOT_FOUND | Inbox message ID does not exist |
IDEMPOTENCY_IN_PROGRESS | Duplicate request still processing — retry with backoff |
ANALYTICS_UNAVAILABLE | Tinybird analytics not configured or down |
STORAGE_UNAVAILABLE | Media storage not configured |
INTERNAL_ERROR | Unexpected server error |
Idempotency
POST /v1/posts supports idempotency via Idempotency-Key header. On 409 IDEMPOTENCY_IN_PROGRESS, wait and retry — the Node SDK retries automatically.
SDK errors
The Node SDK throws AetherError with code, message, and optional httpStatus:
import { AetherError } from "aether";
try {
await client.posts.get("invalid_id");
} catch (err) {
if (err instanceof AetherError) {
console.log(err.code, err.httpStatus);
}
}MCP errors
MCP tools return human-readable error text optimized for LLM recovery — e.g. suggesting list_profiles when profile IDs are invalid.