Skip to main content

Server API

HTTP reference for exd-server. This tree is the authoritative shape of every endpoint, broken out by route family. The user-facing CLI that wraps these endpoints lives in cli/; the operator CLI that provisions the server lives in cli/server/.

Looking for an SDK call instead? SDK references — Rust, TypeScript, Python, Java — are higher-level. Reach for this server-API reference when you're building a custom SDK, calling endpoints directly from curl / Postman, or extending an existing SDK to a new endpoint.


Surface

PageEndpoints
conventionsBase URL, auth header, error envelope, pagination, rate limits
tenantsPOST /api/v1/tenants, GET /api/v1/tenants, GET /api/v1/tenants/{tenant}, tenant-admin grants
namespacesPOST /api/v1/tenants/{tenant}/namespaces, GET /api/v1/namespaces, GET / DELETE /api/v1/tenants/{tenant}/namespaces/{ns}, namespace-admin grants
manifestPUT / GET .../manifest, GET .../manifest/versions, POST .../manifest/lint, git smart-HTTP push
evaluationPOST .../evaluate, POST .../evaluate/all, OPTIONS preflight, GET /api/v1/manifest/snapshot
eventsGET /api/v1/events (SSE closure-delta protocol v2), GET .../closure (signed-token snapshot)
tokensPOST / GET / DELETE /api/v1/tokens — covered in the tokens reference

Deployment modes

The server is designed for three concurrent traffic patterns. A single flag namespace may use any subset.

ModeCallerToken typeEndpoint
Manifest distributionRust / TypeScript SDKnamespace-readGET .../manifest (SDK polls and refreshes; evaluation is in-process)
Server-side evaluation (authenticated)Backend services, agents, scriptsnamespace-read or namespace-writePOST .../evaluate{,/all}
Public evaluation (browsers + untrusted clients)Browser bundles, native mobilenamespace-clientPOST .../evaluate{,/all} (only when bound env has public_evaluate = true)

Choose by who controls the runtime:

  • Trusted backend you operate → SDK (manifest distribution) for latency and resilience, or server-side evaluation when the SDK is impractical.
  • Browser or untrusted client → namespace-client token.
  • Flag branches on attributes the user can lie about → don't use namespace-client. Evaluate server-side and pass the variant down, or restructure the flag.

Implementation status

The shipped exd-server crate (v0) implements the manifest-distribution slice, the admin endpoints needed to stand a flag namespace up end-to-end, server-side evaluation under authenticated tokens, and the namespace-client (browser) public-evaluation surface with CORS:

Implemented in v0Deferred
POST / GET /api/v1/tenants (superadmin only)PUT / DELETE /api/v1/tenants/{tenant}/admins/{user_id}
GET /api/v1/tenants/{tenant}
POST /api/v1/tenants/{tenant}/namespaces, GET /api/v1/namespaces (cross-tenant list with ?tenant= filter), GET /api/v1/tenants/{tenant}/namespaces/{namespace}DELETE on namespaces; admin-grant endpoints
Token mint / list / rotate / revoke (POST / GET / DELETE /api/v1/tokens, POST /tokens/{id}/rotate) including namespace-client with environment_slug + allowed_origins
PUT / GET .../manifest, GET .../manifest/versions, POST .../manifest/lint, ETag + If-None-Match conditional GETs, optional If-Version on push
Git smart-HTTP push (/info/refs, /git-upload-pack, /git-receive-pack) with linting in pre-receiveBranch protection / required reviewers; signed-commit enforcement; multi-instance shared bare-repo storage
POST .../evaluate{,/all} for authenticated tokens AND namespace-client; per-flag flag_not_found entries; X-Exd-Manifest-Version response header; CORS response headersX-Exd-Dry-Run request header; request-side X-Exd-Manifest-Version (canary against historical version)
OPTIONS .../evaluate{,/all} CORS preflight without authentication
Cursor pagination on every list endpoint
GET /healthz (operational; not specced here)
GET /api/v1/events (SSE protocol v2 closure deltas)
GET .../closure (signed-token snapshot endpoint backing snapshot delivery and resync)
GET /api/v1/manifest/snapshot
Rate-limit enforcement, telemetry pipeline, audit events, human session tokens (SSO / email-domain login)

Deferred items do not require a breaking SDK change to adopt later — the SDK call site is Namespace::builder().server(...).api_token(...).build() regardless of which endpoints the server adds underneath. The user-guide chapter docs/user-guide/exd-server.md walks through the v0 surface end-to-end and re-states the deferred list with the operational reasoning behind each cut.


See also

  • conventions — every endpoint inherits these (auth, error envelope, pagination, rate limits).
  • access-control — the permission model behind every Auth required line.
  • tokens — the credentials that authenticate every request.
  • cli/ — user-facing CLIs that wrap these endpoints.
  • exd-server, exd-server-admin — operator binaries.