ShipOS docs
Control plane Targeting Kill switch

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

Path parameters are shown with a leading colon, :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.

bash
curl https://app.shipos.app/api/v1/projects \
  -H "Authorization: Bearer sos_agt_xxxxxxxx"
json
{
  "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.

FieldTypeNotes
namestringRequired. Human-readable project name.
slugstringRequired. Pattern ^[a-z0-9][a-z0-9-]{0,62}$.
bash
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

Exceeding your plan's project limit returns 403 with code 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.

bash
curl "https://app.shipos.app/api/v1/projects/prj_a1b2c3/flags?key=checkout-v2" \
  -H "Authorization: Bearer sos_agt_xxxxxxxx"
json
{
  "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%.

FieldTypeNotes
keystringRequired. Business key used by SDKs and the MCP server.
namestringOptional. Display name.
descriptionstringOptional.
kindenumOne of boolean, string, number, json. Defaults boolean.
defaultValueanyOptional. Fallback served when the flag is archived.
bash
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.

bash
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.

bash
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.

bash
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.

FieldTypeNotes
enabledbooleanTurn the flag on or off in this environment.
rolloutPctnumber0–100. The percentage of traffic the flag serves ON.
rulesarrayTargeting rules (see below).
valueOnanyValue served when the flag resolves ON.
valueOffanyValue served when the flag resolves OFF.
clearKillbooleanClear an active kill switch on this environment.
expectedVersionnumberOptimistic concurrency. A mismatch returns 409 with code version_conflict.

Set a 10% rollout in prod:

bash
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 fieldNotes
idStable identifier for the rule.
descriptionOptional label.
conditionsArray (max 32). Each is { attribute, op, value }.
serveon or off.
rolloutPctOptional. 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):

bash
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.

bash
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.

FieldTypeNotes
fromEnvstringRequired. Source environment to copy from.
bash
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

Promoting replaces the entire destination environment config with the source. Because it applies immediately, treat promoting into 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.

bash
curl "https://app.shipos.app/api/v1/flags/flg_7k9m/environments/prod/stats?period=7d" \
  -H "Authorization: Bearer sos_agt_xxxxxxxx"