Flags API
The control-plane endpoints for managing projects, flags, and their per-environment configuration. Base URL https://app.shipos.app/api/v1. Authenticate with a session cookie, an agent key (sos_agt_*), or an admin key (sos_adm_*).
Path params use colon style
:id, :env, for readability. Substitute the real UUID or environment name (dev, staging, or prod) when you make the request.Projects
GET /api/v1/projects
List the projects in the caller's org. Each project includes its environments.
curl https://app.shipos.app/api/v1/projects \
-H "Authorization: Bearer sos_agt_xxxxxxxx"{
"projects": [
{
"id": "prj_a1b2c3",
"name": "Shop",
"slug": "shop",
"environments": [
{ "id": "env_dev", "name": "dev" },
{ "id": "env_stg", "name": "staging" },
{ "id": "env_prd", "name": "prod" }
]
}
]
}POST /api/v1/projects
Create a project. Automatically provisions dev, staging, and prod environments. Enforces the plan's project limit.
| Field | Type | Notes |
|---|---|---|
name | string | Required. Human-readable project name. |
slug | string | Required. Pattern ^[a-z0-9][a-z0-9-]{0,62}$. |
curl -X POST https://app.shipos.app/api/v1/projects \
-H "Authorization: Bearer sos_agt_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Shop", "slug": "shop" }'Plan limits
plan_limit.Flags
GET /api/v1/projects/:id/flags
List a project's flags with per-environment configs. Pass ?key= to filter to a single flag.
curl "https://app.shipos.app/api/v1/projects/prj_a1b2c3/flags?key=checkout-v2" \
-H "Authorization: Bearer sos_agt_xxxxxxxx"{
"flags": [
{
"id": "flg_7k9m",
"key": "checkout-v2",
"name": "New checkout",
"kind": "boolean",
"defaultValue": false,
"archivedAt": null,
"environments": {
"dev": { "enabled": true, "rolloutPct": 100, "valueOn": true, "valueOff": false, "version": 4, "rules": [] },
"staging": { "enabled": true, "rolloutPct": 25, "valueOn": true, "valueOff": false, "version": 2, "rules": [] },
"prod": { "enabled": false, "rolloutPct": 0, "valueOn": true, "valueOff": false, "version": 1, "rules": [] }
}
}
]
}POST /api/v1/projects/:id/flags
Create a flag. It gets a config in every environment, all starting OFF at 0%.
| Field | Type | Notes |
|---|---|---|
key | string | Required. Business key used by SDKs and the MCP server. |
name | string | Optional. Display name. |
description | string | Optional. |
kind | enum | One of boolean, string, number, json. Defaults boolean. |
defaultValue | any | Optional. Fallback served when the flag is archived. |
curl -X POST https://app.shipos.app/api/v1/projects/prj_a1b2c3/flags \
-H "Authorization: Bearer sos_agt_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"key": "checkout-v2",
"name": "New checkout",
"kind": "boolean",
"defaultValue": false
}'GET /api/v1/flags/lookup?projectSlug=&key=
Look up a flag by its business key within a project. This is the endpoint the MCP server uses to resolve a flag before acting on it.
curl "https://app.shipos.app/api/v1/flags/lookup?projectSlug=shop&key=checkout-v2" \
-H "Authorization: Bearer sos_agt_xxxxxxxx"GET /api/v1/flags/:id
Fetch a single flag with its per-environment configs.
PATCH /api/v1/flags/:id
Update flag metadata only. Body accepts name and description. To change behavior, update an environment config instead.
curl -X PATCH https://app.shipos.app/api/v1/flags/flg_7k9m \
-H "Authorization: Bearer sos_agt_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "description": "Ramps the redesigned checkout flow" }'DELETE /api/v1/flags/:id
Soft-archive a flag (sets archived_at). SDKs then fall back to the flag's defaultValue.
curl -X DELETE https://app.shipos.app/api/v1/flags/flg_7k9m \
-H "Authorization: Bearer sos_agt_xxxxxxxx"Environment config
A flag's behavior lives in its per-environment config: whether it's enabled, the rollout percentage, targeting rules, and the on/off values.
PUT /api/v1/flags/:id/environments/:env/config
Update one environment's config. All fields are optional.
| Field | Type | Notes |
|---|---|---|
enabled | boolean | Turn the flag on or off in this environment. |
rolloutPct | number | 0–100. The percentage of traffic the flag serves ON. |
rules | array | Targeting rules (see below). |
valueOn | any | Value served when the flag resolves ON. |
valueOff | any | Value served when the flag resolves OFF. |
clearKill | boolean | Clear an active kill switch on this environment. |
expectedVersion | number | Optimistic concurrency. A mismatch returns 409 with code version_conflict. |
Set a 10% rollout in prod:
curl -X PUT https://app.shipos.app/api/v1/flags/flg_7k9m/environments/prod/config \
-H "Authorization: Bearer sos_agt_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"rolloutPct": 10,
"expectedVersion": 1
}'Targeting rules
rules is an array (max 64). Each rule serves on or off to contexts matching its conditions, optionally scoped by rolloutPct. Each rule can have up to 32 conditions.
| Rule field | Notes |
|---|---|
id | Stable identifier for the rule. |
description | Optional label. |
conditions | Array (max 32). Each is { attribute, op, value }. |
serve | on or off. |
rolloutPct | Optional. Applies the rule to a percentage of matches. |
Condition operators: eq, neq, in, not_in, contains, gt, gte, lt, lte, semver_eq, semver_gt, semver_lt.
Add targeting rules (pro users in the EU always get ON):
curl -X PUT https://app.shipos.app/api/v1/flags/flg_7k9m/environments/prod/config \
-H "Authorization: Bearer sos_agt_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"id": "eu-pro",
"description": "Pro users in the EU",
"conditions": [
{ "attribute": "plan", "op": "eq", "value": "pro" },
{ "attribute": "region", "op": "in", "value": ["eu", "uk"] }
],
"serve": "on"
}
]
}'POST /api/v1/flags/:id/environments/:env/kill
Pull the kill switch: serve OFF to everyone in this environment via the fast KV path, in seconds. Executes immediately and is written to the audit log.
curl -X POST https://app.shipos.app/api/v1/flags/flg_7k9m/environments/prod/kill \
-H "Authorization: Bearer sos_agt_xxxxxxxx"POST /api/v1/flags/:id/environments/:env/promote
Copy a full environment config from another environment (e.g. staging → prod). Executes immediately and is written to the audit log.
| Field | Type | Notes |
|---|---|---|
fromEnv | string | Required. Source environment to copy from. |
curl -X POST https://app.shipos.app/api/v1/flags/flg_7k9m/environments/prod/promote \
-H "Authorization: Bearer sos_agt_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "fromEnv": "staging" }'Promote overwrites the target config
prod as a deploy, and remember the flag's kill switch is always one call away if you need to undo it.GET /api/v1/flags/:id/environments/:env/stats?period=24h|7d|30d
Hourly per-variation evaluation counts for the environment over the requested period.
curl "https://app.shipos.app/api/v1/flags/flg_7k9m/environments/prod/stats?period=7d" \
-H "Authorization: Bearer sos_agt_xxxxxxxx"