Declaratively replaces the resolved flag's entire targeting rule set in the resolved environment.
const url = 'https://api.featureflip.io/api/v1/orgs/example/projects/example/flags/example/environments/example/targeting';const options = { method: 'PUT', headers: {Authorization: '<Authorization>', 'Content-Type': 'application/json'}, body: '{"rules":[{"description":"North American users get the new flow at 25%.","variationId":"0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e","rolloutPercentage":25,"conditionGroups":[{"operator":"And","conditions":[{"attribute":"country","operator":"In","values":["US","CA"],"negate":false}]}]}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.featureflip.io/api/v1/orgs/example/projects/example/flags/example/environments/example/targeting \ --header 'Authorization: <Authorization>' \ --header 'Content-Type: application/json' \ --data '{ "rules": [ { "description": "North American users get the new flow at 25%.", "variationId": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e", "rolloutPercentage": 25, "conditionGroups": [ { "operator": "And", "conditions": [ { "attribute": "country", "operator": "In", "values": [ "US", "CA" ], "negate": false } ] } ] } ] }'The ordered Rules list is applied in array order (= evaluation order); an empty or omitted list clears all rules. Segment-scoped rules are supported. The replace is atomic. Requires at least Member.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Body
Section titled “Request Body”Request body for PUT .../targeting — a declarative full replace of the environment’s
ordered targeting rule set. Rules are applied in array order (index = priority, so the array
order IS the evaluation order). Rules is nullable so that an OMITTED rules
field (a body of {}) binds successfully instead of failing ASP.NET Core’s implicit
required-property check on non-nullable reference types — both an omitted rules field
and an explicit empty list ({ "rules": [] }) clear all targeting rules for the
environment. Each element is a PublicCreateTargetingRuleRequest (identical to the
POST .../rules body), so UserSegmentId is supported — segment-scoped rules can be
submitted through this endpoint. The replace is atomic (all-or-nothing): the whole rule set is
swapped in one transaction, or nothing changes.
object
Request body for POST .../rules. The Application-side
CreateTargetingRuleDto/CreateConditionGroupDto/CreateConditionDto all take
their Operator as a bare string, re-parsed CASE-SENSITIVELY inside
CreateTargetingRuleCommandHandler — FlagTargetingController’s mapping helpers
validate every operator against the enum’s member-name allowlist AND canonicalize the casing
(e.g. "in" → "In") before building the command DTO, so a valid
case-insensitive match never trips the handler’s strict re-parse.
object
Request-side condition group, symmetric with PublicConditionGroupResponse.
object
Allowed values: And, Or.
Request-side condition, symmetric with PublicConditionResponse.
object
Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.
Example
{ "description": "North American users get the new flow at 25%.", "variationId": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e", "rolloutPercentage": 25, "conditionGroups": [ { "operator": "And", "conditions": [ { "attribute": "country", "operator": "In", "values": [ "US", "CA" ], "negate": false } ] } ]}Request body for PUT .../targeting — a declarative full replace of the environment’s
ordered targeting rule set. Rules are applied in array order (index = priority, so the array
order IS the evaluation order). Rules is nullable so that an OMITTED rules
field (a body of {}) binds successfully instead of failing ASP.NET Core’s implicit
required-property check on non-nullable reference types — both an omitted rules field
and an explicit empty list ({ "rules": [] }) clear all targeting rules for the
environment. Each element is a PublicCreateTargetingRuleRequest (identical to the
POST .../rules body), so UserSegmentId is supported — segment-scoped rules can be
submitted through this endpoint. The replace is atomic (all-or-nothing): the whole rule set is
swapped in one transaction, or nothing changes.
object
Request body for POST .../rules. The Application-side
CreateTargetingRuleDto/CreateConditionGroupDto/CreateConditionDto all take
their Operator as a bare string, re-parsed CASE-SENSITIVELY inside
CreateTargetingRuleCommandHandler — FlagTargetingController’s mapping helpers
validate every operator against the enum’s member-name allowlist AND canonicalize the casing
(e.g. "in" → "In") before building the command DTO, so a valid
case-insensitive match never trips the handler’s strict re-parse.
object
Request-side condition group, symmetric with PublicConditionGroupResponse.
object
Allowed values: And, Or.
Request-side condition, symmetric with PublicConditionResponse.
object
Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.
Example
{ "description": "North American users get the new flow at 25%.", "variationId": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e", "rolloutPercentage": 25, "conditionGroups": [ { "operator": "And", "conditions": [ { "attribute": "country", "operator": "In", "values": [ "US", "CA" ], "negate": false } ] } ]}Request body for PUT .../targeting — a declarative full replace of the environment’s
ordered targeting rule set. Rules are applied in array order (index = priority, so the array
order IS the evaluation order). Rules is nullable so that an OMITTED rules
field (a body of {}) binds successfully instead of failing ASP.NET Core’s implicit
required-property check on non-nullable reference types — both an omitted rules field
and an explicit empty list ({ "rules": [] }) clear all targeting rules for the
environment. Each element is a PublicCreateTargetingRuleRequest (identical to the
POST .../rules body), so UserSegmentId is supported — segment-scoped rules can be
submitted through this endpoint. The replace is atomic (all-or-nothing): the whole rule set is
swapped in one transaction, or nothing changes.
object
Request body for POST .../rules. The Application-side
CreateTargetingRuleDto/CreateConditionGroupDto/CreateConditionDto all take
their Operator as a bare string, re-parsed CASE-SENSITIVELY inside
CreateTargetingRuleCommandHandler — FlagTargetingController’s mapping helpers
validate every operator against the enum’s member-name allowlist AND canonicalize the casing
(e.g. "in" → "In") before building the command DTO, so a valid
case-insensitive match never trips the handler’s strict re-parse.
object
Request-side condition group, symmetric with PublicConditionGroupResponse.
object
Allowed values: And, Or.
Request-side condition, symmetric with PublicConditionResponse.
object
Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.
Example
{ "description": "North American users get the new flow at 25%.", "variationId": "0197b6a0-6a1b-7d4f-8c2e-2f3a4b5c6d7e", "rolloutPercentage": 25, "conditionGroups": [ { "operator": "And", "conditions": [ { "attribute": "country", "operator": "In", "values": [ "US", "CA" ], "negate": false } ] } ]}Responses
Section titled “Responses”No Content
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.
Bad Request
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.
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.
Forbidden
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.