Build with Estii

Authentication

Bearer credentials, credential types, scopes, rate limits, and errors for the Estii API.

Every request outside the device-flow endpoints needs a bearer credential. Send it in the Authorization header:

curl https://api.estii.com/v1/spaces \
  -H "Authorization: Bearer estp_your_token"

The estii CLI reads the same token from the ESTII_TOKEN environment variable, or you can run estii auth login for the interactive device flow.

Verify your token

GET /v1/spaces lists the spaces your credential can reach, so it doubles as a quick check that a token works. A valid token returns 200 with the list:

curl https://api.estii.com/v1/spaces \
  -H "Authorization: Bearer estp_your_token"
{
  "items": [
    {
      "id": "sp_abc",
      "name": "Acme",
      "role": "owner",
      "is_member": true,
      "plan": "pro",
      "updated_at": 1738368000000
    }
  ],
  "next_cursor": null
}

A missing or invalid token returns 401 instead:

{ "message": "invalid or expired token" }

You can also call GET /v1/meta without a credential to read the current contract version before you build against it.

Credential types

There are two kinds of credential:

  • Personal access tokens (estp_) act as a user across the spaces that user can reach. Create them in Account settings. Best for the CLI and personal scripts.
  • Space API keys (ests_) act as a single space and keep working after the person who created them leaves. Create them in Space settings → API keys (owners and admins). Best for durable server-to-server integrations.

Scopes

Each credential carries a scope: read (read-only) or read_write (read plus mutating calls). A read credential is rejected on any mutating endpoint with a 403 and the message token scope does not permit writes.

Rate limits

Each credential is limited to 120 requests per 60-second window across the whole /v1 surface, expensive exports included. Every response advertises that quota as RateLimit-Policy: 120;w=60. The limiter runs at the edge and reports only whether a request was allowed, so there is no running remaining count to read between requests. When you exceed the limit the API responds with 429, carrying RateLimit-Remaining: 0 and a Retry-After giving the authoritative number of seconds to wait. Back off for that long, then retry.

Errors

Errors return the matching HTTP status with a JSON body:

{ "message": "bearer token required" }

A request that fails schema validation is the one exception, answering 400 with the failing fields instead:

{
  "success": false,
  "data": { "limit": "99999" },
  "error": [{ "path": ["limit"], "message": "..." }]
}
StatusMeaning
401Missing, malformed, or expired bearer credential.
403Credential is valid but its read scope forbids the mutation.
404Resource or endpoint not found.
409Request conflicts with the resource's current state.
429Rate limit exceeded. Honour the Retry-After header.
500Internal error. Retry only if the request is idempotent.

Managing credentials

Create, scope, and revoke tokens in API keys, or drive the API from the estii CLI.