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
Examplegenerated
{ "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.