Atelier201 websiteJoin the waitlist
REST APIErrors
REST API

Errors

The error envelope, every code, and which are worth retrying.

Every failure has the same shape:

JSON
{
  "error": {
    "type": "not_found_error",
    "code": "resource_not_found",
    "message": "This site does not exist.",
    "docs_url": "https://atelier201.com/docs/api/errors#resource_not_found"
  },
  "request_id": "req_01K9X7"
}

Branch on code, never on message. Codes are contract; messages are written for people and improve over time. Some errors add a details object with what you need to act, such as the current revision after a write conflict.

Which to retry

StatusRetry?
429Yes, after Retry-After.
5xxOnly for an idempotent request (GET, PUT, DELETE). A POST that fails with a 5xx may already have been applied. Re-read the resource first.
4xxNo. The request is wrong and will be wrong again.

Every code

authentication_required

authentication_error · HTTP 401

No credential was sent. Add an Authorization: Bearer header.

invalid_api_key

authentication_error · HTTP 401

The credential is not recognised. It may belong to a workspace that no longer exists.

api_key_expired

authentication_error · HTTP 401

The key passed its expiry date. Create a new one.

api_key_revoked

authentication_error · HTTP 401

Somebody revoked it. This is permanent.

insufficient_scope

permission_error · HTTP 403

The credential is valid but was not granted the scope this endpoint needs. The message names it. Re-issue the credential; the scope cannot be widened in place.

feature_not_available

permission_error · HTTP 403

The plan does not include this. Publishing a draft answers this: details.blockers holds plan_required, and action_url opens the site’s plan.

admin_required

permission_error · HTTP 403

The action is restricted to workspace admins: publishing, rolling back, taking a site offline, deleting a site and changing its domains.

invalid_request

invalid_request_error · HTTP 400

The body or the query did not validate. The message says which field.

unknown_field

invalid_request_error · HTTP 400

A field was sent that this endpoint does not accept. Inputs are strict on purpose: a silently ignored field is a bug you would find much later.

invalid_parameter

invalid_request_error · HTTP 400

A parameter was the wrong shape, usually a malformed id.

invalid_cursor

invalid_request_error · HTTP 400

The pagination cursor is not one we issued. Start the list again.

request_too_large

invalid_request_error · HTTP 413

The body exceeded the hard limit.

resource_not_found

not_found_error · HTTP 404

No such object in THIS workspace. A resource belonging to another workspace returns this too, deliberately: distinguishing them would let you discover which ids exist.

conflict

conflict_error · HTTP 409

The resource exists and the request is well formed, but its current state forbids the action. Unlike a 400, this may succeed later. Common causes:

  • A write conflict. Someone changed a file since you read it. details.reason is revision_conflict, and details.current_revision is the revision to read, and details.paths lists each file with the hash you expected and the hash found.
  • A publish against a stale review, or a build that cannot go live. Review again, and read details.blockers.
  • A plan limit, such as too many drafts or a domain beyond the plan. The message names the limit, and action_url the page that lifts it.

result_not_ready

conflict_error · HTTP 409

The work has not finished, for example a site that is still being created. Wait a few seconds rather than retrying immediately.

idempotency_key_reused

conflict_error · HTTP 409

The Idempotency-Key you sent to an endpoint that accepts one was already used for a different request in this workspace. Nothing was done. Use a new key for new work; a repeat of the same request with the same key returns the first answer instead.

insufficient_credits

invalid_request_error · HTTP 402

Not enough credits. Stop and tell a human; retrying will not help.

request_too_large_for_plan

invalid_request_error · HTTP 422

The body is within the hard limit but above what this plan allows.

result_expired

not_found_error · HTTP 410

The result was deleted by the retention policy. It is not coming back.

rate_limited

rate_limit_error · HTTP 429

Too many requests. Wait for Retry-After before trying again. The same wait is in the body, as data: details.retry_after_seconds and details.retry_at (an ISO date), also in MCP tool errors and in the CLI’s JSON output.

internal_error

api_error · HTTP 500

Something failed on our side. Quote the request_id.

service_unavailable

api_error · HTTP 503

A dependency is down or in maintenance. Retry after a delay.

Use these docs with your AI tools

An AI agent can read this documentation directly. You do not need an account or an API key. Everything here is public and read-only.

Query these docs via MCP

Recommended

Add this server to Claude, Claude Code, Cursor, Mistral, or any tool that supports MCP. Your agent can then search Atelier201 Docs documentation and read it in full, instead of answering from memory.

https://atelier201.com/docs/mcp
  • searchFind the passages that answer a question.
  • fetchRead one page in full, as Markdown.
  • list_pagesSee every page in this documentation.

Query these docs over HTTP

The same tools also work as plain web requests. Use this for scripts, or for any tool that does not support MCP. There is one endpoint per tool. Arguments go in the query string, and the answer comes back as JSON.

https://atelier201.com/docs/api/docs/search?query=custom+domain

Read the OpenAPI description. It is built from the same definitions as the tools, so it always matches what the endpoints do.

Read these docs as Markdown

Add .md to any page URL to get its Markdown source. You can also send the headerAccept: text/markdown to the page URL itself.

To read the whole documentation in one file, open llms-full.txt. For a short index of every page, open llms.txt.