Skip to content

REST API

FlagWire exposes a control plane for dashboard operations and an edge data plane for SDK traffic. Use an official SDK for application evaluation unless you need to integrate directly with the wire protocol.

Service Base URL
Control plane https://api.flagwire.dev
Edge data plane https://edge.flagwire.dev

All request and response bodies use JSON unless a route returns no content or upgrades to a WebSocket.

FlagWire has three authentication modes:

Mode Use
Dashboard session cookie Control-plane project, flag, segment, key, and audit routes
Authorization: Bearer pk_live_... Remote evaluation and exposure events
Authorization: Bearer sk_live_... Bundles, local evaluation support, type generation, and events

State-changing dashboard requests also require an Origin matching the FlagWire application or site. Public browser keys require an exact configured Origin on evaluation, version, event, and WebSocket requests. Production origins use HTTPS; configured HTTP localhost origins are available only for Development and Staging. Wildcards are not accepted.

Never put an sk_live_ key in browser code, HTML, public environment variables, logs, or source control. The key query parameter is accepted only by the WebSocket stream route, where browser WebSocket APIs cannot set an authorization header.

{
"error": {
"code": "INVALID_REQUEST",
"message": "Body must contain a valid context"
}
}

Validation errors can include a details field. Clients should branch on code, not on the human message.

GET /v1/bundle
Authorization: Bearer sk_live_...
If-None-Match: "previous-etag"

This route accepts server keys only. Successful responses include an ETag and Cache-Control: private, no-cache. Send If-None-Match on refresh; unchanged state returns 304 without a body.

GET /v1/version
Authorization: Bearer pk_live_...
If-None-Match: "v17"

The route authenticates the key, entitlement, and browser origin. It returns { "version": 17 } with an ETag, or 304 when unchanged. Version checks do not create evaluation usage.

POST /v1/eval
Authorization: Bearer pk_live_...
Content-Type: application/json
{
"context": {
"key": "user-123",
"attributes": { "region": "ap-south" }
}
}

Both client and server keys are accepted. The response contains the environment version and an entry for each flag with flagVersion, variant, value, and reason.

Evaluation context is limited to 8,192 decoded bytes and 64 bounded attributes. Official SDKs send bounded X-FlagWire-SDK and X-FlagWire-Reason diagnostics. These values are untrusted and never affect authentication, entitlement, evaluation, or usage counting.

GET /v1/eval?ctx=<base64url-json> is available for transports that need a GET request. It still requires bearer authentication and returns Cache-Control: no-store.

POST /v1/events
Authorization: Bearer pk_live_...
Content-Type: application/json
[
{
"flagKey": "checkout-redesign",
"flagVersion": 7,
"variant": "on",
"count": 1
}
]

The request may contain at most 100 events and may not exceed 64 KiB. A valid batch returns 202 with no response body. Exposure ingestion is intentionally best-effort and does not block flag evaluation.

GET /v1/stream?key=pk_live_...
Upgrade: websocket

The route also accepts an authorization header when the client can provide one. The stream carries version notifications; SDKs still fetch and validate the updated snapshot or bundle before using it.

GET /v1/typegen
Authorization: Bearer sk_live_...

GET /v1/typegen/:projectId can assert the expected project. A key from another project receives 403. Responses use Cache-Control: no-store.

Except for /v1/session, the following routes require a signed-in FlagWire session. They are the routes currently used by the dashboard; they are not API-token-authenticated automation endpoints.

Method Path Purpose
GET /v1/session Read the current session
GET /v1/projects List accessible projects
POST /v1/projects Create a project and default environments
GET /v1/projects/:projectId Read a project
PATCH /v1/projects/:projectId Update a project
DELETE /v1/projects/:projectId Delete a project and revoke its SDK keys
GET /v1/projects/:projectId/environments List project environments
Method Path Purpose
GET /v1/projects/:projectId/flags List flags and environment states
POST /v1/projects/:projectId/flags Create a flag
GET /v1/flags/:flagId Read a flag
PATCH /v1/flags/:flagId Update metadata, variants, or archive state
DELETE /v1/flags/:flagId Archive a flag
PUT /v1/flags/:flagId/env/:envId Save and publish environment configuration
GET /v1/flags/:flagId/env/:envId/versions List configuration versions
POST /v1/flags/:flagId/env/:envId/rollback Roll back to an existing version
POST /v1/env/:envId/publish Force a repair publish
Method Path Purpose
GET /v1/projects/:projectId/segments List segments
POST /v1/projects/:projectId/segments Create and publish a segment
PATCH /v1/projects/:projectId/segments/:segmentId Update and publish a segment
DELETE /v1/projects/:projectId/segments/:segmentId Delete an unused segment
GET /v1/env/:envId/keys List SDK key metadata
POST /v1/env/:envId/keys Create a key; client keys require origins
PATCH /v1/keys/:keyId/origins Replace exact client-key origins
DELETE /v1/keys/:keyId Revoke an SDK key
GET /v1/projects/:projectId/audit Read 50 audit entries with cursor pagination
Method Path Purpose
GET /v1/billing/summary?orgId=... Plan state and approximate current UTC-period usage
GET /v1/billing/usage-breakdown?orgId=... Fixed attribution by project, environment, SDK/reason

Both routes require organization membership. Breakdown values use weighted sampling, include an asOf timestamp, and can be temporarily unavailable without affecting the summary or evaluation runtime. They never accept arbitrary analytics queries.

Next: bundle format or browser quickstart.