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:
- specification:
api/openapi.yaml, the source from which the TypeScript types of the console are generated; - Go client:
pkg/nexoadmin, the same one used bynexoctl; - browsable reference: on the documentation site (
make docs-site) the specification is published as a static page: open the interactive Admin API reference.
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 acceptlimit(1–1000, default 1000) andcursor(the opaquenextCursorof the previous page). - Resources replaced as a whole (distributions, access rules, cache policies) return an
ETag: aPUTwithIf-Matchfails with412 precondition_failedif 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).