Creates a user segment in the resolved project.
const url = 'https://api.featureflip.io/api/v1/orgs/example/projects/example/segments';const options = { method: 'POST', headers: {Authorization: '<Authorization>', 'Content-Type': 'application/json'}, body: '{"key":"beta-testers","name":"Beta Testers","description":"Users enrolled in the beta program.","conditions":[{"attribute":"email","operator":"EndsWith","values":["@acme.com"],"negate":false}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.featureflip.io/api/v1/orgs/example/projects/example/segments \ --header 'Authorization: <Authorization>' \ --header 'Content-Type: application/json' \ --data '{ "key": "beta-testers", "name": "Beta Testers", "description": "Users enrolled in the beta program.", "conditions": [ { "attribute": "email", "operator": "EndsWith", "values": [ "@acme.com" ], "negate": false } ] }'Requires at least Member. Re-fetches via ListUserSegmentsQuery (there is no single-segment query) and locates the new segment by the id returned from CreateUserSegmentCommand so the response reflects exactly what was persisted (e.g. server-assigned condition ids, folded into the public shape via FromDto).
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Body
Section titled “Request Body”Request body for POST /api/v1/orgs/{org}/projects/{project}/segments. Named distinctly
from the dashboard’s own CreateUserSegmentRequest — see
PublicCreateEnvironmentRequest for the schemaId-collision rationale (both
controllers share one Swagger document).
object
A single targeting condition on a segment, used both as input (create/update) and output
(Conditions). Operator is a bare string on
both sides of the wire — on write it’s parsed to
OperatorType by SegmentsController (an unknown
value fails closed with a 400, never silently dropped or defaulted); on read it’s mapped
straight through from Operator, which is already a string.
object
Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.
Example
{ "key": "beta-testers", "name": "Beta Testers", "description": "Users enrolled in the beta program.", "conditions": [ { "attribute": "email", "operator": "EndsWith", "values": [ "@acme.com" ], "negate": false } ]}Request body for POST /api/v1/orgs/{org}/projects/{project}/segments. Named distinctly
from the dashboard’s own CreateUserSegmentRequest — see
PublicCreateEnvironmentRequest for the schemaId-collision rationale (both
controllers share one Swagger document).
object
A single targeting condition on a segment, used both as input (create/update) and output
(Conditions). Operator is a bare string on
both sides of the wire — on write it’s parsed to
OperatorType by SegmentsController (an unknown
value fails closed with a 400, never silently dropped or defaulted); on read it’s mapped
straight through from Operator, which is already a string.
object
Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.
Example
{ "key": "beta-testers", "name": "Beta Testers", "description": "Users enrolled in the beta program.", "conditions": [ { "attribute": "email", "operator": "EndsWith", "values": [ "@acme.com" ], "negate": false } ]}Request body for POST /api/v1/orgs/{org}/projects/{project}/segments. Named distinctly
from the dashboard’s own CreateUserSegmentRequest — see
PublicCreateEnvironmentRequest for the schemaId-collision rationale (both
controllers share one Swagger document).
object
A single targeting condition on a segment, used both as input (create/update) and output
(Conditions). Operator is a bare string on
both sides of the wire — on write it’s parsed to
OperatorType by SegmentsController (an unknown
value fails closed with a 400, never silently dropped or defaulted); on read it’s mapped
straight through from Operator, which is already a string.
object
Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.
Example
{ "key": "beta-testers", "name": "Beta Testers", "description": "Users enrolled in the beta program.", "conditions": [ { "attribute": "email", "operator": "EndsWith", "values": [ "@acme.com" ], "negate": false } ]}Responses
Section titled “Responses”Created
Public representation of a user segment, returned by GET .../segments,
GET .../segments/{segment}, and the body of a successful create.
object
A single targeting condition on a segment, used both as input (create/update) and output
(Conditions). Operator is a bare string on
both sides of the wire — on write it’s parsed to
OperatorType by SegmentsController (an unknown
value fails closed with a 400, never silently dropped or defaulted); on read it’s mapped
straight through from Operator, which is already a string.
object
Allowed values: Equals, NotEquals, Contains, NotContains, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, In, NotIn, MatchesRegex, StartsWith, EndsWith, Before, After, SemverEquals, SemverGreaterThan, SemverGreaterThanOrEqual, SemverLessThan, SemverLessThanOrEqual.
Capability hints: which operations the authenticated caller may perform on this resource, each with allowed + optional reason. Computed from the caller’s role and the resource’s state. Injected at runtime; safe to ignore. Present only on top-level resource responses — nested occurrences (e.g. a rule inside a targeting-config response) do not carry it.
object
One entry in a resource’s _actions block: may the caller perform it, and if not, why.
object
Example
{ "id": "0197b6a1-3c4d-7e5f-8a6b-7c8d9e0f1a2b", "key": "beta-testers", "name": "Beta Testers", "description": "Users enrolled in the beta program.", "conditions": [ { "attribute": "email", "operator": "EndsWith", "values": [ "@acme.com" ], "negate": false } ], "createdAt": "2026-06-01T12:00:00Z", "updatedAt": "2026-06-15T08:30:00Z"}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.