AnkraDocs
Console

API

API overview

Authentication, errors, pagination, rate limits and long-running operations in the Ankra Cloud API, and where to find every operation.

Everything in Ankra Cloud is an HTTP JSON API under https://cloud.ankra.app/v1. The console, the CLI, the Terraform provider and the MCP server all use it. The machine-readable contract is an OpenAPI 3.1 document with every route; the API reference on this site is generated from it at build time.

Authentication#

Create an API token under Settings → API tokens and send it as a bearer token:

bash
curl https://cloud.ankra.app/v1/servers \
  -H "Authorization: Bearer $ANKRA_CLOUD_TOKEN"

A token acts as the user who created it, with that user's current role, limited by the token's scope (read, read_write or a list of permissions). See Security.

The console itself uses a session cookie (ankracloud_session) instead; with a session, unsafe requests (POST, PUT, PATCH, DELETE) must also send X-CSRF-Token equal to the ankracloud_csrf cookie. API tokens need no CSRF header.

Some routes are session-only and refuse API tokens with 403, whatever their scope: signing in (/v1/auth/*), managing API tokens and members, support consents and unlinking sign-in identities. The reference marks every operation with the credentials it accepts and the permission its caller needs.

Requests and responses#

  • JSON everywhere, with snake_case field names.
  • Timestamps are RFC 3339 strings in UTC.
  • Money is in euro minor units: *_cents (1/100 €) and *_millicents (1/100 000 €).
  • Sizes use binary units in the field name: memory_mebibytes, size_gibibytes.
  • Every response carries an X-Request-Id header; audit entries caused by the request carry the same id, so quote it when you contact support.

Errors#

Errors are RFC 7807 problem documents with the content type application/problem+json:

json
{
  "type": "about:blank",
  "title": "Conflict",
  "status": 409,
  "detail": "the server must be stopped to change its plan"
}

detail is written for people and is safe to show to your users.

Status Meaning
400 The request is invalid; detail says why.
401 Not signed in, or the token is invalid, revoked or expired.
403 The role or token scope lacks the permission, the CSRF header is missing, or the route is session-only.
404 No such resource in your account. Another account's resources are always 404.
409 The resource's state does not allow this now (for example the server is not stopped, or another operation runs).
422 The account would exceed a quota; detail names the limit. Refused coupon redemptions also answer 422.
429 Rate limited; wait for Retry-After seconds.
503 No capacity or free address in the zone right now, or a host did not answer; try again later.

Pagination#

List endpoints return one page:

json
{ "items": [ … ], "next_cursor": "eyJpZCI6…" }

Pass next_cursor back as ?cursor= to get the next page; it is null on the last page. Cursors are opaque and keyset-based, so pages stay consistent while items are added. Where an endpoint takes ?limit=, the server applies its own default and maximum.

bash
cursor=""
while :; do
  page=$(curl -s "https://cloud.ankra.app/v1/servers?cursor=$cursor" -H "Authorization: Bearer $ANKRA_CLOUD_TOKEN")
  echo "$page" | jq -r '.items[].hostname'
  cursor=$(echo "$page" | jq -r '.next_cursor // empty')
  [ -z "$cursor" ] && break
done

Operations#

Anything that changes infrastructure (creating, starting, stopping or deleting servers, storages, routers, edges, load balancers, databases) runs as an operation. The API answers 202 Accepted at once with the resource and the operation that carries out the change:

json
{
  "server": { "id": "…", "state": "creating", … },
  "operation": { "id": "…", "kind": "server.create", "status": "pending", "step": "ensure_template_image", "step_index": 0, "step_count": 5 }
}

Follow it with GET /v1/operations/{id} until status is succeeded, failed (with error) or cancelled. step, step_index and step_count show progress. While a resource has an operation running, it also shows it as active_operation, and conflicting changes answer 409.

Operations are durable: a step that fails temporarily is retried with backoff until the operation's deadline, and an operation survives control plane restarts. Clients should poll every few seconds; the CLI's --wait, Terraform and the MCP tool wait_for_operation do this for you.

Quick changes that need no operation answer 200 or 201 directly: renaming, labels, firewall reads, SSH keys, init scripts and load balancer configuration, for example.

Rate limits#

Sign-in, sign-up and invitation routes are rate limited per client network and per email address. Rate-limited requests answer 429 with Retry-After. The server console accepts at most 50 inputs per second per server.

OpenAPI and clients#

  • The OpenAPI 3.1 document is docs/openapi.yaml in the Ankra Cloud repository. Each operation has a stable snake_case operationId (list_servers, create_edge) that names the CLI's ankra-cloud api <operation_id>, the MCP tools and the generated Go client's methods, so renaming one is a breaking change.
  • Its x-ankra-permission extension names the permission an operation needs; x-ankra-credential-read marks reads that reveal a credential or a live view into a server.
  • A typed Go client is generated from it (api/pkg/client/openapi), and a curated client (api/pkg/client) backs the CLI and Terraform provider.

Continue with the API reference.