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
| Page | Endpoints |
|---|---|
| conventions | Base URL, auth header, error envelope, pagination, rate limits |
| tenants | POST /api/v1/tenants, GET /api/v1/tenants, GET /api/v1/tenants/{tenant}, tenant-admin grants |
| namespaces | POST /api/v1/tenants/{tenant}/namespaces, GET /api/v1/namespaces, GET / DELETE /api/v1/tenants/{tenant}/namespaces/{ns}, namespace-admin grants |
| manifest | PUT / GET .../manifest, GET .../manifest/versions, POST .../manifest/lint, git smart-HTTP push |
| evaluation | POST .../evaluate, POST .../evaluate/all, OPTIONS preflight, GET /api/v1/manifest/snapshot |
| events | GET /api/v1/events (SSE closure-delta protocol v2), GET .../closure (signed-token snapshot) |
| tokens | POST / 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.
| Mode | Caller | Token type | Endpoint |
|---|---|---|---|
| Manifest distribution | Rust / TypeScript SDK | namespace-read | GET .../manifest (SDK polls and refreshes; evaluation is in-process) |
| Server-side evaluation (authenticated) | Backend services, agents, scripts | namespace-read or namespace-write | POST .../evaluate{,/all} |
| Public evaluation (browsers + untrusted clients) | Browser bundles, native mobile | namespace-client | POST .../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-clienttoken. - 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 v0 | Deferred |
|---|---|
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-receive | Branch 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 headers | X-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 requiredline. - tokens — the credentials that authenticate every request.
- cli/ — user-facing CLIs that wrap these endpoints.
exd-server,exd-server-admin— operator binaries.