Feature flags

Control feature releases and configuration with user targeting, gradual rollouts, and experiments. $0.03 per 1,000 remote evaluations. The base URL is https://www.motor.dev/feature_flags, and the OpenAPI 3.1 specification describes each endpoint.

Try it

Sign in to try the API here with one of your team's keys. Requests use that key's permissions and spending limit. Standard charges apply.

Quick start

Use feature flags to enable features for specific users, roll out changes gradually, and update configuration without deploying your app. This example creates a flag that enables a new checkout for paid plans, then checks its value for one user. Set $MOTOR_KEY to your Motor secret API key.

  1. Create a project and an environment. Each environment has its own flags. Use the project ID returned by the first request in place of ffp_... in the second.

    curl https://api.motor.dev/feature_flags/projects \
      -H "Authorization: Bearer $MOTOR_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -d '{"key": "web", "name": "Web app"}'
    
    curl -i https://api.motor.dev/feature_flags/environments \
      -H "Authorization: Bearer $MOTOR_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -d '{"project_id": "ffp_...", "key": "production", "name": "Production"}'
  2. Create the flag using the environment ID returned above in place of ffe_.... Copy the environment response's ETag header into If-Match; this prevents your request from overwriting a concurrent change. The rule below enables the flag for users on the pro or team plan:

    curl https://api.motor.dev/feature_flags/environments/ffe_.../flags \
      -H "Authorization: Bearer $MOTOR_KEY" \
      -H "Idempotency-Key: $(uuidgen)" \
      -H 'If-Match: "ff:ffe_...:1"' \
      -d '{"key": "new_checkout", "name": "New checkout", "type": "boolean", "enabled": true,
           "variations": [{"key": "off", "value": false}, {"key": "on", "value": true}],
           "off_variation": "off", "fallthrough": {"variation": "off"},
           "rules": [{"id": "paid", "conditions": [{"attribute": "attributes.plan", "op": "in", "values": ["pro", "team"]}],
                      "serve": {"variation": "on"}}]}'
  3. Evaluate the flag for a user. The response includes the value, the selected variation, and the reason it was selected.

    curl https://api.motor.dev/feature_flags/evaluations \
      -H "Authorization: Bearer $MOTOR_KEY" \
      -d '{"environment_id": "ffe_...",
           "context": {"targeting_key": "user_123", "attributes": {"plan": "pro"}},
           "flags": [{"key": "new_checkout", "type": "boolean", "default": false}]}'
    {"environment_id": "ffe_...", "revision": "2", "results": [{"key": "new_checkout", "value": true,
      "variation": "on", "reason": "TARGETING_MATCH", "rule_id": "paid", "error_code": null, ...}]}

Download the OpenAPI document to generate a client. Generated clients handle API requests. To evaluate flags locally, cache experiment assignments, or reconnect to event streams, implement the behavior described in this guide.

Projects and environments

A project groups environments, such as staging and production. Each environment has its own flags, segments, revisions, SDK keys, and client access policy. A change in one environment never changes another. Your application chooses an environment by its ID.

Use a separate environment, such as staging, to test your flags. The feature flags API does not support test mode: omit the Motor-Mode header or set it to live. Requests with Motor-Mode: test are rejected before processing. Staging and production have the same pricing.

Revisions and ETags

Each configuration change publishes a new revision of the environment. The environment response includes an ETag that identifies its current configuration. Send this value in If-Match when you change the configuration. If it has changed since you read it, Motor returns 412 revision_conflict. Fetch the environment again, review the changes, and retry with the new ETag if your update still applies.

Motor retains the current revision and up to 99 previous revisions from the last 90 days. POST /environments/{env}/rollback restores the flags and segments of a revision as a new revision. It restores the whole environment, not one flag, and it doesn't restore policies or credentials.

Preview environments

POST /environments/{env}/clone copies an environment's flags and segments into a temporary preview environment. Test your changes there, compare them with /diff, and use /promotions to propose a change set in the destination environment.

Flags and targeting

A flag has a type (boolean, string, number, or object) and 1 to 20 variations. Each variation has a stable key and a value. Rules select variations by key, so you can update a variation's value without changing the rules that refer to it.

Motor evaluates a flag in this order:

  1. A disabled flag serves off_variation with reason DISABLED.
  2. Each prerequisite flag must be enabled and return the required variation. If any prerequisite fails, the flag returns off_variation with reason PREREQUISITE_FAILED.
  3. Individual targets select a variation for a matching targeting key.
  4. Rules are checked in order. The first rule whose conditions all match determines the result, with reason TARGETING_MATCH, or SPLIT for a rollout.
  5. If no target or rule matches, the flag uses its fallthrough outcome, with reason DEFAULT, or SPLIT for a rollout.

A condition tests a value in the evaluation context, selected by an attribute such as attributes.plan or a path such as ["attributes", "account", "plan"]. Comparisons require matching types: 1 does not equal "1". Comparison operators, including negative comparisons, return false for missing or null values. Use not_exists to match a missing or null value. Segments let you reuse groups of conditions; not_in_segment matches when the segment does not, which can include contexts without attributes.

Percentage rollouts consistently assign each subject, such as a user or account, to one of 100,000 buckets. Motor hashes the environment ID, flag key, seed, selector, and bucket value with SHA-256. Changing only the weights preserves each subject's bucket. The selected bucket value must be a nonempty string; a missing targeting key produces TARGETING_KEY_MISSING.

For large groups, upload an audience of up to 1,000,000 targeting keys. For application-specific logic, use a custom strategy. Run the strategy in your local evaluator, or pass its result in strategy_results when requesting remote evaluation.

Remote evaluation

POST /evaluations evaluates 1 to 100 flags for one context. For each flag, provide its expected type and a default value. If the flag is missing, its type does not match, or evaluation fails, Motor returns your default with reason ERROR and an error_code.

Each accepted request is billed as one remote evaluation, regardless of the number of flags or their results. A request that times out may still have been billed. Use your default values instead of retrying automatically. Evaluation requests do not accept an Idempotency-Key header.

Credentials:

  • A secret key with the evaluator role, or an environment's server SDK key, can evaluate any flag in that environment with a context you supply.
  • A publishable key evaluates client-visible flags for an anonymous anon:<UUID v4> subject without attributes.
  • A client token can evaluate its permitted flags using the subject and attributes set by your server.

Browsers and mobile apps

Use a publishable key in browsers and mobile apps. Add its key ID to the environment's client access policy and list the exact origins allowed to make browser requests:

curl -X PATCH https://api.motor.dev/feature_flags/environments/ffe_... \
  -H "Authorization: Bearer $MOTOR_KEY" -H 'If-Match: "ff:ffe_...:2"' \
  -d '{"client_access": {"publishable_key_ids": ["key_..."],
       "allowed_origins": ["https://app.example.com"], "allow_native": false}}'

Mark the flags that clients may see with "client_visible": true. Other flags are reported as missing to these clients. Client responses omit rule IDs and prerequisite keys.

For a signed-in user, your server authenticates the user, then issues a client token for that subject and its attributes. The browser sends the token; it can't change the subject or attributes.

See Client tokens for token issuance, revocation, and a request example.

Cache results separately for each credential, environment, and subject. Clear the cache when the user signs out or the token changes, and discard responses for the previous identity. Your app must generate and store its anonymous ID; Motor does not identify users through device fingerprinting.

Local evaluation

Your server can evaluate flags locally to avoid an API request for every evaluation. GET /environments/{env}/config returns a complete configuration snapshot at no charge. Your evaluator must follow the evaluation order in Flags and targeting; the OpenAPI document defines the snapshot schema. Use the language-neutral fixtures in Motor's evaluation corpus to check your evaluator's results.

We recommend this policy:

  • Poll every 30 seconds, with 10% jitter, and send the last ETag in If-None-Match. Motor returns 304 if the configuration has not changed.
  • Time out a configuration request after 5 seconds, or 30 seconds with audience chunks.
  • Apply a newer revision by replacing the entire cached configuration at once. Remove any cached flags absent from the new snapshot.
  • Treat the configuration as stale 30 seconds after the last successful fetch. Continue using it for up to 300 more seconds, then return your default values. You can set this grace period to between 0 and 86,400 seconds.
  • On 401, 403, or 404, clear the configuration at once.
  • Before using a configuration, fetch and verify every audience chunk referenced by that snapshot.

For an experiment, Motor must assign each subject to a variation before you can evaluate it locally: call POST /environments/{env}/assignments, keep the receipt, and serve the variation locally afterward. Until the assignment arrives, serve your default. Use remote evaluation if the snapshot's schema version or an outcome is not supported by your evaluator.

Report counts of local evaluations each minute with POST /environments/{env}/evaluation_counts, so that flag statistics are complete. Reports aren't billed.

Streams

GET /environments/{env}/stream is a server-sent event stream. On connection and after each change, it sends a configuration event containing the revision and configuration tag. A heartbeat arrives every 30 seconds. Configuration events contain no rules or values. When one arrives, fetch the configuration or evaluate the flags again.

curl -N https://api.motor.dev/feature_flags/environments/ffe_.../stream \
  -H "Authorization: Bearer $MOTOR_SDK_KEY"
  • Browsers send the credential in the Authorization header with fetch, never in the URL.
  • Reconnect after 2 seconds, then back off to 30 seconds with jitter, and send Last-Event-ID. On a reset event, fetch fresh data without sending If-None-Match: server clients fetch the configuration, while browser and mobile clients evaluate their flags again.
  • Streams close after 15 minutes and must be reconnected. A change to the credential, key, policy, or team can also close a stream with a revoked event. If reconnection fails with 401, 403, or 404, clear your state.
  • Keep polling as a fallback. Concurrent stream limits are 5,000 per team, 100 per credential, and 20 per publishable key from a single IP address.

OpenFeature (OFREP)

Each environment supports version 0.4.0 of the OpenFeature Remote Evaluation Protocol (OFREP). Use an OFREP-compatible OpenFeature provider to connect without a Motor-specific SDK. Point a provider at the environment's base URL and send a Motor credential as a bearer token:

https://api.motor.dev/feature_flags/environments/ffe_...
  POST /ofrep/v1/evaluate/flags/{key}
  POST /ofrep/v1/evaluate/flags
  GET  /ofrep/v1/events

Motor maps targetingKey to the targeting key and other context fields to attributes. A client token's context is fixed: send {}. Reason DEFAULT is STATIC in the protocol. Only 200 responses are billed as remote evaluations; bulk 304 responses are not billed. When the key reaches its monthly spending limit, Motor returns 429 with X-Motor-Error: limit_reached. The Retry-After header tells the provider to wait until the start of the next UTC month. Use default values until then.

Experiments

  1. Create the metrics you want to measure, such as a binary metric named purchase.
  2. Create an experiment for a flag. Define its arms (the variations to compare), primary metric, enrollment window, and analysis settings.
  3. Set a rule or the flag's fallthrough to {"experiment": "checkout_test", "fallback_variation": "off"}, then start the experiment.
  4. Evaluations enroll eligible subjects and return an assignment_receipt. Include this receipt in exposure events when users see the feature and in metric events when they take the action you are measuring.
  5. Read /results to compare the variations. Sequential analysis supports checking results while the experiment is running. Call /conclude with your chosen variation to propose a change set that replaces the experiment with that variation.
curl https://api.motor.dev/feature_flags/events \
  -H "Authorization: Bearer $MOTOR_KEY" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"events": [{"id": "7b8e...", "environment_id": "ffe_...", "occurred_at": "2026-10-05T12:00:00Z",
                   "type": "metric", "metric_key": "purchase", "value": 1, "assignment_receipt": "motor_fa_..."}]}'

Once assigned, a subject keeps the same variation. Link an anonymous key to the signed-in user with /identity_links. To move from another vendor without moving users between arms, import their assignments into a draft experiment.

Approvals and releases

An environment's approval policy can require 1 to 5 reviewers to approve configuration changes. When approvals are required, create a change set against the current revision, submit it for review, collect the required approvals, and apply it. Motor publishes all operations in a single revision. If the environment has changed since the change set was created, applying it fails with a revision conflict.

A release plan schedules configuration changes, such as increasing a rollout to 10%, then 50%, then 100%. Guardrails can pause or roll back the plan when a metric crosses a configured threshold. An environment admin can always turn one flag off with /flags/{flag}/disable, without approvals.

Access policies assign roles (reader, evaluator, editor, reviewer, admin) to users and service accounts. These identities are called principals. Team admins create service accounts on the API keys page. All keys belonging to a service account share its identity for access checks.

Configuration as code

GET /environments/{env}/export returns flags and segments in Motor's export format. Keep it in Git, and apply it with /sync:

curl https://api.motor.dev/feature_flags/environments/ffe_.../sync \
  -H "Authorization: Bearer $MOTOR_KEY" \
  -d '{"base_revision": "7", "dry_run": true, "flags": [...], "segments": [...]}'

Sync creates or updates flags and segments by key. Omitted fields keep their current values; supplied arrays replace the existing arrays in full. By default, sync performs a dry run: it returns a diff without saving changes. With "dry_run": false and an idempotency key, sync publishes the changes immediately, or proposes a change set if the environment requires approvals. If nothing has changed, sync leaves the current revision unchanged. prune_tag deletes existing flags that have the specified tag but are absent from the request.

Imports from other vendors

Export from your vendor account, then send the JSON to /imports with its format: launchdarkly, unleash, growthbook, flagsmith, configcat, or motor. Motor never asks for vendor credentials. An import creates a draft change set. Review and apply it to publish the changes.

Motor translates rules only when it can preserve their behavior. Vendor rollouts, regular expressions, and negative conditions that match missing values require manual mapping, so the import enters needs_mapping status. Replace each such resource with a Motor flag or segment through /imports/{import}/mappings. Motor uses different rollout buckets from other vendors, so migrating a percentage rollout can change which variation a user receives. For experiments, import existing assignments to preserve each user's variation.

Webhooks

Subscribe to feature flag changes through the Motor event subscription API. Choose specific events, such as feature_flags.flag.updated, or feature_flags.* for all feature flag events. The shared guide covers endpoint registration, signature verification, delivery retries, and event history.

Retries and automation

POST requests that change data require an Idempotency-Key containing 1 to 128 printable ASCII characters. If a response is lost, retry with the same key, body, and headers: Motor returns the recorded response with Idempotency-Replayed: true for 35 days. Use a new key for a new operation. Evaluations, previews, diffs, and dry runs do not accept an idempotency key.

Motor checks for a recorded response before checking If-Match. Retrying a successful change with the same idempotency key therefore returns the original response, even if its ETag is now out of date. A new change with an outdated ETag fails with 412.

If you lose the response that issued an SDK key, client token, or webhook secret, retry with the same issuing key and idempotency key to recover the secret. Recovery is available for up to 35 days, until the credential expires or is revoked. Secrets cannot be retrieved through other read requests. Erasing a subject's data also removes that subject's data from stored replay responses.

For a staging-to-production pipeline: clone or sync into staging, test, compare with /diff, promote with /promotions, collect approvals, apply, and delete the preview environment.

Pricing and limits

  • Remote evaluations: $0.03 per 1,000 requests. Each accepted request counts once, regardless of how many flags it evaluates.
  • Experiment metric events: $0.03 per 1,000 accepted records. Exposures and duplicates aren't billed.
  • Configuration reads, streams, local evaluation, evaluation count reports, and webhooks aren't billed, within rate and transfer limits.
  • Usage is billed from the first remote evaluation or accepted metric event; there is no free allowance.

Each API key's monthly spending limit applies to feature flags usage. Once the limit is reached, evaluation requests return 402 limit_reached until the next UTC month; use your defaults.

GET /limits returns your resource limits, including the default limit of 5,000 flags per environment. Contact Motor support to request an increase.

Projects

POST/feature_flags/projects

Create a project

Creates a project, which groups environments. Credentials: a secret key.

ParameterLocationDescription
Request body
{
  "key": "main",
  "name": "Main",
  "description": "The web app"
}
FieldTypeDescription
keyrequired
namerequired
description
Responses

201Success.

{
  "id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "main",
  "name": "Main",
  "description": "The web app",
  "environment_count": 0,
  "version": "1",
  "created_at": "2026-10-05T00:00:03Z",
  "updated_at": "2026-10-05T00:00:03Z"
}

401

409

422

429

GET/feature_flags/projects

List projects

Lists the team's projects in a stable order. Credentials: a secret key.

ParameterLocationDescription
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
keyqueryFilter by an exact resource key.
Responses

200Success.

{
  "data": [
    {
      "id": "ffp_9kunJd7bTWCR64Mv18pj45",
      "key": "main",
      "name": "Main",
      "description": "The web app",
      "environment_count": 0,
      "version": "1",
      "created_at": "2026-10-05T00:00:03Z",
      "updated_at": "2026-10-05T00:00:03Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/projects/{project_id}

Get a project

Returns a project. Credentials: a secret key.

ParameterLocationDescription
project_idpath
Responses

200Success.

{
  "id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "main",
  "name": "Main",
  "description": "The web app",
  "environment_count": 0,
  "version": "1",
  "created_at": "2026-10-05T00:00:03Z",
  "updated_at": "2026-10-05T00:00:03Z"
}

401

404

429

PATCH/feature_flags/projects/{project_id}

Update a project

Changes the name or description of a project. Credentials: a secret key.

ParameterLocationDescription
project_idpath
Request body
{
  "name": "Main app"
}
FieldTypeDescription
name
description
Responses

200Success.

{
  "id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "main",
  "name": "Main app",
  "description": "The web app",
  "environment_count": 0,
  "version": "2",
  "created_at": "2026-10-05T00:00:03Z",
  "updated_at": "2026-10-05T00:00:12Z"
}

401

404

412

422

428

429

DELETE/feature_flags/projects/{project_id}

Delete a project

Deletes a project. Delete its environments first. Credentials: a secret key.

ParameterLocationDescription
project_idpath
Responses

200Success.

{
  "id": "ffp_8kXTivFLdeu2mgeL2kTj41",
  "deleted": true
}

401

404

409

412

428

429

Environments

POST/feature_flags/environments

Create an environment

Creates an environment in a project. Each environment has its own flags, segments, revisions, and credentials. Credentials: a secret key.

ParameterLocationDescription
Request body
{
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "production",
  "name": "Production"
}
FieldTypeDescription
project_idrequiredstring
keyrequired
namerequired
description
client_access
expires_at
Responses

201Success.

{
  "id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "production",
  "name": "Production",
  "description": "",
  "revision": "1",
  "client_access": {
    "publishable_key_ids": [],
    "allowed_origins": [],
    "allow_native": false
  },
  "approval_policy": {
    "required": 0,
    "reviewer_principal_ids": [],
    "allow_author": false
  },
  "expires_at": null,
  "status": "active",
  "flag_count": 0,
  "segment_count": 0,
  "created_at": "2026-10-05T00:00:15Z",
  "updated_at": "2026-10-05T00:00:15Z"
}

401

404

409

422

429

GET/feature_flags/environments

List environments

Lists the environments that the key can read. Credentials: a secret key.

ParameterLocationDescription
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
keyqueryFilter by an exact resource key.
project_idqueryFilter by project ID.
Responses

200Success.

{
  "data": [
    {
      "id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
      "key": "production",
      "name": "Production",
      "description": "",
      "revision": "1",
      "client_access": {
        "publishable_key_ids": [],
        "allowed_origins": [],
        "allow_native": false
      },
      "approval_policy": {
        "required": 0,
        "reviewer_principal_ids": [],
        "allow_author": false
      },
      "expires_at": null,
      "status": "active",
      "flag_count": 0,
      "segment_count": 0,
      "created_at": "2026-10-05T00:00:15Z",
      "updated_at": "2026-10-05T00:00:15Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}

Get an environment

Returns an environment and its current revision. The ETag is the environment's management tag, used in If-Match when changing its configuration. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Responses

200Success.

{
  "id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "production",
  "name": "Production",
  "description": "",
  "revision": "1",
  "client_access": {
    "publishable_key_ids": [],
    "allowed_origins": [],
    "allow_native": false
  },
  "approval_policy": {
    "required": 0,
    "reviewer_principal_ids": [],
    "allow_author": false
  },
  "expires_at": null,
  "status": "active",
  "flag_count": 0,
  "segment_count": 0,
  "created_at": "2026-10-05T00:00:15Z",
  "updated_at": "2026-10-05T00:00:15Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}

Update an environment

Changes the name, description, client access policy, or approval policy. Only a team admin can change the approval policy, and the request must include X-Change-Comment. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "description": "Live traffic"
}
FieldTypeDescription
name
description
client_access
expires_at
approval_policy
Responses

200Success.

{
  "id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "production",
  "name": "Production",
  "description": "Live traffic",
  "revision": "2",
  "client_access": {
    "publishable_key_ids": [],
    "allowed_origins": [],
    "allow_native": false
  },
  "approval_policy": {
    "required": 0,
    "reviewer_principal_ids": [],
    "allow_author": false
  },
  "expires_at": null,
  "status": "active",
  "flag_count": 0,
  "segment_count": 0,
  "created_at": "2026-10-05T00:00:15Z",
  "updated_at": "2026-10-05T00:00:24Z"
}

401

404

409

412

422

428

429

DELETE/feature_flags/environments/{environment_id}

Delete an environment

Deletes an environment and revokes its credentials. First remove its flags, segments, audiences, and experiments, and stop any running release plans. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Responses

200Success.

{
  "id": "ffe_3XoQo1f4XSAPiuEVqMZz18",
  "deleted": true
}

401

404

409

412

428

429

Flags

POST/feature_flags/environments/{environment_id}/flags

Create a flag

Creates a flag and publishes a new revision. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "key": "checkout",
  "name": "New checkout",
  "type": "boolean",
  "enabled": true,
  "client_visible": true,
  "variations": [
    {
      "key": "off",
      "value": false
    },
    {
      "key": "on",
      "value": true
    }
  ],
  "off_variation": "off",
  "fallthrough": {
    "variation": "off"
  },
  "rules": [
    {
      "id": "paid",
      "conditions": [
        {
          "segment": "paid",
          "op": "in_segment"
        }
      ],
      "serve": {
        "variation": "on"
      }
    }
  ],
  "tags": [
    "web"
  ]
}
Responses

201Success.

{
  "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout",
  "name": "New checkout",
  "description": "",
  "type": "boolean",
  "enabled": true,
  "client_visible": true,
  "variations": [
    {
      "key": "off",
      "value": false
    },
    {
      "key": "on",
      "value": true
    }
  ],
  "off_variation": "off",
  "fallthrough": {
    "variation": "off"
  },
  "prerequisites": [],
  "targets": [],
  "rules": [
    {
      "id": "paid",
      "conditions": [
        {
          "segment": "paid",
          "op": "in_segment"
        }
      ],
      "serve": {
        "variation": "on"
      }
    }
  ],
  "value_schema": null,
  "tags": [
    "web"
  ],
  "owner_principal_id": null,
  "purpose": "release",
  "expires_at": null,
  "archived": false,
  "revision": "5",
  "created_at": "2026-10-05T00:00:39Z",
  "updated_at": "2026-10-05T00:00:39Z"
}

401

404

409

412

422

428

429

GET/feature_flags/environments/{environment_id}/flags

List flags

Lists the environment's flags in a stable order, with optional filters. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
keyqueryFilter by an exact resource key.
tagqueryOnly flags with this tag.
ownerqueryFilter by the ID of the user or service account that owns the flag.
purposequeryOnly flags with this purpose.
lifecyclequeryOnly flags that are active, expired (past expires_at), archived, or stale (without evaluations for 30 days).
Responses

200Success.

{
  "data": [
    {
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "banner",
      "name": "Banner text",
      "description": "",
      "type": "string",
      "enabled": true,
      "client_visible": false,
      "variations": [
        {
          "key": "plain",
          "value": "Welcome"
        },
        {
          "key": "sale",
          "value": "Sale today"
        }
      ],
      "off_variation": "plain",
      "fallthrough": {
        "variation": "plain"
      },
      "prerequisites": [],
      "targets": [],
      "rules": [],
      "value_schema": null,
      "tags": [],
      "owner_principal_id": null,
      "purpose": "release",
      "expires_at": null,
      "archived": false,
      "revision": "6",
      "created_at": "2026-10-05T00:00:42Z",
      "updated_at": "2026-10-05T00:00:42Z"
    },
    {
      "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "checkout",
      "name": "New checkout",
      "description": "",
      "type": "boolean",
      "enabled": true,
      "client_visible": true,
      "variations": [
        {
          "key": "off",
          "value": false
        },
        {
          "key": "on",
          "value": true
        }
      ],
      "off_variation": "off",
      "fallthrough": {
        "variation": "off"
      },
      "prerequisites": [],
      "targets": [],
      "rules": [
        {
          "id": "paid",
          "conditions": [
            {
              "segment": "paid",
              "op": "in_segment"
            }
          ],
          "serve": {
            "variation": "on"
          }
        }
      ],
      "value_schema": null,
      "tags": [
        "web"
      ],
      "owner_principal_id": null,
      "purpose": "release",
      "expires_at": null,
      "archived": false,
      "revision": "6",
      "created_at": "2026-10-05T00:00:39Z",
      "updated_at": "2026-10-05T00:00:39Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/flags/{flag_id}

Get a flag

Returns a flag. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
flag_idpath
Responses

200Success.

{
  "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout",
  "name": "New checkout",
  "description": "",
  "type": "boolean",
  "enabled": true,
  "client_visible": true,
  "variations": [
    {
      "key": "off",
      "value": false
    },
    {
      "key": "on",
      "value": true
    }
  ],
  "off_variation": "off",
  "fallthrough": {
    "variation": "off"
  },
  "prerequisites": [],
  "targets": [],
  "rules": [
    {
      "id": "paid",
      "conditions": [
        {
          "segment": "paid",
          "op": "in_segment"
        }
      ],
      "serve": {
        "variation": "on"
      }
    }
  ],
  "value_schema": null,
  "tags": [
    "web"
  ],
  "owner_principal_id": null,
  "purpose": "release",
  "expires_at": null,
  "archived": false,
  "revision": "6",
  "created_at": "2026-10-05T00:00:39Z",
  "updated_at": "2026-10-05T00:00:39Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}/flags/{flag_id}

Update a flag

Changes a flag and publishes a new revision. Omitted fields keep their current values; supplied arrays replace the existing arrays in full. If the environment requires approvals, Motor returns 409 approval_required. Propose a change set instead. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
flag_idpath
Request body
{
  "description": "The checkout of 2026"
}
Responses

200Success.

{
  "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout",
  "name": "New checkout",
  "description": "The checkout of 2026",
  "type": "boolean",
  "enabled": true,
  "client_visible": true,
  "variations": [
    {
      "key": "off",
      "value": false
    },
    {
      "key": "on",
      "value": true
    }
  ],
  "off_variation": "off",
  "fallthrough": {
    "variation": "off"
  },
  "prerequisites": [],
  "targets": [],
  "rules": [
    {
      "id": "paid",
      "conditions": [
        {
          "segment": "paid",
          "op": "in_segment"
        }
      ],
      "serve": {
        "variation": "on"
      }
    }
  ],
  "value_schema": null,
  "tags": [
    "web"
  ],
  "owner_principal_id": null,
  "purpose": "release",
  "expires_at": null,
  "archived": false,
  "revision": "7",
  "created_at": "2026-10-05T00:00:39Z",
  "updated_at": "2026-10-05T00:00:51Z"
}

401

404

409

412

422

428

429

DELETE/feature_flags/environments/{environment_id}/flags/{flag_id}

Delete a flag

Deletes an archived flag, provided no other resource depends on it. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
flag_idpath
Responses

200Success.

{
  "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
  "deleted": true
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/flags/{flag_id}/disable

Turn a flag off in an emergency

Sets enabled to false without approvals, and cancels the flag's running release plan. Requires the environment admin role. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
flag_idpath
Request body
{
  "comment": "Incident 42"
}
FieldTypeDescription
commentrequired
Responses

200Success.

{
  "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "banner",
  "name": "Banner text",
  "description": "Retiring",
  "type": "string",
  "enabled": false,
  "client_visible": false,
  "variations": [
    {
      "key": "plain",
      "value": "Welcome"
    },
    {
      "key": "sale",
      "value": "Sale today"
    }
  ],
  "off_variation": "plain",
  "fallthrough": {
    "variation": "plain"
  },
  "prerequisites": [],
  "targets": [],
  "rules": [],
  "value_schema": null,
  "tags": [],
  "owner_principal_id": null,
  "purpose": "release",
  "expires_at": null,
  "archived": false,
  "revision": "21",
  "created_at": "2026-10-05T00:00:42Z",
  "updated_at": "2026-10-05T00:08:24Z"
}

401

404

412

422

428

429

Lifecycle

GET/feature_flags/environments/{environment_id}/flags/{flag_id}/statistics

Get a flag's evaluation statistics

Returns hourly evaluation counts by variation and reason, the last evaluation, and whether counts cover every SDK. Motor keeps counts for 90 days. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
flag_idpath
afterqueryOnly items at or after this RFC 3339 time.
beforequeryOnly items before this RFC 3339 time.
Responses

200Success.

{
  "flag_key": "checkout",
  "coverage": "full",
  "usage_status": "used",
  "last_evaluated_at": "2026-10-05T00:01:30Z",
  "total": 44,
  "error_rate": 0,
  "buckets": [
    {
      "hour": "2026-10-05T00:00:00Z",
      "counts": [
        {
          "variation": "on",
          "reason": "TARGETING_MATCH",
          "count": 42
        },
        {
          "variation": "off",
          "reason": "DEFAULT",
          "count": 2
        }
      ]
    }
  ]
}

401

404

422

429

GET/feature_flags/environments/{environment_id}/flags/{flag_id}/code_references

List a flag's code references

Lists code references from the latest scan of each repository and branch. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
flag_idpath
Responses

200Success.

{
  "data": [
    {
      "repository": "acme/web",
      "branch": "main",
      "commit": "abcdef1",
      "path": "src/checkout.ts",
      "line": 12,
      "url": "https://github.com/acme/web/blob/abcdef1/src/checkout.ts#L12",
      "scanned_at": "2026-10-04T00:00:00Z"
    }
  ],
  "next_cursor": null
}

401

404

429

POST/feature_flags/environments/{environment_id}/evaluation_counts

Report evaluation counts

Reports aggregate local evaluation counts for an interval of up to one hour. Reports are not billed. Resending the same batch ID and counts does not add to the totals. Credentials: a secret key, a server SDK key.

ParameterLocationDescription
environment_idpath
Request body
{
  "batch_id": "b1",
  "interval_start": "2026-10-05T00:00:00Z",
  "interval_end": "2026-10-05T00:01:00Z",
  "counts": [
    {
      "flag_key": "checkout",
      "variation": "on",
      "reason": "TARGETING_MATCH",
      "count": 40
    }
  ]
}
FieldTypeDescription
batch_idrequiredstring
interval_startrequired
interval_endrequired
countsrequiredarray
Responses

200Success.

{
  "batch_id": "b1",
  "accepted": true,
  "duplicate": false
}

401

409

422

429

GET/feature_flags/environments/{environment_id}/dependency_graph

Get the dependency graph

Returns the prerequisites, segments, audiences, experiments, and release plans that flags use. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Responses

200Success.

{
  "revision": "10",
  "nodes": [
    {
      "type": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner"
    },
    {
      "type": "flag",
      "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
      "key": "checkout"
    },
    {
      "type": "segment",
      "id": "ffs_VNaTX9Ts3sbY1UXdfYmL8g",
      "key": "paid"
    }
  ],
  "edges": [
    {
      "from": "flag:checkout",
      "to": "segment:paid",
      "kind": "segment"
    }
  ]
}

401

429

POST/feature_flags/environments/{environment_id}/evaluation_preview

Preview an evaluation

Evaluates flags and returns a trace explaining each decision. Previews are not billed and do not create assignments or exposures. Omit the idempotency key. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "context": {
    "targeting_key": "user_123",
    "attributes": {
      "plan": "pro"
    }
  },
  "flags": [
    {
      "key": "checkout",
      "type": "boolean",
      "default": false
    }
  ]
}
FieldTypeDescription
revision
context
flagsrequiredarray
traceboolean
Responses

200Success.

{
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "results": [
    {
      "key": "checkout",
      "value": true,
      "variation": "on",
      "reason": "TARGETING_MATCH",
      "rule_id": "paid",
      "prerequisite_key": null,
      "error_code": null,
      "experiment": null
    }
  ],
  "trace": [
    {
      "step": "flag",
      "flag_key": "checkout"
    },
    {
      "step": "rule",
      "rule_id": "paid",
      "matched": true
    }
  ]
}

401

404

422

429

POST/feature_flags/environments/{environment_id}/code_references

Report code references

Replaces the code references for one repository and branch with the supplied scan results. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "repository": "acme/web",
  "branch": "main",
  "commit": "abcdef1",
  "scanned_at": "2026-10-04T00:00:00Z",
  "references": [
    {
      "flag_key": "checkout",
      "path": "src/checkout.ts",
      "line": 12,
      "url": "https://github.com/acme/web/blob/abcdef1/src/checkout.ts#L12"
    }
  ]
}
FieldTypeDescription
repositoryrequiredstring
branchrequiredstring
commitrequiredstring
scanned_atrequired
referencesrequiredarray
Responses

200Success.

{
  "repository": "acme/web",
  "branch": "main",
  "commit": "abcdef1",
  "scanned_at": "2026-10-04T00:00:00Z",
  "reference_count": 1
}

401

422

429

Segments

POST/feature_flags/environments/{environment_id}/segments

Create a segment

Creates a segment and publishes a new revision. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "key": "paid",
  "name": "Paid plans",
  "groups": [
    [
      {
        "attribute": "attributes.plan",
        "op": "in",
        "values": [
          "pro",
          "team"
        ]
      }
    ]
  ]
}
Responses

201Success.

{
  "id": "ffs_VNaTX9Ts3sbY1UXdfYmL8g",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "paid",
  "name": "Paid plans",
  "description": "",
  "groups": [
    [
      {
        "attribute": "attributes.plan",
        "op": "in",
        "values": [
          "pro",
          "team"
        ]
      }
    ]
  ],
  "revision": "3",
  "created_at": "2026-10-05T00:00:27Z",
  "updated_at": "2026-10-05T00:00:27Z"
}

401

404

409

412

422

428

429

GET/feature_flags/environments/{environment_id}/segments

List segments

Lists the environment's segments in a stable order. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
keyqueryFilter by an exact resource key.
Responses

200Success.

{
  "data": [
    {
      "id": "ffs_VNaTX9Ts3sbY1UXdfYmL8g",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "paid",
      "name": "Paid plans",
      "description": "",
      "groups": [
        [
          {
            "attribute": "attributes.plan",
            "op": "in",
            "values": [
              "pro",
              "team"
            ]
          }
        ]
      ],
      "revision": "3",
      "created_at": "2026-10-05T00:00:27Z",
      "updated_at": "2026-10-05T00:00:27Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/segments/{segment_id}

Get a segment

Returns a segment. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
segment_idpath
Responses

200Success.

{
  "id": "ffs_VNaTX9Ts3sbY1UXdfYmL8g",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "paid",
  "name": "Paid plans",
  "description": "",
  "groups": [
    [
      {
        "attribute": "attributes.plan",
        "op": "in",
        "values": [
          "pro",
          "team"
        ]
      }
    ]
  ],
  "revision": "3",
  "created_at": "2026-10-05T00:00:27Z",
  "updated_at": "2026-10-05T00:00:27Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}/segments/{segment_id}

Update a segment

Changes a segment and publishes a new revision. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
segment_idpath
Request body
{
  "name": "Paid accounts"
}
Responses

200Success.

{
  "id": "ffs_VNaTX9Ts3sbY1UXdfYmL8g",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "paid",
  "name": "Paid accounts",
  "description": "",
  "groups": [
    [
      {
        "attribute": "attributes.plan",
        "op": "in",
        "values": [
          "pro",
          "team"
        ]
      }
    ]
  ],
  "revision": "4",
  "created_at": "2026-10-05T00:00:27Z",
  "updated_at": "2026-10-05T00:00:36Z"
}

401

404

409

412

422

428

429

DELETE/feature_flags/environments/{environment_id}/segments/{segment_id}

Delete a segment

Deletes a segment that no flag uses. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
segment_idpath
Responses

200Success.

{
  "id": "ffs_RveuKXV25H2KaWKDeUbayF",
  "deleted": true
}

401

404

409

412

428

429

Configuration

GET/feature_flags/environments/{environment_id}/config

Get the configuration snapshot

Returns the complete configuration for local evaluation: flags, segments, pinned audiences, experiments, and strategies. A request with the current tag in If-None-Match gets 304. Authentication and rate limits come first, so a revoked credential never gets 304. Credentials: a secret key, a server SDK key.

ParameterLocationDescription
environment_idpath
Responses

200Success.

{
  "audiences": [],
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "experiments": [],
  "flags": [
    {
      "client_visible": false,
      "enabled": true,
      "fallthrough": {
        "variation": "plain"
      },
      "key": "banner",
      "off_variation": "plain",
      "prerequisites": [],
      "rules": [],
      "targets": [],
      "type": "string",
      "value_schema": null,
      "variations": [
        {
          "key": "plain",
          "value": "Welcome"
        },
        {
          "key": "sale",
          "value": "Sale today"
        }
      ]
    },
    {
      "client_visible": true,
      "enabled": true,
      "fallthrough": {
        "variation": "off"
      },
      "key": "checkout",
      "off_variation": "off",
      "prerequisites": [],
      "rules": [
        {
          "conditions": [
            {
              "op": "in_segment",
              "segment": "paid"
            }
          ],
          "id": "paid",
          "serve": {
            "variation": "on"
          }
        }
      ],
      "targets": [],
      "type": "boolean",
      "value_schema": null,
      "variations": [
        {
          "key": "off",
          "value": false
        },
        {
          "key": "on",
          "value": true
        }
      ]
    }
  ],
  "hash_algorithm": "motor_sha256_v1",
  "revision": "7",
  "schema_version": 1,
  "segments": [
    {
      "groups": [
        [
          {
            "attribute": "attributes.plan",
            "op": "in",
            "values": [
              "pro",
              "team"
            ]
          }
        ]
      ],
      "key": "paid"
    }
  ],
  "strategies": []
}

401

304

404

429

GET/feature_flags/environments/{environment_id}/revisions

List revisions

Lists retained revisions, newest first. Motor retains the current revision and up to 99 previous revisions from the last 90 days. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "revision": "7",
      "created_at": "2026-10-05T00:00:51Z",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "action": "feature_flags.flag.updated",
      "comment": null,
      "restored_from": null
    },
    {
      "revision": "6",
      "created_at": "2026-10-05T00:00:42Z",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "action": "feature_flags.flag.created",
      "comment": null,
      "restored_from": null
    },
    {
      "revision": "5",
      "created_at": "2026-10-05T00:00:39Z",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "action": "feature_flags.flag.created",
      "comment": null,
      "restored_from": null
    },
    {
      "revision": "4",
      "created_at": "2026-10-05T00:00:36Z",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "action": "feature_flags.segment.updated",
      "comment": null,
      "restored_from": null
    },
    {
      "revision": "3",
      "created_at": "2026-10-05T00:00:27Z",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "action": "feature_flags.segment.created",
      "comment": null,
      "restored_from": null
    },
    {
      "revision": "2",
      "created_at": "2026-10-05T00:00:24Z",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "action": "feature_flags.environment.updated",
      "comment": null,
      "restored_from": null
    },
    {
      "revision": "1",
      "created_at": "2026-10-05T00:00:15Z",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "action": "feature_flags.environment.created",
      "comment": null,
      "restored_from": null
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/revisions/{revision}

Get a revision

Returns a revision's metadata and its management snapshot. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
revisionpath
Responses

200Success.

{
  "revision": "1",
  "created_at": "2026-10-05T00:00:15Z",
  "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "action": "feature_flags.environment.created",
  "comment": null,
  "restored_from": null,
  "snapshot": {
    "approval_policy": {
      "allow_author": false,
      "required": 0,
      "reviewer_principal_ids": []
    },
    "audiences": [],
    "client_access": {
      "allow_native": false,
      "allowed_origins": [],
      "publishable_key_ids": []
    },
    "environment": {
      "description": "",
      "id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "production",
      "name": "Production",
      "project_id": "ffp_9kunJd7bTWCR64Mv18pj45"
    },
    "experiments": [],
    "flags": [],
    "format": "motor.feature_flags.management",
    "revision": "1",
    "schema_version": 1,
    "segments": []
  }
}

401

404

429

POST/feature_flags/environments/{environment_id}/rollback

Roll back

Restores all flags and segments from a retained revision and publishes them as a new revision. It doesn't restore policies or credentials. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "revision": "7",
  "comment": "Undo the description"
}
FieldTypeDescription
revisionrequired
commentrequired
Responses

200Success.

{
  "id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "production",
  "name": "Production",
  "description": "Live traffic",
  "revision": "9",
  "client_access": {
    "publishable_key_ids": [],
    "allowed_origins": [],
    "allow_native": false
  },
  "approval_policy": {
    "required": 0,
    "reviewer_principal_ids": [],
    "allow_author": false
  },
  "expires_at": null,
  "status": "active",
  "flag_count": 2,
  "segment_count": 1,
  "created_at": "2026-10-05T00:00:15Z",
  "updated_at": "2026-10-05T00:01:06Z"
}

401

404

409

412

422

428

429

GET/feature_flags/audit_events

List audit events

Lists audit events accessible to the key, newest first. Motor retains up to 10,000 audit events per team from the last 90 days. Credentials: a secret key.

ParameterLocationDescription
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
environment_idqueryOnly this environment.
resource_idqueryOnly events of this resource.
actionqueryOnly events of this action, such as feature_flags.flag.updated.
afterqueryOnly items at or after this RFC 3339 time.
beforequeryOnly items before this RFC 3339 time.
Responses

200Success.

{
  "data": [
    {
      "id": "ffa_0_11",
      "sequence": "11",
      "at": "2026-10-05T00:01:06Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "environment",
      "resource_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "resource_key": "production",
      "action": "feature_flags.environment.rolled_back",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "8",
      "revision_after": "9",
      "comment": "Undo the description",
      "changed_fields": [
        "flags"
      ],
      "before_digest": "ff43e147d64a87069d2164f61f614ab179c40d3f1e1587fd8bffadb09e51a502",
      "after_digest": "63700af2c114a8f6a92285299408f0548e4355208536ad3c2832a0c7deea3d84"
    },
    {
      "id": "ffa_0_10",
      "sequence": "10",
      "at": "2026-10-05T00:01:03Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "flag",
      "resource_id": "ffl_VrfGhkyrB2pjGqESka3ALF",
      "resource_key": "checkout",
      "action": "feature_flags.flag.updated",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "7",
      "revision_after": "8",
      "comment": null,
      "changed_fields": [
        "description"
      ],
      "before_digest": "c10534a1e1c5c5c5250dba52a2fad84b2cf120b4ef0611aa58e70939d0803ecf",
      "after_digest": "31588d37159b234cbded0bee17bc9e24687bde8b7338a0582c889b5c62a85ed5"
    },
    {
      "id": "ffa_0_9",
      "sequence": "9",
      "at": "2026-10-05T00:00:51Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "flag",
      "resource_id": "ffl_VrfGhkyrB2pjGqESka3ALF",
      "resource_key": "checkout",
      "action": "feature_flags.flag.updated",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "6",
      "revision_after": "7",
      "comment": null,
      "changed_fields": [
        "description"
      ],
      "before_digest": "a33ebc0aeb309ccb3d455b266f61b75357ec6df48802e0d20f37b5f02682c9e4",
      "after_digest": "c10534a1e1c5c5c5250dba52a2fad84b2cf120b4ef0611aa58e70939d0803ecf"
    },
    {
      "id": "ffa_0_8",
      "sequence": "8",
      "at": "2026-10-05T00:00:42Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "flag",
      "resource_id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "resource_key": "banner",
      "action": "feature_flags.flag.created",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "5",
      "revision_after": "6",
      "comment": null,
      "changed_fields": [
        "archived",
        "client_visible",
        "created_at",
        "description",
        "enabled",
        "expires_at",
        "fallthrough",
        "id",
        "key",
        "name",
        "off_variation",
        "owner_principal_id",
        "prerequisites",
        "purpose",
        "rules",
        "tags",
        "targets",
        "type",
        "value_schema",
        "variations"
      ],
      "before_digest": null,
      "after_digest": "af63e352aff6bca9a785ae26388ec7bbf5166ad2e1904670cd7c666bbd499477"
    },
    {
      "id": "ffa_0_7",
      "sequence": "7",
      "at": "2026-10-05T00:00:39Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "flag",
      "resource_id": "ffl_VrfGhkyrB2pjGqESka3ALF",
      "resource_key": "checkout",
      "action": "feature_flags.flag.created",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "4",
      "revision_after": "5",
      "comment": null,
      "changed_fields": [
        "archived",
        "client_visible",
        "created_at",
        "description",
        "enabled",
        "expires_at",
        "fallthrough",
        "id",
        "key",
        "name",
        "off_variation",
        "owner_principal_id",
        "prerequisites",
        "purpose",
        "rules",
        "tags",
        "targets",
        "type",
        "value_schema",
        "variations"
      ],
      "before_digest": null,
      "after_digest": "a33ebc0aeb309ccb3d455b266f61b75357ec6df48802e0d20f37b5f02682c9e4"
    },
    {
      "id": "ffa_0_6",
      "sequence": "6",
      "at": "2026-10-05T00:00:36Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "segment",
      "resource_id": "ffs_VNaTX9Ts3sbY1UXdfYmL8g",
      "resource_key": "paid",
      "action": "feature_flags.segment.updated",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "3",
      "revision_after": "4",
      "comment": null,
      "changed_fields": [
        "name"
      ],
      "before_digest": "3f9e06e491819cdcb1994c1441ba386066b687987b606cf0479f905bfd120dcf",
      "after_digest": "4a4b2bd015c7c8de4016b4eecf92ab86d007a548837f7671a0a7a9e23598fa7d"
    },
    {
      "id": "ffa_0_5",
      "sequence": "5",
      "at": "2026-10-05T00:00:27Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "segment",
      "resource_id": "ffs_VNaTX9Ts3sbY1UXdfYmL8g",
      "resource_key": "paid",
      "action": "feature_flags.segment.created",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "2",
      "revision_after": "3",
      "comment": null,
      "changed_fields": [
        "created_at",
        "description",
        "groups",
        "id",
        "key",
        "name"
      ],
      "before_digest": null,
      "after_digest": "3f9e06e491819cdcb1994c1441ba386066b687987b606cf0479f905bfd120dcf"
    },
    {
      "id": "ffa_0_4",
      "sequence": "4",
      "at": "2026-10-05T00:00:24Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "environment",
      "resource_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "resource_key": "production",
      "action": "feature_flags.environment.updated",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": "1",
      "revision_after": "2",
      "comment": null,
      "changed_fields": [
        "description"
      ],
      "before_digest": "9b7383a7ad0c93c22a5be55e20a068d9e9262f51f277042107afece86e33aa52",
      "after_digest": "1cd45c0fcd98c2a04681905f554cd54960e90f756c2e2903bf42055a62d0d3fe"
    },
    {
      "id": "ffa_0_3",
      "sequence": "3",
      "at": "2026-10-05T00:00:15Z",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "environment_key": "production",
      "resource_type": "environment",
      "resource_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "resource_key": "production",
      "action": "feature_flags.environment.created",
      "actor_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "actor_name": "Agent",
      "principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "revision_before": null,
      "revision_after": "1",
      "comment": null,
      "changed_fields": [
        "key",
        "name"
      ],
      "before_digest": null,
      "after_digest": "e4c08c5a73f5be63488a322b2d202bd37d2ec411ea634797ff83fbf32ca9e908"
    }
  ],
  "next_cursor": null
}

401

429

Credentials

POST/feature_flags/environments/{environment_id}/sdk_keys

Create a server SDK key

Creates a key that reads one environment's configuration and evaluates its flags. The response shows the secret once; an idempotent retry recovers the same secret. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "name": "Web servers"
}
FieldTypeDescription
namerequired
Responses

201Success.

{
  "id": "ffk_6b4EGwzwbss1Gf5WBQaXGa",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "name": "Web servers",
  "owner_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "created_at": "2026-10-05T00:01:12Z",
  "revoked_at": null,
  "secret": "motor_ffsk_EXAMPLE_NOT_A_REAL_SECRET"
}

401

404

412

422

428

429

GET/feature_flags/environments/{environment_id}/sdk_keys

List server SDK keys

Lists an environment's SDK keys, without secrets. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "ffk_6b4EGwzwbss1Gf5WBQaXGa",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "name": "Web servers",
      "owner_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "created_at": "2026-10-05T00:01:12Z",
      "revoked_at": null
    }
  ],
  "next_cursor": null
}

401

429

DELETE/feature_flags/environments/{environment_id}/sdk_keys/{sdk_key_id}

Revoke a server SDK key

Immediately revokes the key and closes its event streams. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
sdk_key_idpath
Responses

200Success.

{
  "id": "ffk_6b4EGwzwbss1Gf5WBQaXGa",
  "deleted": true
}

401

404

412

428

429

GET/feature_flags/limits

Get limits

Returns the resource limits currently applied to the team, project, or environment. Contact Motor support to request an increase. Credentials: a secret key.

ParameterLocationDescription
project_idqueryFilter by project ID.
environment_idqueryOnly this environment.
Responses

200Success.

{
  "configuration_version": "0",
  "data": [
    {
      "key": "max_flags",
      "description": "Flags of one environment.",
      "scope": "flag_environment",
      "scope_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "unit": "flags",
      "default": 5000,
      "effective": 5000
    },
    {
      "key": "max_segments",
      "description": "Segments of one environment.",
      "scope": "flag_environment",
      "scope_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "unit": "segments",
      "default": 1000,
      "effective": 1000
    },
    {
      "key": "max_running_experiments",
      "description": "Running experiments of one environment.",
      "scope": "flag_environment",
      "scope_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "unit": "experiments",
      "default": 100,
      "effective": 100
    }
  ]
}

401

429

GET/feature_flags/access_policy

Get the access policy

Returns the roles assigned to users and service accounts in the team. Credentials: a secret key.

ParameterLocationDescription
Responses

200Success.

{
  "version": "1",
  "grants": [],
  "default_role": "editor",
  "updated_at": "1970-01-01T00:00:00Z"
}

401

429

PATCH/feature_flags/access_policy

Update the access policy

Replaces the team's role assignments. Requires a team admin's secret key. Credentials: a secret key.

ParameterLocationDescription
Request body
{
  "grants": [
    {
      "principal_id": "user_CbJvbgw5XNiJcPMi9mEavM",
      "project_ids": [],
      "environment_ids": [],
      "roles": [
        "reviewer",
        "editor"
      ]
    }
  ],
  "default_role": "none"
}
FieldTypeDescription
grantsarray
default_rolestring
Responses

200Success.

{
  "version": "2",
  "grants": [
    {
      "principal_id": "user_CbJvbgw5XNiJcPMi9mEavM",
      "project_ids": [],
      "environment_ids": [],
      "roles": [
        "reviewer",
        "editor"
      ]
    }
  ],
  "default_role": "none",
  "updated_at": "2026-10-05T00:01:24Z"
}

401

403

412

422

428

429

Evaluation

POST/feature_flags/evaluations

Evaluate flags

Evaluates 1 to 100 flags for one context. Each accepted request is billed as one remote evaluation ($0.03 per 1,000 requests), regardless of the number of flags or their results. Don't retry automatically: a retry is another billable request. Credentials: a secret key, a server SDK key, a publishable key, a client token.

ParameterLocationDescription
Request body
{
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "context": {
    "targeting_key": "user_123",
    "attributes": {
      "plan": "pro"
    }
  },
  "flags": [
    {
      "key": "checkout",
      "type": "boolean",
      "default": false
    },
    {
      "key": "banner",
      "type": "string",
      "default": "Welcome"
    }
  ]
}
FieldTypeDescription
environment_idrequiredstring
context
flagsrequiredarray
strategy_resultsobjectTrusted results of custom strategies, such as {"my_strategy@1": true}. Secret and SDK keys only.
record_exposurebooleanWhether an experiment result records an exposure. Default true; use false for prefetch.
Responses

200Success.

{
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "revision": "10",
  "results": [
    {
      "key": "checkout",
      "value": true,
      "variation": "on",
      "reason": "TARGETING_MATCH",
      "rule_id": "paid",
      "prerequisite_key": null,
      "error_code": null,
      "experiment": null
    },
    {
      "key": "banner",
      "value": "Welcome",
      "variation": "plain",
      "reason": "DEFAULT",
      "rule_id": null,
      "prerequisite_key": null,
      "error_code": null,
      "experiment": null
    }
  ]
}

401

402

403

404

413

422

429

Audiences

POST/feature_flags/environments/{environment_id}/audiences

Create an audience

Creates an imported audience, a list of up to 1,000,000 targeting keys that rules can use. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "key": "beta",
  "name": "Beta testers"
}
FieldTypeDescription
keyrequired
namerequired
description
match_bystring
local_deliverybooleanWhether server SDKs get the membership chunks. Default true.
Responses

201Success.

{
  "id": "ffauds_EsdpMBV91zRKnBddyK2dux",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "beta",
  "name": "Beta testers",
  "description": "",
  "match_by": "targeting_key",
  "local_delivery": true,
  "committed_version": null,
  "version": "1",
  "created_at": "2026-10-05T00:02:03Z",
  "updated_at": "2026-10-05T00:02:03Z"
}

401

409

422

429

GET/feature_flags/environments/{environment_id}/audiences

List audiences

Lists the environment's audiences. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "ffauds_EsdpMBV91zRKnBddyK2dux",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "beta",
      "name": "Beta testers",
      "description": "",
      "match_by": "targeting_key",
      "local_delivery": true,
      "committed_version": null,
      "version": "1",
      "created_at": "2026-10-05T00:02:03Z",
      "updated_at": "2026-10-05T00:02:03Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/audiences/{audience_id}

Get an audience

Returns an audience and its current version. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
audience_idpath
Responses

200Success.

{
  "id": "ffauds_EsdpMBV91zRKnBddyK2dux",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "beta",
  "name": "Beta testers",
  "description": "",
  "match_by": "targeting_key",
  "local_delivery": true,
  "committed_version": null,
  "version": "1",
  "created_at": "2026-10-05T00:02:03Z",
  "updated_at": "2026-10-05T00:02:03Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}/audiences/{audience_id}

Update an audience

Changes an audience's name, description, or availability for local evaluation. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
audience_idpath
Request body
{
  "name": "Beta users"
}
FieldTypeDescription
name
description
local_deliveryboolean
Responses

200Success.

{
  "id": "ffauds_EsdpMBV91zRKnBddyK2dux",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "beta",
  "name": "Beta users",
  "description": "",
  "match_by": "targeting_key",
  "local_delivery": true,
  "committed_version": null,
  "version": "2",
  "created_at": "2026-10-05T00:02:03Z",
  "updated_at": "2026-10-05T00:02:12Z"
}

401

404

412

422

428

429

DELETE/feature_flags/environments/{environment_id}/audiences/{audience_id}

Delete an audience

Deletes an audience that no flag or segment uses. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
audience_idpath
Responses

200Success.

{
  "id": "ffauds_HYghvt78rohy83YCEmzdYP",
  "deleted": true
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/audiences/{audience_id}/imports

Upload audience members

Uploads newline-delimited targeting keys (at most 64 MiB). A job checks and stages them; nothing changes until you commit the import. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
audience_idpath
Responses

202Success.

{
  "id": "ffaudi_TchiqWGh3FyaanRo5hAvXa",
  "audience_id": "ffauds_EsdpMBV91zRKnBddyK2dux",
  "status": "processing",
  "members": 0,
  "duplicates": 0,
  "digest": null,
  "chunk_count": 0,
  "errors": [],
  "version": null,
  "created_at": "2026-10-05T00:02:12Z",
  "finished_at": null
}

401

404

413

422

429

GET/feature_flags/environments/{environment_id}/audiences/{audience_id}/imports/{import_id}

Get an audience import

Returns an import's status: processing, ready, or failed. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
audience_idpath
import_idpath
Responses

200Success.

{
  "id": "ffaudi_TchiqWGh3FyaanRo5hAvXa",
  "audience_id": "ffauds_EsdpMBV91zRKnBddyK2dux",
  "status": "ready",
  "members": 2,
  "duplicates": 0,
  "digest": "0ff5263c14f3e95f4e6f53891bacb664a4f3f5d35b2efe68ee75a0df5143b950",
  "chunk_count": 1,
  "errors": [],
  "version": null,
  "created_at": "2026-10-05T00:02:12Z",
  "finished_at": "2026-10-08T16:30:47Z"
}

401

404

429

POST/feature_flags/environments/{environment_id}/audiences/{audience_id}/imports/{import_id}/commit

Commit an audience import

Makes a ready import the audience's current version, and publishes a new revision. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
audience_idpath
import_idpath
Request body
{
  "base_revision": "10"
}
FieldTypeDescription
base_revisionrequired
Responses

200Success.

{
  "id": "ffaudi_TchiqWGh3FyaanRo5hAvXa",
  "audience_id": "ffauds_EsdpMBV91zRKnBddyK2dux",
  "status": "committed",
  "members": 2,
  "duplicates": 0,
  "digest": "0ff5263c14f3e95f4e6f53891bacb664a4f3f5d35b2efe68ee75a0df5143b950",
  "chunk_count": 1,
  "errors": [],
  "version": "1",
  "created_at": "2026-10-05T00:02:12Z",
  "finished_at": "2026-10-08T16:30:47Z"
}

401

404

409

412

428

429

GET/feature_flags/environments/{environment_id}/audiences/{audience_id}/versions/{version}/chunks/{index}

Get an audience chunk

Returns one immutable chunk of 4,096 sorted SHA-256 membership hashes, for server SDKs. Credentials: a secret key, a server SDK key.

ParameterLocationDescription
environment_idpath
audience_idpath
versionpath
indexpath
Responses

200Success.

{
  "audience_id": "ffauds_EsdpMBV91zRKnBddyK2dux",
  "format": "motor.feature_flags.audience_chunk",
  "hashes": [
    "36372583505716e7f086f04d84b818c9cbd77c36b6b47aeed9403d306c76ced7",
    "402ad881fde87d9f270a1e0e1cc833fc7b295e6bf235637e211f364c14215a80"
  ],
  "index": 0
}

401

404

429

Release plans

POST/feature_flags/environments/{environment_id}/release_plans

Create a release plan

Schedules a sequence of configuration changes, either directly or from a template with a start_at time. Each step publishes a new revision. If its expected base revision has changed, the step fails with a revision conflict. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "name": "Checkout launch",
  "base_revision": "11",
  "comment": "10% then 50%",
  "steps": [
    {
      "at": "2026-10-05T01:00:00Z",
      "operations": [
        {
          "op": "update",
          "resource": "flag",
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "body": {
            "fallthrough": {
              "rollout": {
                "seed": "launch",
                "bucket_by": "targeting_key",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 10000
                  },
                  {
                    "variation": "off",
                    "weight": 90000
                  }
                ]
              }
            }
          }
        }
      ]
    },
    {
      "at": "2026-10-05T02:00:00Z",
      "operations": [
        {
          "op": "update",
          "resource": "flag",
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "body": {
            "fallthrough": {
              "rollout": {
                "seed": "launch",
                "bucket_by": "targeting_key",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 50000
                  },
                  {
                    "variation": "off",
                    "weight": 50000
                  }
                ]
              }
            }
          }
        }
      ]
    }
  ]
}
FieldTypeDescription
namerequired
base_revisionrequired
stepsarray
guardrailsarray
comment
template_idstring
start_at
Responses

201Success.

{
  "id": "ffrp_3UCS21dyKxZGTC8yd917i8",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "name": "Checkout launch",
  "base_revision": "11",
  "steps": [
    {
      "at": "2026-10-05T01:00:00Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 10000
                  },
                  {
                    "variation": "off",
                    "weight": 90000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    },
    {
      "at": "2026-10-05T02:00:00Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 50000
                  },
                  {
                    "variation": "off",
                    "weight": 50000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "comment": "10% then 50%",
  "status": "scheduled",
  "change_id": null,
  "next_step": 0,
  "applied_steps": [],
  "history": [],
  "version": "1",
  "created_at": "2026-10-05T00:02:36Z",
  "updated_at": "2026-10-05T00:02:36Z"
}

401

404

409

412

422

429

GET/feature_flags/environments/{environment_id}/release_plans

List release plans

Lists the environment's release plans in a stable order. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "ffrp_3UCS21dyKxZGTC8yd917i8",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "name": "Checkout launch",
      "base_revision": "11",
      "steps": [
        {
          "at": "2026-10-05T01:00:00Z",
          "operations": [
            {
              "body": {
                "fallthrough": {
                  "rollout": {
                    "bucket_by": "targeting_key",
                    "seed": "launch",
                    "weights": [
                      {
                        "variation": "on",
                        "weight": 10000
                      },
                      {
                        "variation": "off",
                        "weight": 90000
                      }
                    ]
                  }
                }
              },
              "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
              "op": "update",
              "resource": "flag"
            }
          ]
        },
        {
          "at": "2026-10-05T02:00:00Z",
          "operations": [
            {
              "body": {
                "fallthrough": {
                  "rollout": {
                    "bucket_by": "targeting_key",
                    "seed": "launch",
                    "weights": [
                      {
                        "variation": "on",
                        "weight": 50000
                      },
                      {
                        "variation": "off",
                        "weight": 50000
                      }
                    ]
                  }
                }
              },
              "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
              "op": "update",
              "resource": "flag"
            }
          ]
        }
      ],
      "guardrails": [],
      "comment": "10% then 50%",
      "status": "scheduled",
      "change_id": null,
      "next_step": 0,
      "applied_steps": [],
      "history": [],
      "version": "1",
      "created_at": "2026-10-05T00:02:36Z",
      "updated_at": "2026-10-05T00:02:36Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/release_plans/{plan_id}

Get a release plan

Returns a release plan, including its steps and which steps have been applied. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
plan_idpath
Responses

200Success.

{
  "id": "ffrp_3UCS21dyKxZGTC8yd917i8",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "name": "Checkout launch",
  "base_revision": "11",
  "steps": [
    {
      "at": "2026-10-05T01:00:00Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 10000
                  },
                  {
                    "variation": "off",
                    "weight": 90000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    },
    {
      "at": "2026-10-05T02:00:00Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 50000
                  },
                  {
                    "variation": "off",
                    "weight": 50000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "comment": "10% then 50%",
  "status": "scheduled",
  "change_id": null,
  "next_step": 0,
  "applied_steps": [],
  "history": [],
  "version": "1",
  "created_at": "2026-10-05T00:02:36Z",
  "updated_at": "2026-10-05T00:02:36Z"
}

401

404

429

POST/feature_flags/environments/{environment_id}/release_plans/{plan_id}/pause

Pause a release plan

Pauses a running plan. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
plan_idpath
Request body
{
  "comment": "Wait for support"
}
FieldTypeDescription
comment
Responses

200Success.

{
  "id": "ffrp_3UCS21dyKxZGTC8yd917i8",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "name": "Checkout launch",
  "base_revision": "11",
  "steps": [
    {
      "at": "2026-10-05T01:00:00Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 10000
                  },
                  {
                    "variation": "off",
                    "weight": 90000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    },
    {
      "at": "2026-10-05T02:00:00Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 50000
                  },
                  {
                    "variation": "off",
                    "weight": 50000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "comment": "10% then 50%",
  "status": "paused",
  "change_id": null,
  "next_step": 0,
  "applied_steps": [],
  "history": [],
  "version": "2",
  "created_at": "2026-10-05T00:02:36Z",
  "updated_at": "2026-10-05T00:02:45Z"
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/release_plans/{plan_id}/resume

Resume a release plan

Resumes a paused plan. Overdue steps are applied in order. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
plan_idpath
Request body
{
  "comment": "Ready"
}
FieldTypeDescription
comment
Responses

200Success.

{
  "id": "ffrp_3UCS21dyKxZGTC8yd917i8",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "name": "Checkout launch",
  "base_revision": "11",
  "steps": [
    {
      "at": "2026-10-05T01:00:03Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 10000
                  },
                  {
                    "variation": "off",
                    "weight": 90000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    },
    {
      "at": "2026-10-05T02:00:03Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 50000
                  },
                  {
                    "variation": "off",
                    "weight": 50000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "comment": "10% then 50%",
  "status": "scheduled",
  "change_id": null,
  "next_step": 0,
  "applied_steps": [],
  "history": [],
  "version": "3",
  "created_at": "2026-10-05T00:02:36Z",
  "updated_at": "2026-10-05T00:02:48Z"
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/release_plans/{plan_id}/cancel

Cancel a release plan

Cancels a release plan. Changes from steps already applied remain in effect. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
plan_idpath
Request body
{
  "comment": "Not now"
}
FieldTypeDescription
comment
Responses

200Success.

{
  "id": "ffrp_3UCS21dyKxZGTC8yd917i8",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "name": "Checkout launch",
  "base_revision": "11",
  "steps": [
    {
      "at": "2026-10-05T01:00:03Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 10000
                  },
                  {
                    "variation": "off",
                    "weight": 90000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    },
    {
      "at": "2026-10-05T02:00:03Z",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "rollout": {
                "bucket_by": "targeting_key",
                "seed": "launch",
                "weights": [
                  {
                    "variation": "on",
                    "weight": 50000
                  },
                  {
                    "variation": "off",
                    "weight": 50000
                  }
                ]
              }
            }
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "comment": "10% then 50%",
  "status": "canceled",
  "change_id": null,
  "next_step": 0,
  "applied_steps": [],
  "history": [],
  "version": "4",
  "created_at": "2026-10-05T00:02:36Z",
  "updated_at": "2026-10-05T00:02:51Z"
}

401

404

409

412

428

429

POST/feature_flags/release_templates

Create a release template

Creates a reusable template of steps relative to a start time. Credentials: a secret key.

ParameterLocationDescription
Request body
{
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "gradual",
  "name": "Gradual",
  "steps": [
    {
      "after_seconds": 3600,
      "operations": [
        {
          "op": "update",
          "resource": "flag",
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "body": {
            "description": "Step one"
          }
        }
      ]
    }
  ]
}
FieldTypeDescription
project_idrequiredstring
keyrequired
namerequired
description
stepsrequiredarray
guardrailsarray
Responses

201Success.

{
  "id": "ffrt_858vymcGFLBztDgAtMihee",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "gradual",
  "name": "Gradual",
  "description": "",
  "steps": [
    {
      "after_seconds": 3600,
      "operations": [
        {
          "body": {
            "description": "Step one"
          },
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "version": "1",
  "created_at": "2026-10-05T00:02:24Z",
  "updated_at": "2026-10-05T00:02:24Z"
}

401

404

409

422

429

GET/feature_flags/release_templates

List release templates

Lists the team's templates. Credentials: a secret key.

ParameterLocationDescription
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
project_idqueryFilter by project ID.
Responses

200Success.

{
  "data": [
    {
      "id": "ffrt_858vymcGFLBztDgAtMihee",
      "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
      "key": "gradual",
      "name": "Gradual",
      "description": "",
      "steps": [
        {
          "after_seconds": 3600,
          "operations": [
            {
              "body": {
                "description": "Step one"
              },
              "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
              "op": "update",
              "resource": "flag"
            }
          ]
        }
      ],
      "guardrails": [],
      "version": "1",
      "created_at": "2026-10-05T00:02:24Z",
      "updated_at": "2026-10-05T00:02:24Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/release_templates/{template_id}

Get a release template

Returns a template. Credentials: a secret key.

ParameterLocationDescription
template_idpath
Responses

200Success.

{
  "id": "ffrt_858vymcGFLBztDgAtMihee",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "gradual",
  "name": "Gradual",
  "description": "",
  "steps": [
    {
      "after_seconds": 3600,
      "operations": [
        {
          "body": {
            "description": "Step one"
          },
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "version": "1",
  "created_at": "2026-10-05T00:02:24Z",
  "updated_at": "2026-10-05T00:02:24Z"
}

401

404

429

PATCH/feature_flags/release_templates/{template_id}

Update a release template

Changes a template. Credentials: a secret key.

ParameterLocationDescription
template_idpath
Request body
{
  "name": "Gradual rollout"
}
FieldTypeDescription
name
description
stepsarray
guardrailsarray
Responses

200Success.

{
  "id": "ffrt_858vymcGFLBztDgAtMihee",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "gradual",
  "name": "Gradual rollout",
  "description": "",
  "steps": [
    {
      "after_seconds": 3600,
      "operations": [
        {
          "body": {
            "description": "Step one"
          },
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "op": "update",
          "resource": "flag"
        }
      ]
    }
  ],
  "guardrails": [],
  "version": "2",
  "created_at": "2026-10-05T00:02:24Z",
  "updated_at": "2026-10-05T00:02:33Z"
}

401

404

412

422

428

429

DELETE/feature_flags/release_templates/{template_id}

Delete a release template

Deletes a template without deleting release plans created from it. Credentials: a secret key.

ParameterLocationDescription
template_idpath
Responses

200Success.

{
  "id": "ffrt_858vymcGFLBztDgAtMihee",
  "deleted": true
}

401

404

412

428

429

Experiments

POST/feature_flags/environments/{environment_id}/experiments

Create an experiment

Creates a draft experiment for a flag. To use it, set a flag rule or fallthrough to an experiment outcome. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "key": "checkout_test",
  "name": "Checkout test",
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400
  }
}
FieldTypeDescription
keyrequired
namerequired
description
tagsarray
flag_keyrequired
controlrequired
weightsrequiredarray
bucket_byrequired
seedrequired
metricsrequiredarray
primary_metric_idrequiredstring
enrollmentrequiredobject
attribution_secondsrequiredinteger
analysisrequiredobject
cohort_namespacestring or null
Responses

201Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "draft",
  "enrolled": 0,
  "version": "1",
  "started_at": null,
  "stopped_at": null,
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:03:06Z"
}

401

404

409

422

429

GET/feature_flags/environments/{environment_id}/experiments

List experiments

Lists experiments other than archived ones, unless include_archived=true. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
include_archivedqueryWhether the list has archived resources. Default false.
Responses

200Success.

{
  "data": [
    {
      "id": "ffx_11iuayY2VkrTYqo5A98uC9",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "checkout_test",
      "name": "Checkout test",
      "description": "",
      "tags": [],
      "flag_key": "checkout",
      "control": "off",
      "weights": [
        {
          "variation": "off",
          "weight": 50000
        },
        {
          "variation": "on",
          "weight": 50000
        }
      ],
      "bucket_by": "targeting_key",
      "seed": "checkout_test",
      "metrics": [
        "ffm_3PihqRDi3X1ka9K5SG55oJ"
      ],
      "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
      "enrollment": {
        "start_at": "2026-10-05T00:05:03Z",
        "end_at": "2026-10-12T00:00:00Z",
        "max_subjects": 10000
      },
      "attribution_seconds": 86400,
      "analysis": {
        "mode": "sequential",
        "alpha": 0.05,
        "minimum_subjects": 100,
        "minimum_duration_seconds": 86400,
        "covariate_metric_id": null,
        "method": "bounded_hoeffding",
        "target_subjects_per_arm": null
      },
      "cohort_namespace": null,
      "status": "draft",
      "enrolled": 0,
      "version": "1",
      "started_at": null,
      "stopped_at": null,
      "completed_at": null,
      "created_at": "2026-10-05T00:03:06Z",
      "updated_at": "2026-10-05T00:03:06Z"
    },
    {
      "id": "ffx_CQvMdjfHE84eRfK4L28auS",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "spare_test",
      "name": "Checkout test",
      "description": "",
      "tags": [],
      "flag_key": "checkout",
      "control": "off",
      "weights": [
        {
          "variation": "off",
          "weight": 50000
        },
        {
          "variation": "on",
          "weight": 50000
        }
      ],
      "bucket_by": "targeting_key",
      "seed": "spare_test",
      "metrics": [
        "ffm_3PihqRDi3X1ka9K5SG55oJ"
      ],
      "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
      "enrollment": {
        "start_at": "2026-10-05T00:05:03Z",
        "end_at": "2026-10-12T00:00:00Z",
        "max_subjects": 10000
      },
      "attribution_seconds": 86400,
      "analysis": {
        "mode": "sequential",
        "alpha": 0.05,
        "minimum_subjects": 100,
        "minimum_duration_seconds": 86400,
        "covariate_metric_id": null,
        "method": "bounded_hoeffding",
        "target_subjects_per_arm": null
      },
      "cohort_namespace": null,
      "status": "draft",
      "enrolled": 0,
      "version": "1",
      "started_at": null,
      "stopped_at": null,
      "completed_at": null,
      "created_at": "2026-10-05T00:03:09Z",
      "updated_at": "2026-10-05T00:03:09Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/experiments/{experiment_id}

Get an experiment

Returns an experiment. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

200Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "draft",
  "enrolled": 0,
  "version": "1",
  "started_at": null,
  "stopped_at": null,
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:03:06Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}/experiments/{experiment_id}

Update an experiment

Updates an experiment. Once it has started, only name, description, and tags can change. Create a new experiment to change its design. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Request body
{
  "description": "Does the new checkout sell more?"
}
FieldTypeDescription
name
description
tagsarray
control
weightsarray
bucket_by
seed
metricsarray
primary_metric_idstring
enrollmentobject
attribution_secondsinteger
analysisobject
cohort_namespacestring or null
Responses

200Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "Does the new checkout sell more?",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "draft",
  "enrolled": 0,
  "version": "2",
  "started_at": null,
  "stopped_at": null,
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:03:18Z"
}

401

404

409

412

422

428

429

DELETE/feature_flags/environments/{environment_id}/experiments/{experiment_id}

Delete an experiment

Deletes an experiment that isn't running or paused and that no flag serves, with its assignments, exposures, and events. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

200Success.

{
  "id": "ffx_CQvMdjfHE84eRfK4L28auS",
  "deleted": true
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/experiments/{experiment_id}/start

Start an experiment

Starts enrollment and publishes the frozen assignment definition as a new revision. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

200Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "Does the new checkout sell more?",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "running",
  "enrolled": 0,
  "version": "3",
  "started_at": "2026-10-05T00:06:39Z",
  "stopped_at": null,
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:06:39Z"
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/experiments/{experiment_id}/pause

Pause an experiment

Stops new enrollment; assigned subjects keep their variations. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

200Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "Does the new checkout sell more?",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "paused",
  "enrolled": 1,
  "version": "4",
  "started_at": "2026-10-05T00:06:39Z",
  "stopped_at": null,
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:06:54Z"
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/experiments/{experiment_id}/resume

Resume an experiment

Resumes enrollment, provided the enrollment window has not ended. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

200Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "Does the new checkout sell more?",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "running",
  "enrolled": 1,
  "version": "5",
  "started_at": "2026-10-05T00:06:39Z",
  "stopped_at": null,
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:06:57Z"
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/experiments/{experiment_id}/stop

Stop an experiment

Ends enrollment and returns flags to their fallback variations. Metric events can still be attributed to existing assignments until their attribution windows close. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Request body
{
  "comment": "Enough data"
}
FieldTypeDescription
commentrequired
Responses

200Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "Does the new checkout sell more?",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "stopped",
  "enrolled": 1,
  "version": "6",
  "started_at": "2026-10-05T00:06:39Z",
  "stopped_at": "2026-10-05T00:07:09Z",
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:07:09Z"
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/experiments/{experiment_id}/archive

Archive an experiment

Hides a stopped or completed experiment from default lists. Its results remain available. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

200Success.

{
  "id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_test",
  "name": "Checkout test",
  "description": "Does the new checkout sell more?",
  "tags": [],
  "flag_key": "checkout",
  "control": "off",
  "weights": [
    {
      "variation": "off",
      "weight": 50000
    },
    {
      "variation": "on",
      "weight": 50000
    }
  ],
  "bucket_by": "targeting_key",
  "seed": "checkout_test",
  "metrics": [
    "ffm_3PihqRDi3X1ka9K5SG55oJ"
  ],
  "primary_metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "enrollment": {
    "start_at": "2026-10-05T00:05:03Z",
    "end_at": "2026-10-12T00:00:00Z",
    "max_subjects": 10000
  },
  "attribution_seconds": 86400,
  "analysis": {
    "mode": "sequential",
    "alpha": 0.05,
    "minimum_subjects": 100,
    "minimum_duration_seconds": 86400,
    "covariate_metric_id": null,
    "method": "bounded_hoeffding",
    "target_subjects_per_arm": null
  },
  "cohort_namespace": null,
  "status": "archived",
  "enrolled": 1,
  "version": "7",
  "started_at": "2026-10-05T00:06:39Z",
  "stopped_at": "2026-10-05T00:07:09Z",
  "completed_at": null,
  "created_at": "2026-10-05T00:03:06Z",
  "updated_at": "2026-10-05T00:07:15Z"
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/experiments/{experiment_id}/conclude

Conclude an experiment

Proposes a draft change set that serves the chosen variation in place of the experiment. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Request body
{
  "variation": "on",
  "comment": "Ship the new checkout"
}
FieldTypeDescription
variationrequired
commentrequired
Responses

201Success.

{
  "id": "ffc_MghVzJxWKbtjnDF2LJNCNy",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "16",
  "operations": [
    {
      "body": {
        "fallthrough": {
          "variation": "on"
        },
        "rules": [
          {
            "conditions": [
              {
                "op": "in_segment",
                "segment": "paid"
              }
            ],
            "id": "paid",
            "serve": {
              "variation": "on"
            }
          }
        ]
      },
      "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
      "key": "checkout",
      "changed_fields": [
        "fallthrough"
      ]
    }
  ],
  "comment": "Conclude checkout_test with on (no results yet): Ship the new checkout",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "experiment",
  "status": "draft",
  "version": "1",
  "applied_revision": null,
  "applied_at": null,
  "reviews": [],
  "created_at": "2026-10-05T00:07:12Z",
  "updated_at": "2026-10-05T00:07:12Z",
  "expires_at": "2026-11-04T00:07:12Z"
}

401

404

409

422

429

GET/feature_flags/environments/{environment_id}/experiments/{experiment_id}/results

Get experiment results

Returns the latest analysis: arms, metrics, always-valid intervals, and a recommendation once data is sufficient. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

200Success.

{
  "experiment_id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "revision": "0",
  "status": "insufficient_data",
  "method": "bounded_hoeffding_v1",
  "mode": "sequential",
  "alpha": 0.05,
  "data_through": "2026-10-05T00:06:51Z",
  "arms": [
    {
      "variation": "off",
      "control": true,
      "enrolled": 0,
      "exposed": 0,
      "mature": 0,
      "allocation_mismatch": false
    },
    {
      "variation": "on",
      "control": false,
      "enrolled": 1,
      "exposed": 1,
      "mature": 0,
      "allocation_mismatch": false
    }
  ],
  "comparisons": [
    {
      "metric_id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
      "variation": "on",
      "treatment_mean": 0,
      "control_mean": 0,
      "difference": {
        "low": -1,
        "high": 1
      },
      "relative_lift": null,
      "relative_lift_reason": "control_near_zero",
      "verdict": "inconclusive",
      "diagnostic_only": null
    }
  ],
  "permutation": null,
  "diagnostics": {
    "unattributed_events": 0,
    "missing_exposure_rate": 0
  },
  "reasons": [
    "minimum_subjects",
    "minimum_duration"
  ]
}

401

404

429

GET/feature_flags/environments/{environment_id}/experiments/{experiment_id}/assignments

List assignments

Lists assignments in enrollment order. Responses contain identity hashes, not the original identities. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "ffas_72e85a35955a5f8efcf8503e",
      "identity_hash": "0805df29c7f69b794d22f28e767d0cedb162877d56eeb2e972006206c480abc2",
      "variation": "on",
      "sequence": "1",
      "config_revision": "13",
      "created_at": "2026-10-05T00:06:42Z"
    }
  ],
  "next_cursor": null
}

401

404

429

POST/feature_flags/environments/{environment_id}/experiments/{experiment_id}/assignment_imports

Import assignments

Imports up to 1,000,000 newline-delimited {"identity", "variation", "first_exposure_at"} lines into a draft experiment, so that subjects keep their variations from another vendor. Motor hashes identities at once. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
experiment_idpath
Responses

201Success.

{
  "experiment_id": "ffx_CQvMdjfHE84eRfK4L28auS",
  "imported": 2,
  "data_quality": "unknown"
}

401

404

409

413

422

429

POST/feature_flags/environments/{environment_id}/assignments

Get an assignment

Evaluates experiment enrollment for a context. Local evaluators call this when they have no cached assignment for the experiment and subject. Each call is billed as one remote evaluation. Credentials: a secret key, a server SDK key, a client token.

ParameterLocationDescription
environment_idpath
Request body
{
  "experiment_id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "context": {
    "targeting_key": "user_9"
  }
}
FieldTypeDescription
experiment_idrequiredstring
context
Responses

200Success.

{
  "eligible": true,
  "experiment_id": "ffx_11iuayY2VkrTYqo5A98uC9",
  "variation": "on",
  "value": true,
  "assignment_receipt": "motor_fa_EXAMPLE_NOT_A_REAL_SECRET"
}

401

402

403

404

422

429

DELETE/feature_flags/environments/{environment_id}/assignments/{assignment_id}

Erase an assignment

Erases a subject's assignment, receipts, and events in response to a privacy request. Do not use this endpoint to change a subject's assigned variation. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
assignment_idpath
Responses

200Success.

{
  "id": "ffas_72e85a35955a5f8efcf8503e",
  "deleted": true
}

401

404

422

429

POST/feature_flags/environments/{environment_id}/identity_links

Link identities

Links an anonymous targeting key to an identified one after your server verifies the login. The identified subject inherits the anonymous subject's assignments. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "anonymous_targeting_key": "anon:4b4f8e9c-1f8e-4f5a-9d0e-2b7a6c1d3e4f",
  "identified_targeting_key": "user_9"
}
FieldTypeDescription
anonymous_targeting_keyrequiredstring
identified_targeting_keyrequiredstring
Responses

201Success.

{
  "id": "ffil_LjVCKWgGdBk2dh242Yrsy8",
  "anonymous_hash": "54164490bfb4a7debfc8e66eb23fa1153312db769970de6def5108bd2279dc41",
  "identified_hash": "0805df29c7f69b794d22f28e767d0cedb162877d56eeb2e972006206c480abc2",
  "created_at": "2026-10-05T00:07:00Z"
}

401

409

422

429

DELETE/feature_flags/environments/{environment_id}/identity_links/{link_id}

Erase an identity link

Erases a link and the assignments that it copied, for privacy. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
link_idpath
Responses

200Success.

{
  "id": "ffil_LjVCKWgGdBk2dh242Yrsy8",
  "deleted": true
}

401

404

429

POST/feature_flags/environments/{environment_id}/layers

Create a layer

Creates a layer of mutually exclusive experiments. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "key": "checkout_layer",
  "name": "Checkout",
  "bucket_by": "targeting_key",
  "seed": "checkout_layer",
  "ranges": [
    {
      "experiment_id": "ffx_CQvMdjfHE84eRfK4L28auS",
      "start": 0,
      "end": 50000
    }
  ]
}
FieldTypeDescription
keyrequired
namerequired
bucket_byrequired
seedrequired
rangesarrayDisjoint half-open ranges of 100,000 buckets.
Responses

201Success.

{
  "id": "ffly_7uenUpNwxcG1gwwkUv6B3B",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_layer",
  "name": "Checkout",
  "bucket_by": "targeting_key",
  "seed": "checkout_layer",
  "ranges": [
    {
      "experiment_id": "ffx_CQvMdjfHE84eRfK4L28auS",
      "start": 0,
      "end": 50000
    }
  ],
  "version": "1",
  "created_at": "2026-10-05T00:03:21Z",
  "updated_at": "2026-10-05T00:03:21Z"
}

401

409

422

429

GET/feature_flags/environments/{environment_id}/layers

List layers

Lists the environment's layers. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "ffly_7uenUpNwxcG1gwwkUv6B3B",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "checkout_layer",
      "name": "Checkout",
      "bucket_by": "targeting_key",
      "seed": "checkout_layer",
      "ranges": [
        {
          "experiment_id": "ffx_CQvMdjfHE84eRfK4L28auS",
          "start": 0,
          "end": 50000
        }
      ],
      "version": "1",
      "created_at": "2026-10-05T00:03:21Z",
      "updated_at": "2026-10-05T00:03:21Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/layers/{layer_id}

Get a layer

Returns a layer. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
layer_idpath
Responses

200Success.

{
  "id": "ffly_7uenUpNwxcG1gwwkUv6B3B",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_layer",
  "name": "Checkout",
  "bucket_by": "targeting_key",
  "seed": "checkout_layer",
  "ranges": [
    {
      "experiment_id": "ffx_CQvMdjfHE84eRfK4L28auS",
      "start": 0,
      "end": 50000
    }
  ],
  "version": "1",
  "created_at": "2026-10-05T00:03:21Z",
  "updated_at": "2026-10-05T00:03:21Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}/layers/{layer_id}

Update a layer

Updates a layer's name. Its bucket ranges can also be changed if none of its experiments are running. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
layer_idpath
Request body
{
  "name": "Checkout experiments"
}
FieldTypeDescription
name
rangesarrayDisjoint half-open ranges of 100,000 buckets.
Responses

200Success.

{
  "id": "ffly_7uenUpNwxcG1gwwkUv6B3B",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "checkout_layer",
  "name": "Checkout experiments",
  "bucket_by": "targeting_key",
  "seed": "checkout_layer",
  "ranges": [
    {
      "experiment_id": "ffx_CQvMdjfHE84eRfK4L28auS",
      "start": 0,
      "end": 50000
    }
  ],
  "version": "2",
  "created_at": "2026-10-05T00:03:21Z",
  "updated_at": "2026-10-05T00:03:30Z"
}

401

404

409

412

422

428

429

DELETE/feature_flags/environments/{environment_id}/layers/{layer_id}

Delete a layer

Deletes a layer, provided none of its experiments are running. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
layer_idpath
Responses

200Success.

{
  "id": "ffly_7uenUpNwxcG1gwwkUv6B3B",
  "deleted": true
}

401

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/metrics

Create a metric

Creates a metric that experiments measure. Numeric metrics require lower and upper bounds; values outside those bounds are clamped to the nearest bound. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "key": "purchase",
  "name": "Purchase",
  "kind": "binary",
  "aggregation": "any",
  "direction": "increase"
}
FieldTypeDescription
keyrequired
namerequired
description
kindrequiredstring
aggregationrequiredstring
lower_boundnumber or null
upper_boundnumber or null
directionrequiredstring
numerator_metric_idstring or null
denominator_metric_idstring or null
Responses

201Success.

{
  "id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "purchase",
  "name": "Purchase",
  "description": "",
  "kind": "binary",
  "aggregation": "any",
  "lower_bound": 0,
  "upper_bound": 1,
  "direction": "increase",
  "numerator_metric_id": null,
  "denominator_metric_id": null,
  "version": "1",
  "created_at": "2026-10-05T00:02:54Z",
  "updated_at": "2026-10-05T00:02:54Z"
}

401

409

422

429

GET/feature_flags/environments/{environment_id}/metrics

List metrics

Lists the environment's metrics. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "key": "purchase",
      "name": "Purchase",
      "description": "",
      "kind": "binary",
      "aggregation": "any",
      "lower_bound": 0,
      "upper_bound": 1,
      "direction": "increase",
      "numerator_metric_id": null,
      "denominator_metric_id": null,
      "version": "1",
      "created_at": "2026-10-05T00:02:54Z",
      "updated_at": "2026-10-05T00:02:54Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/metrics/{metric_id}

Get a metric

Returns a metric. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
metric_idpath
Responses

200Success.

{
  "id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "purchase",
  "name": "Purchase",
  "description": "",
  "kind": "binary",
  "aggregation": "any",
  "lower_bound": 0,
  "upper_bound": 1,
  "direction": "increase",
  "numerator_metric_id": null,
  "denominator_metric_id": null,
  "version": "1",
  "created_at": "2026-10-05T00:02:54Z",
  "updated_at": "2026-10-05T00:02:54Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}/metrics/{metric_id}

Update a metric

Changes a metric. While a running experiment uses it, only name and description can change. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
metric_idpath
Request body
{
  "description": "A completed order"
}
FieldTypeDescription
name
description
kindstring
aggregationstring
lower_boundnumber or null
upper_boundnumber or null
directionstring
numerator_metric_idstring or null
denominator_metric_idstring or null
Responses

200Success.

{
  "id": "ffm_3PihqRDi3X1ka9K5SG55oJ",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "key": "purchase",
  "name": "Purchase",
  "description": "A completed order",
  "kind": "binary",
  "aggregation": "any",
  "lower_bound": 0,
  "upper_bound": 1,
  "direction": "increase",
  "numerator_metric_id": null,
  "denominator_metric_id": null,
  "version": "2",
  "created_at": "2026-10-05T00:02:54Z",
  "updated_at": "2026-10-05T00:03:03Z"
}

401

404

409

412

422

428

429

DELETE/feature_flags/environments/{environment_id}/metrics/{metric_id}

Delete a metric

Deletes a metric, provided no retained experiment or ratio metric depends on it. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
metric_idpath
Responses

200Success.

{
  "id": "ffm_16TXaAvisQ5UfB1bUL542Y",
  "deleted": true
}

401

404

409

412

428

429

POST/feature_flags/events

Record events

Records up to 1,000 exposure and metric events. Exposures aren't billed; each accepted metric event is billed at $0.03 per 1,000, from the first event. Retrying with the same idempotency key returns the original response. Events sent with a new idempotency key but previously accepted event IDs are treated as duplicates. Credentials: a secret key, a server SDK key, a publishable key, a client token.

ParameterLocationDescription
Request body
{
  "events": [
    {
      "id": "153f8171-190c-43d0-8f7c-6c38e6e83d34",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "occurred_at": "2026-10-05T00:00:00Z",
      "type": "exposure",
      "assignment_receipt": "motor_fa_EXAMPLE_NOT_A_REAL_SECRET"
    },
    {
      "id": "c5c1089b-cd3c-4fca-9c88-99e5884e342a",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "occurred_at": "2026-10-05T00:00:00Z",
      "type": "metric",
      "metric_key": "purchase",
      "value": 1,
      "assignment_receipt": "motor_fa_EXAMPLE_NOT_A_REAL_SECRET"
    }
  ]
}
FieldTypeDescription
eventsrequiredarray
Responses

200Success.

{
  "accepted": 2,
  "duplicates": 0,
  "unattributed": 0
}

401

402

413

422

429

Changes

POST/feature_flags/environments/{environment_id}/clone

Clone an environment

Copies an environment's flags and segments into a new preview environment that expires. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "preview",
  "name": "Preview",
  "expires_at": "2026-10-06T00:00:00Z"
}
FieldTypeDescription
project_idrequiredstring
keyrequired
namerequired
expires_at
Responses

201Success.

{
  "id": "ffe_5SiFJ2GJ2sdn64wg73uS99",
  "project_id": "ffp_9kunJd7bTWCR64Mv18pj45",
  "key": "preview",
  "name": "Preview",
  "description": "Live traffic",
  "revision": "1",
  "client_access": {
    "publishable_key_ids": [],
    "allowed_origins": [],
    "allow_native": false
  },
  "approval_policy": {
    "required": 0,
    "reviewer_principal_ids": [],
    "allow_author": false
  },
  "expires_at": "2026-10-06T00:00:00Z",
  "status": "active",
  "flag_count": 2,
  "segment_count": 1,
  "created_at": "2026-10-05T00:07:21Z",
  "updated_at": "2026-10-05T00:07:21Z"
}

401

404

409

412

422

428

429

POST/feature_flags/environments/{environment_id}/diff

Compare environments

Compares flags of a source environment's revision with this environment. Read-only: send no idempotency key. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "source_environment_id": "ffe_5SiFJ2GJ2sdn64wg73uS99",
  "source_revision": "2",
  "flag_keys": [
    "banner"
  ]
}
FieldTypeDescription
source_environment_idrequiredstring
source_revisionrequired
flag_keysarray
include_dependenciesboolean
Responses

200Success.

{
  "base_revision": "17",
  "source_revision": "2",
  "operations": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "body": {
        "name": "Banner text",
        "description": "Preview copy",
        "enabled": true,
        "variations": [
          {
            "key": "plain",
            "value": "Welcome"
          },
          {
            "key": "sale",
            "value": "Sale today"
          }
        ],
        "off_variation": "plain",
        "fallthrough": {
          "variation": "plain"
        },
        "prerequisites": [],
        "targets": [],
        "rules": [],
        "value_schema": null,
        "tags": [],
        "owner_principal_id": null,
        "purpose": "release",
        "expires_at": null
      }
    }
  ],
  "conflicts": []
}

401

404

422

429

POST/feature_flags/environments/{environment_id}/promotions

Promote flags

Proposes a draft change set that copies flags of a source revision into this environment. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "source_environment_id": "ffe_5SiFJ2GJ2sdn64wg73uS99",
  "source_revision": "2",
  "flag_keys": [
    "banner"
  ],
  "base_revision": "17",
  "comment": "Promote the banner"
}
FieldTypeDescription
source_environment_idrequiredstring
source_revisionrequired
flag_keysarray
include_dependenciesboolean
base_revisionrequired
commentrequired
Responses

201Success.

{
  "id": "ffc_KZQQox6wwzEFhiWoit6Emk",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "17",
  "operations": [
    {
      "body": {
        "description": "Preview copy",
        "enabled": true,
        "expires_at": null,
        "fallthrough": {
          "variation": "plain"
        },
        "name": "Banner text",
        "off_variation": "plain",
        "owner_principal_id": null,
        "prerequisites": [],
        "purpose": "release",
        "rules": [],
        "tags": [],
        "targets": [],
        "value_schema": null,
        "variations": [
          {
            "key": "plain",
            "value": "Welcome"
          },
          {
            "key": "sale",
            "value": "Sale today"
          }
        ]
      },
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "description"
      ]
    }
  ],
  "comment": "Promote the banner",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "promotion",
  "status": "draft",
  "version": "1",
  "applied_revision": null,
  "applied_at": null,
  "reviews": [],
  "created_at": "2026-10-05T00:07:30Z",
  "updated_at": "2026-10-05T00:07:30Z",
  "expires_at": "2026-11-04T00:07:30Z"
}

401

404

409

412

422

429

POST/feature_flags/environments/{environment_id}/changes

Propose a change set

Creates a draft change set containing up to 1,000 operations against a base revision. Applying the change set publishes all operations together. If the base revision has changed, applying it fails with a revision conflict. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "base_revision": "18",
  "comment": "Retire the banner text",
  "operations": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "body": {
        "description": "Retiring"
      }
    }
  ]
}
FieldTypeDescription
base_revisionrequired
operationsrequiredarray
commentrequired
Responses

201Success.

{
  "id": "ffc_44jMG2arwxyjzZt3kCcA7q",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "18",
  "operations": [
    {
      "body": {
        "description": "Retiring"
      },
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "description"
      ]
    }
  ],
  "comment": "Retire the banner text",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "api",
  "status": "draft",
  "version": "1",
  "applied_revision": null,
  "applied_at": null,
  "reviews": [],
  "created_at": "2026-10-05T00:07:36Z",
  "updated_at": "2026-10-05T00:07:36Z",
  "expires_at": "2026-11-04T00:07:36Z"
}

401

409

412

422

429

GET/feature_flags/environments/{environment_id}/changes

List change sets

Lists change sets in a stable order, with an optional exact status. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
statusqueryOnly resources with this status.
Responses

200Success.

{
  "data": [
    {
      "id": "ffc_44jMG2arwxyjzZt3kCcA7q",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "base_revision": "18",
      "operations": [
        {
          "body": {
            "description": "Retiring"
          },
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "op": "update",
          "resource": "flag"
        }
      ],
      "diff": [
        {
          "op": "update",
          "resource": "flag",
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "key": "banner",
          "changed_fields": [
            "description"
          ]
        }
      ],
      "comment": "Retire the banner text",
      "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "source": "api",
      "status": "draft",
      "version": "1",
      "applied_revision": null,
      "applied_at": null,
      "reviews": [],
      "created_at": "2026-10-05T00:07:36Z",
      "updated_at": "2026-10-05T00:07:36Z",
      "expires_at": "2026-11-04T00:07:36Z"
    },
    {
      "id": "ffc_KZQQox6wwzEFhiWoit6Emk",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "base_revision": "17",
      "operations": [
        {
          "body": {
            "description": "Preview copy",
            "enabled": true,
            "expires_at": null,
            "fallthrough": {
              "variation": "plain"
            },
            "name": "Banner text",
            "off_variation": "plain",
            "owner_principal_id": null,
            "prerequisites": [],
            "purpose": "release",
            "rules": [],
            "tags": [],
            "targets": [],
            "value_schema": null,
            "variations": [
              {
                "key": "plain",
                "value": "Welcome"
              },
              {
                "key": "sale",
                "value": "Sale today"
              }
            ]
          },
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "op": "update",
          "resource": "flag"
        }
      ],
      "diff": [
        {
          "op": "update",
          "resource": "flag",
          "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
          "key": "banner",
          "changed_fields": [
            "description"
          ]
        }
      ],
      "comment": "Promote the banner",
      "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "source": "promotion",
      "status": "draft",
      "version": "1",
      "applied_revision": null,
      "applied_at": null,
      "reviews": [],
      "created_at": "2026-10-05T00:07:30Z",
      "updated_at": "2026-10-05T00:07:30Z",
      "expires_at": "2026-11-04T00:07:30Z"
    },
    {
      "id": "ffc_MghVzJxWKbtjnDF2LJNCNy",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "base_revision": "16",
      "operations": [
        {
          "body": {
            "fallthrough": {
              "variation": "on"
            },
            "rules": [
              {
                "conditions": [
                  {
                    "op": "in_segment",
                    "segment": "paid"
                  }
                ],
                "id": "paid",
                "serve": {
                  "variation": "on"
                }
              }
            ]
          },
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "op": "update",
          "resource": "flag"
        }
      ],
      "diff": [
        {
          "op": "update",
          "resource": "flag",
          "id": "ffl_VrfGhkyrB2pjGqESka3ALF",
          "key": "checkout",
          "changed_fields": [
            "fallthrough"
          ]
        }
      ],
      "comment": "Conclude checkout_test with on (no results yet): Ship the new checkout",
      "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
      "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
      "source": "experiment",
      "status": "draft",
      "version": "1",
      "applied_revision": null,
      "applied_at": null,
      "reviews": [],
      "created_at": "2026-10-05T00:07:12Z",
      "updated_at": "2026-10-05T00:07:12Z",
      "expires_at": "2026-11-04T00:07:12Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/changes/{change_id}

Get a change set

Returns a change set with its diff and reviews. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
change_idpath
Responses

200Success.

{
  "id": "ffc_44jMG2arwxyjzZt3kCcA7q",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "18",
  "operations": [
    {
      "body": {
        "description": "Retiring"
      },
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "description"
      ]
    }
  ],
  "comment": "Retire the banner text",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "api",
  "status": "draft",
  "version": "1",
  "applied_revision": null,
  "applied_at": null,
  "reviews": [],
  "created_at": "2026-10-05T00:07:36Z",
  "updated_at": "2026-10-05T00:07:36Z",
  "expires_at": "2026-11-04T00:07:36Z",
  "approval_policy": {
    "required": 1,
    "reviewer_principal_ids": [
      "user_CbJvbgw5XNiJcPMi9mEavM"
    ],
    "allow_author": false
  }
}

401

404

429

POST/feature_flags/environments/{environment_id}/changes/{change_id}/preview

Preview a change set

Compares results of up to 100 contexts and flags before and after the change. Read-only: send no idempotency key. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
change_idpath
Request body
{
  "contexts": [
    {
      "targeting_key": "user_123"
    }
  ],
  "flag_keys": [
    "banner"
  ]
}
FieldTypeDescription
contextsrequiredarray
flag_keysarray
Responses

200Success.

{
  "base_revision": "18",
  "results": [
    {
      "context_index": 0,
      "flag_key": "banner",
      "before": {
        "value": "Welcome",
        "variation": "plain",
        "reason": "DEFAULT",
        "error_code": null
      },
      "after": {
        "value": "Welcome",
        "variation": "plain",
        "reason": "DEFAULT",
        "error_code": null
      },
      "changed": false
    }
  ]
}

401

404

422

429

POST/feature_flags/environments/{environment_id}/changes/{change_id}/submit

Submit a change set

Submits a draft for review. It is approved automatically if the environment does not require approvals. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
change_idpath
Responses

200Success.

{
  "id": "ffc_44jMG2arwxyjzZt3kCcA7q",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "18",
  "operations": [
    {
      "body": {
        "description": "Retiring"
      },
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "description"
      ]
    }
  ],
  "comment": "Retire the banner text",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "api",
  "status": "pending",
  "version": "2",
  "applied_revision": null,
  "applied_at": null,
  "reviews": [],
  "created_at": "2026-10-05T00:07:36Z",
  "updated_at": "2026-10-05T00:07:48Z",
  "expires_at": "2026-11-04T00:07:36Z"
}

401

403

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/changes/{change_id}/review

Review a change set

Records a reviewer's decision. The reviewer must be a user listed in the environment's approval policy. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
change_idpath
Request body
{
  "decision": "approve",
  "comment": "Looks right"
}
FieldTypeDescription
decisionrequiredstring
comment
Responses

200Success.

{
  "id": "ffc_44jMG2arwxyjzZt3kCcA7q",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "18",
  "operations": [
    {
      "body": {
        "description": "Retiring"
      },
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "description"
      ]
    }
  ],
  "comment": "Retire the banner text",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "api",
  "status": "approved",
  "version": "3",
  "applied_revision": null,
  "applied_at": null,
  "reviews": [
    {
      "principal_id": "user_CbJvbgw5XNiJcPMi9mEavM",
      "key_id": "key_3CKBrMD1KmGksgf4ej3pmN",
      "decision": "approve",
      "comment": "Looks right",
      "at": "2026-10-05T00:07:51Z"
    }
  ],
  "created_at": "2026-10-05T00:07:36Z",
  "updated_at": "2026-10-05T00:07:51Z",
  "expires_at": "2026-11-04T00:07:36Z"
}

401

403

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/changes/{change_id}/apply

Apply a change set

Applies an approved change set as one new revision, after checking the base, approvals, and configuration again. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
change_idpath
Responses

200Success.

{
  "id": "ffc_44jMG2arwxyjzZt3kCcA7q",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "18",
  "operations": [
    {
      "body": {
        "description": "Retiring"
      },
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "description"
      ]
    }
  ],
  "comment": "Retire the banner text",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "api",
  "status": "applied",
  "version": "4",
  "applied_revision": "19",
  "applied_at": "2026-10-05T00:07:54Z",
  "reviews": [
    {
      "principal_id": "user_CbJvbgw5XNiJcPMi9mEavM",
      "key_id": "key_3CKBrMD1KmGksgf4ej3pmN",
      "decision": "approve",
      "comment": "Looks right",
      "at": "2026-10-05T00:07:51Z"
    }
  ],
  "created_at": "2026-10-05T00:07:36Z",
  "updated_at": "2026-10-05T00:07:54Z",
  "expires_at": "2026-11-04T00:07:36Z"
}

401

403

404

409

412

428

429

POST/feature_flags/environments/{environment_id}/changes/{change_id}/cancel

Cancel a change set

Cancels an open change set. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
change_idpath
Request body
{
  "comment": "Not this week"
}
FieldTypeDescription
comment
Responses

200Success.

{
  "id": "ffc_5HyScKNxfnefTuAKoJ7zfq",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "base_revision": "20",
  "operations": [
    {
      "body": {
        "fallthrough": {
          "variation": "sale"
        }
      },
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "op": "update",
      "resource": "flag"
    }
  ],
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "fallthrough"
      ]
    }
  ],
  "comment": "Try a sale",
  "author_key_id": "key_DuQaWzydzQjd8J84rbPfSd",
  "author_principal_id": "user_P68xcnDgjsgeCWkZpWrhXx",
  "source": "api",
  "status": "canceled",
  "version": "2",
  "applied_revision": null,
  "applied_at": null,
  "reviews": [],
  "created_at": "2026-10-05T00:08:00Z",
  "updated_at": "2026-10-05T00:08:03Z",
  "expires_at": "2026-11-04T00:08:00Z"
}

401

403

404

409

412

428

429

Configuration as code

GET/feature_flags/environments/{environment_id}/export

Export an environment

Returns a Motor export of the current or a retained revision, without credentials or policies. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
revisionqueryA retained revision number. Default: the current revision.
Responses

200Success.

{
  "format": "motor.feature_flags",
  "format_version": 1,
  "source_environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "revision": "20",
  "flags": [
    {
      "key": "banner",
      "name": "Banner text",
      "description": "Retiring",
      "type": "string",
      "enabled": true,
      "client_visible": false,
      "variations": [
        {
          "key": "plain",
          "value": "Welcome"
        },
        {
          "key": "sale",
          "value": "Sale today"
        }
      ],
      "off_variation": "plain",
      "fallthrough": {
        "variation": "plain"
      },
      "prerequisites": [],
      "targets": [],
      "rules": [],
      "value_schema": null,
      "tags": [],
      "owner_principal_id": null,
      "purpose": "release",
      "expires_at": null,
      "archived": false
    },
    {
      "key": "checkout",
      "name": "New checkout",
      "description": "The checkout of 2026",
      "type": "boolean",
      "enabled": true,
      "client_visible": true,
      "variations": [
        {
          "key": "off",
          "value": false
        },
        {
          "key": "on",
          "value": true
        }
      ],
      "off_variation": "off",
      "fallthrough": {
        "experiment": "checkout_test",
        "fallback_variation": "off"
      },
      "prerequisites": [],
      "targets": [],
      "rules": [
        {
          "id": "paid",
          "conditions": [
            {
              "segment": "paid",
              "op": "in_segment"
            }
          ],
          "serve": {
            "variation": "on"
          }
        }
      ],
      "value_schema": null,
      "tags": [
        "web"
      ],
      "owner_principal_id": null,
      "purpose": "release",
      "expires_at": null,
      "archived": false
    }
  ],
  "segments": [
    {
      "key": "paid",
      "name": "Paid accounts",
      "description": "",
      "groups": [
        [
          {
            "attribute": "attributes.plan",
            "op": "in",
            "values": [
              "pro",
              "team"
            ]
          }
        ]
      ]
    }
  ],
  "audience_manifests": [
    {
      "id": "ffauds_EsdpMBV91zRKnBddyK2dux",
      "key": "beta",
      "version": 1,
      "local_delivery": true,
      "members": 2,
      "digest": "0ff5263c14f3e95f4e6f53891bacb664a4f3f5d35b2efe68ee75a0df5143b950",
      "chunks": [
        "99a0566fdbd9a50cd7fe12ea6281ee4657117263eb70913168441fd8cdd89e20"
      ]
    }
  ],
  "value_schemas": {}
}

401

429

POST/feature_flags/environments/{environment_id}/sync

Sync an environment

Creates or updates flags and segments by key using Motor's export format. By default, a dry run returns a diff without saving changes. With dry_run: false, sync publishes immediately or proposes a change set if the environment requires approvals. Send an idempotency key only with dry_run: false. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "base_revision": "20",
  "dry_run": true,
  "flags": [
    {
      "key": "banner",
      "tags": [
        "gitops"
      ]
    }
  ],
  "segments": []
}
FieldTypeDescription
formatstring
format_versioninteger
source_environment_idstring
revision
flagsarray
segmentsarray
audience_manifestsarray
value_schemasobject
base_revisionrequired
dry_runbooleanDefault true.
prune_tag
commentstring
Responses

200Success.

{
  "dry_run": true,
  "changed": true,
  "base_revision": "20",
  "prospective_revision": "21",
  "diff": [
    {
      "op": "update",
      "resource": "flag",
      "id": "ffl_PduaHSfBcMPJXFHC8gtUyj",
      "key": "banner",
      "changed_fields": [
        "tags"
      ]
    }
  ],
  "change_set": null
}

401

409

412

422

429

POST/feature_flags/environments/{environment_id}/imports

Import a configuration

Starts a job that translates a Motor or vendor export (LaunchDarkly, Unleash, GrowthBook, Flagsmith, or ConfigCat) into a draft change set. Rules that don't have the same meaning in Motor become issues that need a mapping. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
Request body
{
  "format": "motor",
  "base_revision": "20",
  "comment": "Copy production",
  "document": {
    "format": "motor.feature_flags",
    "format_version": 1,
    "flags": [
      {
        "key": "imported",
        "name": "Imported",
        "type": "boolean",
        "variations": [
          {
            "key": "off",
            "value": false
          },
          {
            "key": "on",
            "value": true
          }
        ],
        "off_variation": "off",
        "fallthrough": {
          "variation": "off",
          "rollout": null
        }
      }
    ],
    "segments": []
  }
}
FieldTypeDescription
formatrequiredstring
documentrequired
base_revisionrequired
import_modestring
prune_tag
source_environmentstring or null
commentrequired
Responses

202Success.

{
  "id": "ffi_8Vd59L8nFLjznXy3twGTgd",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "format": "motor",
  "source_environment": null,
  "import_mode": "merge",
  "prune_tag": null,
  "base_revision": "20",
  "comment": "Copy production",
  "status": "processing",
  "error": null,
  "flags": 0,
  "segments": 0,
  "issues": [],
  "change_set_id": null,
  "cohort_warning": "Motor puts subjects in rollout buckets with its own hash, so a subject can get another variation than the source gave it. Import experiment assignments to keep them.",
  "document_expires_at": "2026-10-12T00:08:12Z",
  "created_at": "2026-10-05T00:08:12Z",
  "updated_at": "2026-10-05T00:08:12Z"
}

401

412

413

422

429

GET/feature_flags/environments/{environment_id}/imports

List imports

Lists the environment's imports, newest first, for 90 days. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
limitqueryMaximum number of results per page: 1 to 200. Defaults to 50.
cursorqueryThe next_cursor value returned by the previous page.
Responses

200Success.

{
  "data": [
    {
      "id": "ffi_8Vd59L8nFLjznXy3twGTgd",
      "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
      "format": "motor",
      "source_environment": null,
      "import_mode": "merge",
      "prune_tag": null,
      "base_revision": "20",
      "comment": "Copy production",
      "status": "needs_mapping",
      "error": null,
      "flags": 1,
      "segments": 0,
      "issues": [
        {
          "id": "ffii_invalid_flag_imported",
          "path": "$",
          "code": "invalid_resource",
          "message": "`fallthrough.rollout` isn't a field here.",
          "resource": "flag",
          "proposed_key": "imported",
          "resolved": false
        }
      ],
      "change_set_id": null,
      "cohort_warning": "Motor puts subjects in rollout buckets with its own hash, so a subject can get another variation than the source gave it. Import experiment assignments to keep them.",
      "document_expires_at": "2026-10-12T00:08:12Z",
      "created_at": "2026-10-05T00:08:12Z",
      "updated_at": "2026-10-08T16:30:47Z"
    }
  ],
  "next_cursor": null
}

401

429

GET/feature_flags/environments/{environment_id}/imports/{import_id}

Get an import

Returns an import's status (processing, needs_mapping, ready, or failed), issues, and change set. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
import_idpath
Responses

200Success.

{
  "id": "ffi_8Vd59L8nFLjznXy3twGTgd",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "format": "motor",
  "source_environment": null,
  "import_mode": "merge",
  "prune_tag": null,
  "base_revision": "20",
  "comment": "Copy production",
  "status": "needs_mapping",
  "error": null,
  "flags": 1,
  "segments": 0,
  "issues": [
    {
      "id": "ffii_invalid_flag_imported",
      "path": "$",
      "code": "invalid_resource",
      "message": "`fallthrough.rollout` isn't a field here.",
      "resource": "flag",
      "proposed_key": "imported",
      "resolved": false
    }
  ],
  "change_set_id": null,
  "cohort_warning": "Motor puts subjects in rollout buckets with its own hash, so a subject can get another variation than the source gave it. Import experiment assignments to keep them.",
  "document_expires_at": "2026-10-12T00:08:12Z",
  "created_at": "2026-10-05T00:08:12Z",
  "updated_at": "2026-10-08T16:30:47Z"
}

401

404

429

PATCH/feature_flags/environments/{environment_id}/imports/{import_id}/mappings

Map an import issue

Resolves import issues by replacing the affected resources with Motor flags or segments. Motor then translates and validates the import again. Credentials: a secret key.

ParameterLocationDescription
environment_idpath
import_idpath
Request body
{
  "issue_id": "ffii_invalid_flag_imported",
  "action": "replace",
  "replacement": {
    "key": "imported",
    "name": "Imported",
    "type": "boolean",
    "variations": [
      {
        "key": "off",
        "value": false
      },
      {
        "key": "on",
        "value": true
      }
    ],
    "off_variation": "off",
    "fallthrough": {
      "variation": "off"
    }
  }
}
FieldTypeDescription
issue_idrequiredstring
actionrequiredstring
replacementrequiredobjectA Motor flag or segment create body.
Responses

202Success.

{
  "id": "ffi_8Vd59L8nFLjznXy3twGTgd",
  "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
  "format": "motor",
  "source_environment": null,
  "import_mode": "merge",
  "prune_tag": null,
  "base_revision": "20",
  "comment": "Copy production",
  "status": "processing",
  "error": null,
  "flags": 1,
  "segments": 0,
  "issues": [
    {
      "id": "ffii_invalid_flag_imported",
      "path": "$",
      "code": "invalid_resource",
      "message": "`fallthrough.rollout` isn't a field here.",
      "resource": "flag",
      "proposed_key": "imported",
      "resolved": false
    }
  ],
  "change_set_id": null,
  "cohort_warning": "Motor puts subjects in rollout buckets with its own hash, so a subject can get another variation than the source gave it. Import experiment assignments to keep them.",
  "document_expires_at": "2026-10-12T00:08:12Z",
  "created_at": "2026-10-05T00:08:12Z",
  "updated_at": "2026-10-05T00:08:21Z"
}

401

404

409

412

422

428

429

Streams

GET/feature_flags/environments/{environment_id}/stream

Stream configuration changes

A server-sent event stream: a configuration event with the environment's revision on connection and after each change, and heartbeat every 30 seconds. It ends after 15 minutes or when a credential changes; reconnect with Last-Event-ID. Credentials: a secret key, a server SDK key, a publishable key, a client token.

ParameterLocationDescription
environment_idpath
Responses

200A text/event-stream of invalidation events.

event: configuration
retry: 2000
data: {"environment_id":"ffe_UJAs9eZep7hvba6xBh5dvY","revision":"21","config_etag":"\"ffc:ffe_UJAs9eZep7hvba6xBh5dvY:21:1\""}

id: 1-44

401

403

404

422

429

OFREP

POST/feature_flags/environments/{environment_id}/ofrep/v1/evaluate/flags/{key}

Evaluate a flag (OFREP)

OFREP 0.4.0 single-flag evaluation. Errors use the protocol's bodies. Only 200 responses are billed as remote evaluations. Credentials: a secret key, a server SDK key, a publishable key, a client token.

ParameterLocationDescription
environment_idpath
keypath
Request body
{
  "context": {
    "targetingKey": "user_123",
    "plan": "pro"
  }
}
FieldTypeDescription
contextrequiredobject
Responses

200Success.

{
  "key": "banner",
  "value": "Welcome",
  "reason": "DISABLED",
  "variant": "plain",
  "metadata": {
    "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
    "revision": 21
  }
}

400OFREP failure, such as INVALID_CONTEXT or TARGETING_KEY_MISSING.

404OFREP FLAG_NOT_FOUND: the flag doesn't exist or the credential can't see it.

401The credential is missing or invalid. No body.

403The credential can't use this environment. No body.

429Rate limited, or the monthly spending limit (X-Motor-Error: limit_reached). Retry-After is an RFC 3339 time, the start of the next UTC month for the spending limit.

POST/feature_flags/environments/{environment_id}/ofrep/v1/evaluate/flags

Evaluate all flags (OFREP)

OFREP 0.4.0 bulk evaluation of every flag that the credential can see. A request with the response's ETag in If-None-Match gets 304 when nothing changed for this context, without a charge. Credentials: a secret key, a server SDK key, a publishable key, a client token.

ParameterLocationDescription
environment_idpath
flagConfigEtagqueryAn OFREP freshness hint from an event; Motor checks results itself.
flagConfigLastModifiedqueryAn OFREP freshness hint from an event.
Request body
{
  "context": {
    "targetingKey": "user_123"
  }
}
FieldTypeDescription
contextrequiredobject
Responses

200Success.

{
  "flags": [
    {
      "key": "banner",
      "value": "Welcome",
      "reason": "DISABLED",
      "variant": "plain",
      "metadata": {
        "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
        "revision": 21
      }
    },
    {
      "key": "checkout",
      "value": false,
      "reason": "STATIC",
      "variant": "off",
      "metadata": {
        "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
        "revision": 21
      }
    }
  ],
  "metadata": {
    "environment_id": "ffe_UJAs9eZep7hvba6xBh5dvY",
    "revision": 21
  },
  "eventStreams": [
    {
      "type": "sse",
      "endpoint": {
        "requestUri": "/feature_flags/environments/ffe_UJAs9eZep7hvba6xBh5dvY/ofrep/v1/events"
      },
      "inactivityDelaySec": 120
    }
  ]
}

304Not modified for this context.

400OFREP failure of the whole request, such as INVALID_CONTEXT.

401The credential is missing or invalid. No body.

403The credential can't use this environment. No body.

429Rate limited, or the monthly spending limit (X-Motor-Error: limit_reached). Retry-After is an RFC 3339 time, the start of the next UTC month for the spending limit.

GET/feature_flags/environments/{environment_id}/ofrep/v1/events

Stream change events (OFREP)

The OFREP event stream: message events with {"type": "refetchEvaluation"} after each change. Credentials: a secret key, a server SDK key, a publishable key, a client token.

ParameterLocationDescription
environment_idpath
Responses

200A text/event-stream of invalidation events.

retry: 2000
data: {"type":"refetchEvaluation","etag":"\"ffc:ffe_UJAs9eZep7hvba6xBh5dvY:21:1\"","lastModified":1791158904}

id: 1-44

400OFREP failure, such as INVALID_CONTEXT or TARGETING_KEY_MISSING.

401The credential is missing or invalid. No body.

403The credential can't use this environment. No body.

429Rate limited, or the monthly spending limit (X-Motor-Error: limit_reached). Retry-After is an RFC 3339 time, the start of the next UTC month for the spending limit.