segment_apply
Create one segment or update an observed non-preset segment's title and/or complete conditions. Requires the reader's permission and identities. Updates do not expose description, preset status, arbitrary trees or URLs.
Input
| Input | Contract |
|---|---|
| channelCode | Required selected channel code. |
| requestId | Required stable ID matching [A-Za-z0-9_-]{8,80}; keep it for all recovery. |
| expectedRevision | Required 64 lowercase hexadecimal characters. For create use creationRevision from list/options; for update use the selected detail revision. Catalogue revision is not interchangeable. |
| action | Required create or update. |
| distinctId | Forbidden on create; required observed target on update. |
| settings | Required strict object with title, conditions or both. Create requires both. |
| settings.title | Optional on update; trimmed to 1–50 characters. |
| settings.conditions | Full replacement of both trees when present; omitted on update preserves existing trees. |
| dryRun | Optional boolean, default false. A fresh dry run saves no journal or business state; entity resolution may use read-only POST. |
The nested paths settings.conditions.include, settings.conditions.include[].anyOf, settings.conditions.include[].anyOf[].classificationCode, settings.conditions.include[].anyOf[].value and settings.conditions.include[].anyOf[].targetEntityIds follow the condition contract. So do settings.conditions.exclude, settings.conditions.exclude[].anyOf, settings.conditions.exclude[].anyOf[].classificationCode, settings.conditions.exclude[].anyOf[].value and settings.conditions.exclude[].anyOf[].targetEntityIds. Include/exclude groups and limits are identical to preview. Omitted/null exclude in a replacement means no exclusion; this is not a patch to just inclusion. All source value, release, entity and exhaustible rules apply. Saving does not count members.
{"channelCode":"selected-channel-code","action":"create","requestId":"segment-create-001","expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000","settings":{"title":"Example audience","conditions":{"include":[{"anyOf":[{"classificationCode":"SGMT_FINALIZED_NONE_ENUM_USER_A001001"}]}]}},"dryRun":true}
{"channelCode":"selected-channel-code","action":"update","distinctId":"observed-segment","requestId":"segment-rename-001","expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000","settings":{"title":"Updated audience"},"dryRun":true}
{"channelCode":"selected-channel-code","action":"update","distinctId":"observed-segment","requestId":"segment-conditions-001","expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000","settings":{"conditions":{"include":[{"anyOf":[{"classificationCode":"SGMT_FINALIZED_NONE_ENUM_USER_A001001"}]}],"exclude":null}},"dryRun":true}
Replace every example revision/ID/classification with observed values. The demo classification is illustrative; no default audience is selected for the caller.
Prepare, save and preservation
Create observes two complete inventories, up to 2,000 rows/20 pages of 100, with stable totals and unique numeric/opaque identities. The creation revision binds context, not that inventory. Update reads full selected detail twice; presets fail before writing. The expected revision must match, and replacement conditions are composed from current definitions/entities. A matching update is a no-op with a completed saved job, no source mutation and the original snapshot retained.
A fresh dry run returns SEGMENT_PLAN, changes containing the actual title/tree body, warnings, noop, plannedStages and verification.confirmed:false. It does not reserve context, entities or capacity. Reusing an existing requestId validates its stored fingerprint: different input returns REQUEST_ID_CONFLICT; dryRun for that existing job returns historical planning information without executing it, so it is not a fresh validation of the source.
Before dispatch, context, complete before-state, any baseline inventory and definitions/entities are observed again. The prepared journal is durably advanced to write-sent before one create POST or update PATCH. Create accepts HTTP 200/201; PATCH expects 200. The receipt requires segment with a positive safe-integer id or a canonical positive decimal string of 1–16 digits normalized to that integer, plus opaque distinctId and optional numeric channelId. Zero, leading zeros, signs, spaces, decimal/exponent forms and unsafe values fail. Only receipt row id is normalized; full detail, journals and optional receipt channelId remain strictly numeric. Create cannot reuse any baseline identity; update must match the selected identity. Returned fields that contradict the requested/preserved state fail receipt verification. Update also rejects new unknown receipt fields; create may return additional generated fields.
After a valid receipt, a durable created identity is retained for create, acknowledged is set, and fresh repeated full detail must match the intended result. Update preserves every unedited internal business field and permits only top-level updatedAt to change; if present before it must remain present. Full timestamps remain in revisions and pre-write/no-op evidence. Create verifies the returned identity, requested title/trees/evaluationType and isPreset:false. The composer uses observed definition.name for itemName and selected option.name/description for every supported value type. Exact repeated entity resolution supplies IDs/titles and canonical isDeleted:false. Receipt/readback still rejects changed metadata, deleted entities and unrequested tree changes. Standalone description:null is preserved distinctly from empty string or absence through reads, journals and comparisons. Completion requires the final context check. No atomic conditional update, rollback or financial grant is provided.
Inputs
| Field | Required here | Contract |
|---|---|---|
action |
Yes | create, update |
distinctId |
No | string; pattern ^[A-Za-z0-9_-]{1,128}$ |
settings |
Yes | object |
settings.title |
No | string; min length 1; max length 50 |
settings.conditions |
No | object |
settings.conditions.include |
Yes | array; min items 1; max items 20 |
settings.conditions.include[].anyOf |
Yes | array; min items 1; max items 25 |
settings.conditions.include[].anyOf[].classificationCode |
Yes | string; min length 1; max length 256 |
settings.conditions.include[].anyOf[].value |
No | string; max length 10000 |
settings.conditions.include[].anyOf[].targetEntityIds |
No | array; items: string; pattern ^[A-Za-z0-9_-]{1,128}$; max items 100 |
settings.conditions.exclude |
No | array; min items 1; max items 20 or null |
confirmToken |
No | string; pattern ^ct[a-f\d]{32}$; The confirmToken from this tool's preview result. Omit it to preview; repeat the same input with it to execute. |
Result and recovery
The shared segment recovery contract applies. Results use taskType:segment and phases prepared, write-sent or done. SEGMENT_COMPLETE requires done; SEGMENT_PENDING can wrap an error/unknown outcome in lastResult. acknowledged:true means receipt validation succeeded for save, not just that the HTTP response arrived. Therefore false after write-sent cannot prove no effect. writesPerformed is false for prepared/no-op, true after acknowledgement, otherwise null.
Use status first, then resume only within the original operation. Prepared may perform the original first write after guards; write-sent only reconciles and never resends. A lost create receipt/identity cannot be adopted by title or reconstructed from a newly appearing list row. Preserve the job and inspect the exact console list. Completed results are historical on replay/status/resume and confirmed:false; get current detail separately. Authentication/context failures and journalPersistence.saved:false require inspection, not a new request ID. Delivery, eligibility and linked campaign behavior remain outside this result.
Current observations use the bounded response and recovery rules. An oversized response is not a successful empty result. If a write was already sent, retain its original task and reconcile; the failed read does not authorize repeating the change.
Saved record identity
A missing record differs from an existing malformed record. Stored JSON null,
false, zero or an empty string is rejected with TASK_STATE_UNVERIFIED by the
existing record validator. Apply/dry-run/status/resume must not overwrite it or
treat it as a fresh task. Preserve the file for inspection; do not delete/edit it
or replace the request ID to bypass the error. Existing valid task recovery and
genuinely missing-record behavior remain unchanged.