The Launch HTTP API
Every SDK speaks this API; if we do not ship an SDK for your language, these four endpoints are the whole integration. Base URL is https://api.e-volv.io/api/public/v1/flags. Every request carries Authorization: Bearer <key>; server keys send no Origin or x-evolve-app-id, client keys must send one of them. The normative contract is the Launch SDK contract.
GET /bootstrap?v=2 — server ruleset
Returns the environment’s full ruleset for server keys, with ETag. Repeat requests send If-None-Match and get an empty 304 when nothing changed. The SDK declares v=2, the ruleset shape version it understands.
curl -s "https://api.e-volv.io/api/public/v1/flags/bootstrap?v=2" \ -H "Authorization: Bearer $EVOLVE_SERVER_KEY" \ -H 'If-None-Match: "3f2a…"'
GET /bootstrap?context=… — client values
For client keys, returns evaluated values for one context — { flagKey: { value, variant, reason } } for every flag marked client-side available. The context is URL-encoded compact JSON of at most 4,096 characters; a larger or malformed context is read as {}. A flag absent from the response evaluates to the caller’s default with reason FLAG_NOT_FOUND. No rules are ever included.
const context = encodeURIComponent(
JSON.stringify({ targetingKey: user.id, plan: user.plan })
);
const res = await fetch(
`https://api.e-volv.io/api/public/v1/flags/bootstrap?context=${context}`,
{
headers: { Authorization: `Bearer ${EVOLVE_CLIENT_KEY}` },
}
);
const { flags } = await res.json(); // { "checkout.new": { value: true, variant: "on", reason: "RULE:0" } }GET /stream — server change notifications
A server-sent events stream for server SDKs. Events:
| Event | Data | Meaning |
|---|---|---|
ruleset | {"environmentId":"…","etag":"…"} | On connect; fetch bootstrap if the etag is new. |
ruleset | {"environmentId":"…","changedAt":<ms>} | A flag changed; always refetch bootstrap with If-None-Match. |
heartbeat | {} | Every 25 s; no event for 60 s means the connection is dead. |
429 with Retry-After means the workspace is at its streaming cap: switch to polling and retry the stream afterwards. Client SDKs do not stream — they poll and re-fetch on focus.
POST /exposures
Records that subjects saw flags, for analytics and rollups. Batches of at most 1,000 exposures; always answered 202 — accepted: 0 means dropped (allowance or storage), which is not an error. Retries are idempotent on (ts, id). Each exposure carries:
| Field | Limits | Meaning |
|---|---|---|
id | 1–64, unique | UUID v4, unique per exposure |
ts | ISO-8601 UTC | When the exposure happened |
flagKey | ≤ 64 | The flag evaluated |
variant | ≤ 60, optional | The variant served |
reason | ≤ 40 | The evaluation reason |
subject | ≤ 200, optional | The context key |
contextKind | ≤ 64, optional | user, org, device, … |
contextName | ≤ 200, optional | Display name of the subject |
anonymous | optional | Subject is anonymous |
attributes | optional object | Context attributes, if opted in |
count | 1–1,000,000 | De-duplicated repeats within the window |
sampleRate | (0–1] | Sampling probability used |
curl -X POST "https://api.e-volv.io/api/public/v1/flags/exposures" \
-H "Authorization: Bearer $EVOLVE_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{"exposures":[{"id":"9f1c…","ts":"2026-09-13T15:00:00.000Z","flagKey":"checkout.new","variant":"on","reason":"RULE:0","subject":"u_1","contextKind":"user"}]}'
# 202 { "accepted": 1 }GET /ping
The install check behind flags.verify(), never a hot path:
curl -s "https://api.e-volv.io/api/public/v1/flags/ping" -H "Authorization: Bearer $EVOLVE_SERVER_KEY"
# 200 { "environment": "production", "keyKind": "server", "flags": 4, "etag": "…" }Status codes
| Response | SDK behaviour |
|---|---|
401 | Key invalid or revoked. Keep serving held values or defaults, log once, retry bootstrap every 5 min. |
403 "lacks the scope flags:read" | Disable flags with one warning; telemetry unaffected. No retry until re-init. |
403 origin / app id refused | Client SDKs: log once naming the origin or app id and the project page’s Access action; keep defaults. |
404 | Launch not enabled for the workspace, or the key is not bound to an environment. Same as 401. |
429 | Honour Retry-After (seconds); the delivery rate limit is 3,000 requests/min per key. |
5xx, timeout, network error | Retry with backoff; keep held values. |
Next: SDKs by platform or back to Launch concepts.