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.