Skip to content

Admin API reference

The Admin API is the REST API with which the console, nexoctl and your automation administer Nexo. It is served on the console listener (port 9001) under /api/v1, exchanges JSON and is described by an OpenAPI 3.1 document:

Local HTML reference

The page is generated by Redocly and already contains every operation and schema, so it can be browsed offline too:

make docs-api                     # bin/docs/admin-api.html (requires Node.js: npx @redocly/cli)
xdg-open bin/docs/admin-api.html  # or open on macOS

Alternatively, api/openapi.yaml can be opened with any OpenAPI viewer (Swagger UI, the OpenAPI extension of your editor) or imported into an HTTP client such as Postman or Bruno.

Authentication

Every request uses one of two forms.

AWS Signature Version 4 (scripts, SDKs, CLI): service s3, region of the server, Authorization header. Presigned URLs are not accepted. With curl:

$ curl -s --aws-sigv4 "aws:amz:us-east-1:s3" --user "$ACCESS_KEY:$SECRET_KEY" \
    "https://console.example.com/api/v1/users?limit=2"
{"items":[{"accessKey":"alice", ...}],"nextCursor":"..."}

Console session (browser): POST /api/v1/auth/login with {"accessKey": ..., "secretKey": ...} sets the nexo_session cookie (HttpOnly, SameSite=Strict) and returns a csrfToken. Every request that changes something must carry the X-CSRF-Token header and come from the console's origin:

curl -s -c jar -H 'Content-Type: application/json' \
  -d '{"accessKey":"admin","secretKey":"supersecret"}' https://console.example.com/api/v1/auth/login
# {"id":"...","accessKey":"admin","identity":{...},"csrfToken":"...","expiresAt":"..."}
curl -s -b jar -X POST -H 'Content-Type: application/json' \
  -H "X-CSRF-Token: $CSRF" -H 'Origin: https://console.example.com' \
  -d '{"name":"report"}' https://console.example.com/api/v1/buckets

Without credentials the response is 401 unauthenticated; without the CSRF token 403 invalid_csrf_token.

Authorization

Every operation requires policy actions, listed in the specification in the x-nexo-actions field: admin:* actions (for example admin:CreateUser, admin:ManageDistributions, admin:InvalidateCache) and s3:* actions for the operations on buckets and objects. They are evaluated by the same engine as the IAM policies, so a user can be granted only the part of the administration they need. Some operations are self-service: every user manages their own access keys and their own share links. GET /api/v1/me/permissions tells what the current user can do (the console uses it to show only the allowed actions).

Errors

Errors are RFC 9457 application/problem+json documents with a stable snake_case code:

{
  "type": "about:blank",
  "title": "Not Found",
  "status": 404,
  "detail": "bucket not found: report",
  "instance": "/api/v1/buckets/report",
  "code": "bucket_not_found",
  "requestId": "DFEBCBB5A41BB795"
}

Common codes: unauthenticated, access_denied, invalid_csrf_token, invalid_argument, bucket_not_found, object_not_found, user_not_found, policy_not_found, conflict, malformed_policy (with positioned errors), invalid_configuration (with ruleErrors), invalid_access_rule, public_access_blocked, object_locked, entity_too_large, not_implemented. The requestId also appears in the server logs and audit.

Pagination and concurrency

  • Lists answer {"items": [...], "nextCursor": "..."} and accept limit (1–1000, default 1000) and cursor (the opaque nextCursor of the previous page).
  • Resources replaced as a whole (distributions, access rules, cache policies) return an ETag: a PUT with If-Match fails with 412 precondition_failed if another client changed them in the meantime.

Operation groups

Tag Main paths For
session /auth/login, /auth/logout, /auth/session, /me/permissions console session
server /info, /usage, /heal, /service/restart, /service/stop status, usage, healing, service
monitoring /metrics, /metrics/query, /trace, /logs, /audit metrics, streaming trace and logs (SSE), audit
diagnostics /profile, /speedtest/{kind} pprof profiles, speed tests
buckets /buckets, /buckets/{bucket}/{versioning,policy,quota,tags,objectlock,encryption,access,lifecycle,events,cors} buckets and their settings
objects /buckets/{bucket}/objects, .../stat, .../versions, .../download, .../download-zip, .../retention, .../legal-hold browsing and managing objects
uploads /buckets/{bucket}/objects/upload, /buckets/{bucket}/uploads/... simple and multipart uploads from the console
shares /shares, /buckets/{bucket}/objects/share, /presign, /post-policy share links, presigned URLs, POST policies
users, groups, access-keys, policies /users, /groups, /access-keys, /policies, /policies/simulate identities and permissions
config /config, /config/{subsys}, /config/schema, /config/export, /config/import dynamic configuration
cluster /cluster/export, /cluster/import, /locks metadata migration, distributed locks
notify, kms /notify/targets, /kms/status, /kms/keys, /kms/reseal event targets, KMS keys
access-rules /buckets/{bucket}/access-rules, .../test, .../public, /access/block-public access rules, block public access
distributions /distributions, /distributions/{id}/{test,sign,origin-secret/rotate}, /keygroups, /routing/resolve distributions, key groups, routing
certificates /certificates, /dns-providers certificates of the distributions, DNS providers of the ACME DNS-01 challenge
cache /cache/{policies,settings,inspect,stats,invalidations}, /distributions/{id}/cache/..., /distributions/{id}/invalidations cache, invalidations, warm-up, webhooks

The complete specification has 180 operations; the HTML reference shows them with parameters, bodies and example responses.

Examples

SIG=(--aws-sigv4 "aws:amz:us-east-1:s3" --user "$ACCESS_KEY:$SECRET_KEY")
API=https://console.example.com/api/v1

curl -s "${SIG[@]}" "$API/info"                                      # status of the deployment
curl -s "${SIG[@]}" "$API/buckets/photos/objects?prefix=2026/&limit=100"   # objects under a prefix
curl -s "${SIG[@]}" -X POST -H 'Content-Type: application/json' \
  -d '{"paths":["/index.html"],"soft":true}' "$API/distributions/site/invalidations"   # cache invalidation

For a typed client in Go use pkg/nexoadmin; for other languages generate a client from the specification (for example with openapi-generator).