ShipOS docs
Edge Under 50ms SDK keys

Edge Evaluation API

The edge surface evaluates flags globally in under 50ms. Base URL https://edge.shipos.app. Authenticate with an SDK key (sos_sdk_*) scoped to a single project and environment, these keys are publishable and safe to ship in a browser.

You probably don't call this directly

The @shipos/sdk and @shipos/react packages wrap these endpoints, cache results in-memory, and poll the snapshot with If-None-Match so your request path never blocks. Reach for the raw API only if you're building a client for a language we don't ship yet, otherwise see the SDK docs.

Authentication

Send Authorization: Bearer sos_sdk_*. Because an SDK key is scoped to one project and one environment, you never pass a project or environment, the key determines both.

Evaluate

POST /v1/evaluate

Evaluate a single flag (key) or several at once (keys), optionally with an evaluation context.

FieldTypeNotes
keystringEvaluate one flag by its business key.
keysstring[]Evaluate several flags in one request.
contextobjectOptional. { userId?, attributes? }, drives percentage bucketing and targeting rules.

Evaluate a single flag:

bash
curl -X POST https://edge.shipos.app/v1/evaluate \
  -H "Authorization: Bearer sos_sdk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "checkout-v2",
    "context": {
      "userId": "u_42",
      "attributes": { "plan": "pro", "region": "eu" }
    }
  }'

Per-flag results carry the value and how it was reached:

json
{
  "checkout-v2": {
    "value": true,
    "reason": "rule_match",
    "variation": "on",
    "ruleId": "eu-pro",
    "bucket": 37
  }
}

Evaluate several flags in one round trip:

bash
curl -X POST https://edge.shipos.app/v1/evaluate \
  -H "Authorization: Bearer sos_sdk_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "keys": ["checkout-v2", "new-nav", "pricing-experiment"],
    "context": { "userId": "u_42" }
  }'
json
{
  "checkout-v2":       { "value": true,  "reason": "rollout",       "variation": "on",  "bucket": 8 },
  "new-nav":           { "value": false, "reason": "flag_disabled", "variation": "off" },
  "pricing-experiment":{ "value": "b",   "reason": "rule_match",    "variation": "b", "ruleId": "cohort-2" }
}

Snapshot

GET /v1/snapshot

Return the full snapshot for the key's environment, every flag and its config, so a client can evaluate locally. The response sets an ETag of the form "v{version}". Send it back on the next request as If-None-Match; if nothing changed, the edge replies 304 Not Modified with no body, making polling cheap.

bash
# First fetch, returns the snapshot and an ETag
curl -i https://edge.shipos.app/v1/snapshot \
  -H "Authorization: Bearer sos_sdk_xxxxxxxx"

# Subsequent polls, send the ETag back
curl -i https://edge.shipos.app/v1/snapshot \
  -H "Authorization: Bearer sos_sdk_xxxxxxxx" \
  -H 'If-None-Match: "v42"'
http
HTTP/1.1 200 OK
ETag: "v42"
Content-Type: application/json

{
  "version": 42,
  "environment": "prod",
  "flags": {
    "checkout-v2": { "enabled": true, "rolloutPct": 10, "valueOn": true, "valueOff": false, "rules": [] },
    "new-nav":     { "enabled": false, "rolloutPct": 0, "valueOn": true, "valueOff": false, "rules": [] }
  }
}

When the snapshot is unchanged, the edge short-circuits:

http
HTTP/1.1 304 Not Modified
ETag: "v42"

Reasons

The reason field explains a value: rule_match, rollout, flag_disabled, default, and similar. Use it when debugging why a user saw a given variation.