Lists confidently-dead (or, with `staleness=stale`, stale-or-dead) flags the Featureflip Flag Cleanup Action should remove, cursor-paginated, each with its kill `treatment` (true = keep the on-branch, false = keep the off-branch).
const url = 'https://api.featureflip.io/api/v1/orgs/example/projects/example/flags/removal-candidates';const options = {method: 'GET', headers: {Authorization: '<Authorization>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://api.featureflip.io/api/v1/orgs/example/projects/example/flags/removal-candidates \ --header 'Authorization: <Authorization>'Only flags the staleness engine marks at or above the requested tier via a decisive StuckRolledOut/StuckRolledBack reason are returned; ZeroTraffic/CreatedUnused, cross-env-divergent, and archived flags are omitted (no confident code treatment). The ONLY public projection of staleness.
Authorizations
Section titled “ Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “ Path Parameters ”Query Parameters
Section titled “ Query Parameters ”Minimum staleness tier to include: dead (default) or stale (includes Stale + Dead).
Omitted or any unrecognized value falls back to dead — the safe default never widens
silently.
Responses
Section titled “ Responses ”OK
A page of results plus an opaque cursor for the next page, or null when this is the last
page. Wire keys are frozen: items (already lowercase under the camelCase policy) and
next_cursor (pinned explicitly — the policy alone would emit nextCursor).
object
One dead flag the Featureflip Flag Cleanup Action should remove, returned by
GET .../flags/removal-candidates. Treatment is the kill decision: true → keep the
flag’s on-branch, false → keep the off-branch. Status is the flag’s staleness tier
("Stale" or "Dead", never "Active") — lets a caller distinguish the two when
?staleness=stale widens the response to include both tiers. This is the ONLY public
projection of staleness — PublicFlagResponse and PublicFlagListItem
still omit it by design.
object
Example generated
{ "items": [ { "key": "example", "reason": "example", "treatment": true, "status": "example" } ], "next_cursor": "example"}Headers
Section titled “ Headers ”The maximum number of requests permitted per rate-limit window for this caller.
The number of requests remaining in the current rate-limit window.
The UTC time at which the current rate-limit window resets, as a Unix timestamp in seconds.
Authentication is required, or the supplied API token is invalid or expired.
The frozen public-API error contract. error codes are stable snake_case strings. Wire keys
are frozen snake_case too (error, message, docs_url, fields,
retry_after) — the global camelCase naming policy would otherwise emit
docsUrl/retryAfter, breaking the published spec. !:JsonPropertyName
always wins over the policy, so these are pinned explicitly rather than relying on the
property names already being lowercase for the single-word ones.
did_you_mean and next_actions are ADDITIVE optional keys (null → omitted via
the global DefaultIgnoreCondition = WhenWritingNull), so pre-existing error bodies
are byte-for-byte unchanged when they’re absent.
object
object
object
Example
{ "error": "not_found", "message": "Flag 'new-checkout-flw' was not found in project 'checkout'.", "docs_url": "https://featureflip.io/docs/management-api/errors/not_found", "did_you_mean": [ "new-checkout-flow" ], "next_actions": [ { "method": "GET", "path": "/api/v1/orgs/acme/projects/checkout/flags" } ]}Headers
Section titled “ Headers ”The maximum number of requests permitted per rate-limit window for this caller.
The number of requests remaining in the current rate-limit window.
The UTC time at which the current rate-limit window resets, as a Unix timestamp in seconds.
Not Found
The frozen public-API error contract. error codes are stable snake_case strings. Wire keys
are frozen snake_case too (error, message, docs_url, fields,
retry_after) — the global camelCase naming policy would otherwise emit
docsUrl/retryAfter, breaking the published spec. !:JsonPropertyName
always wins over the policy, so these are pinned explicitly rather than relying on the
property names already being lowercase for the single-word ones.
did_you_mean and next_actions are ADDITIVE optional keys (null → omitted via
the global DefaultIgnoreCondition = WhenWritingNull), so pre-existing error bodies
are byte-for-byte unchanged when they’re absent.
object
object
object
Example
{ "error": "not_found", "message": "Flag 'new-checkout-flw' was not found in project 'checkout'.", "docs_url": "https://featureflip.io/docs/management-api/errors/not_found", "did_you_mean": [ "new-checkout-flow" ], "next_actions": [ { "method": "GET", "path": "/api/v1/orgs/acme/projects/checkout/flags" } ]}Headers
Section titled “ Headers ”The maximum number of requests permitted per rate-limit window for this caller.
The number of requests remaining in the current rate-limit window.
The UTC time at which the current rate-limit window resets, as a Unix timestamp in seconds.
Rate limit exceeded. Retry after the interval indicated by the Retry-After header.
The frozen public-API error contract. error codes are stable snake_case strings. Wire keys
are frozen snake_case too (error, message, docs_url, fields,
retry_after) — the global camelCase naming policy would otherwise emit
docsUrl/retryAfter, breaking the published spec. !:JsonPropertyName
always wins over the policy, so these are pinned explicitly rather than relying on the
property names already being lowercase for the single-word ones.
did_you_mean and next_actions are ADDITIVE optional keys (null → omitted via
the global DefaultIgnoreCondition = WhenWritingNull), so pre-existing error bodies
are byte-for-byte unchanged when they’re absent.
object
object
object
Example
{ "error": "not_found", "message": "Flag 'new-checkout-flw' was not found in project 'checkout'.", "docs_url": "https://featureflip.io/docs/management-api/errors/not_found", "did_you_mean": [ "new-checkout-flow" ], "next_actions": [ { "method": "GET", "path": "/api/v1/orgs/acme/projects/checkout/flags" } ]}Headers
Section titled “ Headers ”Number of seconds to wait before retrying the request.
The maximum number of requests permitted per rate-limit window for this caller.
The number of requests remaining in the current rate-limit window.
The UTC time at which the current rate-limit window resets, as a Unix timestamp in seconds.