EddytorDocs & API

REST API

Call the Eddytor REST API - auth, the OpenAPI spec, the error envelope, and rate limits.

The REST API (https://<host>/api/v1/…) is the control plane for apps and integrations: tables, schema, domains, storage, org, and auth. The machine-readable contract is the OpenAPI spec at /spec - generate a client from it rather than hardcoding routes.

Auth

Send Authorization: Bearer <credential>:

  • an OAuth 2.1 access token (short-lived, ~15 min - refresh it), or
  • an API key (edd_live_…) for headless / server-to-server (effective permission = role ∩ key scope).

Browser SPAs use a cookie session + CSRF token and the CORS allowlist; server-side callers use a bearer token/API key and can ignore CSRF/CORS.

The unified error envelope

Every error is the same shape - branch on code, show message, log request_id:

{ "code": "not_found", "message": "Table not found",
  "request_id": "550e8400-…",
  "details": [{ "field": "name", "message": "must not be empty" }] }

Codes: validation_error, authentication_error, forbidden, not_found, conflict, unprocessable_entity, rate_limited, provider_reauth_required, provider_upstream_error, internal_error.

Good to know

Always capture request_id - it's the key for support and log correlation. A 5xx without an envelope is an opaque internal fault: retry with backoff, don't treat it as a client error.

Rate limits

IP-based, 60 requests/min by default (OAuth endpoints stricter at 10/min). Every response carries X-RateLimit-{Limit,Remaining,Reset}; a 429 includes Retry-After - honor it with backoff.

The read/write boundary

Heads up

Row DML is not REST. Insert/update/merge/delete go over the gRPC path - there is no REST merge endpoint. Do writes via the CLI (insert/merge), an SDK, or MCP write tools. Bulk reads go over Flight SQL, not REST pagination.

DML guardrail failures return a structured write-error: unique/PK → 409, domain/check/not-null → 422, type → 400.

Gotchas

  • Access tokens expire (~15 min) - for long-running integrations use an API key, or implement refresh; don't pin one access token.
  • provider_reauth_required means a delegated storage credential lapsed - the user must re-link, not retry.
  • Discover routes from /spec - don't guess endpoints.

Next

On this page