Status (Semantic Module)
In modern business applications, data rarely exists in a static state. An article moves from a draft to editorial review, publication, and eventual archival. An order moves from placed to fulfilled to completed. A support ticket progresses from open to in-progress to resolved.
The Status semantic module brings lifecycle workflow management directly to your data model. It transforms a standard text property with predefined choices into an active lifecycle state machine.
Instead of writing custom backend code or database triggers, you configure your business lifecycle declaratively:
- Predefined States: The valid choices defined directly on the property (such as
draft,submitted,in_review,published, andarchived). - Default Starting State: The automatic starting state assigned when a record is newly created without a specified status.
- Allowed Initial States: Which states callers are permitted to choose when creating a new record (preventing callers from bypassing early workflow stages).
- Permitted State Transitions: The step-by-step roadmap of allowed next states (preventing illegal workflow jumps).
- Terminal States: Final, closed states where a record’s lifecycle concludes and no further status modifications are permitted.
The platform automatically validates every creation and update request against these rules. If an API client attempts an illegal transition or tries to modify a finalized record, the request is safely rejected with clear, actionable HTTP 422 Unprocessable Entity feedback.
Technical Specifications
Section titled “Technical Specifications”| Attribute | Specification |
|---|---|
| Scope | Property (Applied directly to a single entity property) |
| Data Type | String (Text) with predefined values (choices / enum) |
| Multiplicity | Single value only (scalar). Records cannot have multiple statuses simultaneously. |
| Entity Frequency | Maximum 1 Status property per entity across its entire hierarchy. |
| Database Indexing | Mandatory. Status properties must be marked as indexed to ensure fast query filtering. |
| Valid States Source | The property’s predefined values list. |
| Default State Source | The property’s standard default value setting. |
| Authorization Integration | Auto-detected by the Match Lifecycle Status access rule in the API Modeler. |
Key Capabilities & Workflow Rules
Section titled “Key Capabilities & Workflow Rules”1. Predefined States & Starting Default
Section titled “1. Predefined States & Starting Default”The valid states for your lifecycle come directly from the list of predefined choices configured on the property.
The starting state is defined using the property’s standard Default Value setting (for example, draft). When an API client creates a record without providing a status, the system automatically assigns this default value.
2. Restricting Creation States (initialStatuses)
Section titled “2. Restricting Creation States (initialStatuses)”By default, if no initial states are specified, an API client can create a new record in any valid predefined state.
In many business workflows, however, records must begin in a specific starting stage:
- Editorial Review: An author should only be able to create articles in
draft, not directly inpublished. - Invoicing: A bill should start as
draftorpending_approval, notpaid.
By configuring Allowed Initial States, you specify the subset of states accepted during record creation (POST). Any attempt to create a record with an unapproved initial state is rejected with an HTTP 422 Unprocessable Entity error.
3. Permitted State Transitions (transitions)
Section titled “3. Permitted State Transitions (transitions)”The state transition map defines the directed roadmap of valid next steps from each current state:
stateDiagram-v2
[*] --> draft : Initial State on Create
draft --> submitted : Submit for Review
submitted --> in_review : Start Review
submitted --> draft : Return for Edits
in_review --> published : Approve & Publish
in_review --> draft : Reject to Draft
published --> draft : New Revision
published --> archived : Archive Content
archived --> [*] : Terminal (Locked)
- Step-by-Step Validation: When an API client updates a record’s status, the system checks whether the new status is an approved next step for the current state.
- Preventing Workflow Bypasses: If an article is currently in
draft, an attempt to update its status directly topublishedis rejected becausepublishedis not in the allowed next steps fordraft. - Flexible Workflows & Cycles: Workflows can branch into multiple directions or loop cyclically. For example, a
publishedarticle can transition back todraftwhen starting a revision. - Open Transitions: If no transition rules are configured, records can transition freely between any of the property’s predefined states.
4. Terminal States (terminalStatuses)
Section titled “4. Terminal States (terminalStatuses)”Terminal states represent permanent end-of-lifecycle stages (such as archived, cancelled, or closed):
- Write Locking: Once a record enters a terminal state, its status field is locked against any further modifications.
- Immediate Rejection: Any update request attempting to change the status of a terminal record is rejected with an HTTP
422 Unprocessable Entityerror. - Completely Optional: Lifecycles without permanent dead-ends (such as continuous cyclic workflows) do not require terminal states.
Workflow Integrity vs. API Authorization
Section titled “Workflow Integrity vs. API Authorization”It is important to understand the distinct roles of the Status semantic module and API Access Rules:
| Concept | Purpose | Where It Is Configured | How It Behaves |
|---|---|---|---|
| Status Semantic Module | Workflow Integrity & Transitions | Data Domain Modeler (on the entity property) | Answers: “Is this state transition physically and logically valid according to business rules?” Evaluates submitted data during record creation and updates. |
Match Lifecycle Status | Permissions & Visibility | API Modeler (on exposed endpoints & actions) | Answers: “Who is allowed to view, edit, or delete records that are currently in this state?” Evaluates caller identity and injects database filters. |
Practical Example: Publishing an Article
Section titled “Practical Example: Publishing an Article”- The State Machine (Status Module) defines that an article can legally transition from
in_reviewtopublished. - The API Access Rule (
Match Lifecycle Status) ensures that only callers with theeditorrole can invoke the endpoint when the article is inin_review, while public callers can only see records inpublished.
Operational permissions (such as which roles can edit or view records in a given state) are managed in API Access Rules, keeping your data model clean, reusable, and decoupled from authentication strategies.
Runtime Behavior & HTTP Responses
Section titled “Runtime Behavior & HTTP Responses”The runtime enforces your lifecycle rules consistently across all API operations:
Record Creation (POST /resources)
Section titled “Record Creation (POST /resources)”- Status omitted: The system automatically assigns the property’s default value (
201 Created). - Explicit
nullsubmitted: The request is rejected with HTTP422 Unprocessable Entity("The field 'status' cannot be set to null."). - Disallowed initial status submitted: If initial states are configured and the submitted value is not among them, the request is rejected with HTTP
422 Unprocessable Entity. - Valid initial status submitted: The record is created with the requested status (
201 Created).
Record Modification (PATCH / PUT /resources/:id)
Section titled “Record Modification (PATCH / PUT /resources/:id)”- Status omitted: The record’s status remains unchanged; other properties update normally (
200 OK). - Status unchanged: Submitting the current status is treated as a safe, idempotent operation (
200 OK). - Explicit
nullsubmitted: The request is rejected with HTTP422 Unprocessable Entity. - Record currently in a terminal state: Any attempt to modify the status is rejected with HTTP
422 Unprocessable Entity("Cannot transition from terminal status 'archived'."). - Invalid transition attempted: If the new status is not listed in the transitions map for the current status, the request is rejected with HTTP
422 Unprocessable Entity. - Legacy or uninitialized records: If an existing database record does not have a status set, an update that omits status automatically initializes it with the default value, while an update that supplies a status validates it as an initial assignment.
Concrete API Examples
Section titled “Concrete API Examples”In this example, an Article entity defines a status property with choices draft, submitted, in_review, published, and archived:
- Default Value:
draft - Allowed Initial States:
['draft'] - Transitions:
draft→['submitted']submitted→['in_review', 'draft']in_review→['published', 'draft']published→['draft', 'archived']
- Terminal States:
['archived']
1. Creating a Record with the Default Status
Section titled “1. Creating a Record with the Default Status”When an author creates a new article without providing a status:
POST /articlesContent-Type: application/json
{ "title": "Designing Data Semantics"}The system automatically assigns the default status draft:
HTTP/1.1 201 CreatedContent-Type: application/json
{ "data": { "id": "art_101", "title": "Designing Data Semantics", "status": "draft" }}2. Attempting an Unauthorized Initial Status
Section titled “2. Attempting an Unauthorized Initial Status”A caller attempts to create an article directly in the published state, bypassing the review process:
POST /articlesContent-Type: application/json
{ "title": "Unreviewed Article", "status": "published"}The system blocks the request:
HTTP/1.1 422 Unprocessable EntityContent-Type: application/json
{ "type": "https://docs.apinow.app/errors/validation", "title": "Validation Error", "status": 422, "code": "VALIDATION_ERROR", "detail": "Field validation failed", "errors": [ { "field": "status", "message": "Invalid initial status: 'published'. Allowed initial statuses: 'draft'." } ]}3. Executing a Valid State Transition
Section titled “3. Executing a Valid State Transition”The author submits their draft for review:
PATCH /articles/art_101Content-Type: application/json
{ "status": "submitted"}Because draft → submitted is an approved transition path, the update succeeds:
HTTP/1.1 200 OKContent-Type: application/json
{ "data": { "id": "art_101", "title": "Designing Data Semantics", "status": "submitted" }}4. Attempting an Invalid State Transition
Section titled “4. Attempting an Invalid State Transition”A client attempts to move an article directly from submitted to archived:
PATCH /articles/art_101Content-Type: application/json
{ "status": "archived"}The transition is rejected because archived is not an allowed next step from submitted:
HTTP/1.1 422 Unprocessable EntityContent-Type: application/json
{ "type": "https://docs.apinow.app/errors/validation", "title": "Validation Error", "status": 422, "code": "VALIDATION_ERROR", "detail": "Field validation failed", "errors": [ { "field": "status", "message": "Invalid status transition from 'submitted' to 'archived'. Valid transitions: 'in_review', 'draft'." } ]}5. Attempting to Modify a Terminal Record
Section titled “5. Attempting to Modify a Terminal Record”An article has reached the archived state. A client attempts to return it to draft:
PATCH /articles/art_101Content-Type: application/json
{ "status": "draft"}The engine blocks the modification because archived is a terminal state:
HTTP/1.1 422 Unprocessable EntityContent-Type: application/json
{ "type": "https://docs.apinow.app/errors/validation", "title": "Validation Error", "status": 422, "code": "VALIDATION_ERROR", "detail": "Field validation failed", "errors": [ { "field": "status", "message": "Cannot transition from terminal status 'archived'." } ]}Data Modeling Best Practices & Validation Rules
Section titled “Data Modeling Best Practices & Validation Rules”1. The Single Status Rule (No Multiple Statuses)
Section titled “1. The Single Status Rule (No Multiple Statuses)”The platform enforces that an entity can have at most one property tagged with the Status semantic module across its entire inheritance tree.
- Why this rule exists: A state machine requires a record to occupy exactly one lifecycle state at any point in time. If an entity could have multiple status properties or multiple status values, the system could not determine which transitions apply, what happens during updates, or which state protects the record in access rules.
- Direct Properties: You cannot tag two fields on the same entity with
Status(for example, attempting to applyStatusto bothorder_statusandpayment_statuson the same entity will trigger a validation error). - Inherited Properties & Shadowing: If an entity inherits from a parent entity that already defines a
Statusproperty (such asArticleextendingContentItem), it automatically shares that status. The child entity cannot define a second, differently named status field, nor can an entity inherit conflicting status properties from multiple parents. However, a child entity can shadow (override) the parent’s status property by declaring a property with the exact same name if it needs to customize the allowed states or state transitions specifically for that child entity. - Single Value (Scalar) Only: A status property must be single-valued (
scalar). It cannot be configured as a list or array (multiple: true). For records that require multiple classification labels, useCategoriesorTagsinstead.
2. How to Model Independent Business Lifecycles
Section titled “2. How to Model Independent Business Lifecycles”In real-world applications, a single business transaction might involve multiple processes that happen in parallel. For example, an e-commerce order tracks:
- Fulfillment Pipeline:
placed→processing→shipped→delivered - Payment Pipeline:
unpaid→authorized→paid→refunded
Because an entity can only have one Status property, choose one of these recommended approaches:
- Approach A (Recommended): Model as Separate Entities: Create an
Orderentity with afulfillment_status(tagged withStatus), and a relatedPaymententity with apayment_status(tagged withStatus). This represents the real-world domain cleanly and gives each entity its own dedicated state machine. - Approach B: Primary Status + Standard Choice Property: Tag the primary business workflow (e.g.
fulfillment_status) with theStatusmodule, and keep the secondary workflow (e.g.payment_status) as a standard text property with predefined choices (enum) without theStatusmodule.
3. General Best Practices Checklist
Section titled “3. General Best Practices Checklist”- Mandatory Indexing: Always ensure database indexing is enabled (
index: true) on your status property. Because status fields are actively filtered in collection queries and evaluated by authorization rules, indexing guarantees fast queries and avoids slow table scans. - Align Default and Initial States: When configuring an initial states list, make sure the property’s default value is one of those initial states so automatic record creation succeeds.
- Reserve Terminal States for True Dead-Ends: If records can ever be reopened or recycled, omit terminal states and use cyclic transitions instead.
Related Guides
Section titled “Related Guides”Match Lifecycle Status: Restrict API endpoint visibility and actions based on record lifecycle status.- Validation Error Reference: Understanding HTTP 422 error payloads and troubleshooting validation failures.
- Entity Properties Guide: Configuring property data types, default values, and enum choices.