Intentions

Intentions are the CQRS write path in Sphere. Instead of performing direct CRUD operations on the database, you submit an "intention" describing what you want to happen. The system processes the intention, validates it, produces domain events, and updates projections (Timeline, Inbox, Search).

This architecture provides a full audit trail of every change, enables event-driven workflows, and ensures that all write operations go through consistent validation and business rules.


How intentions work

When you submit an intention:

  1. The system validates the intention payload against the family schema
  2. Business rules and workflows are evaluated
  3. Domain events are produced (e.g. entity.created, entity.field_updated)
  4. Projections are updated asynchronously (Timeline, Inbox, Search index)
  5. The processed intention is returned with its result

Intentions are processed synchronously -- the response includes the resulting entity state and any events that were produced.


POST/core/api/v1/intentions

Submit an intention

Submit an intention to be processed. The intention type determines what action will be taken, and the payload provides the data for that action.

Request body

  • Name
    type
    Type
    string
    Description

    The intention type. One of entity.create, entity.update, entity.delete, or entity.status_change.

  • Name
    payload
    Type
    object
    Description

    The data for the intention. Structure depends on the intention type (see examples below).

Intention types

  • Name
    entity.create
    Description

    Create a new entity. Payload requires family (string) and fields (object). Optionally accepts status.

  • Name
    entity.update
    Description

    Update an existing entity. Payload requires entity_id (string) and fields (object with changed values).

  • Name
    entity.delete
    Description

    Delete an entity. Payload requires entity_id (string).

  • Name
    entity.status_change
    Description

    Change an entity's pipeline status. Payload requires entity_id (string) and status (string).

Response fields

  • Name
    id
    Type
    string
    Description

    The unique identifier of the processed intention.

  • Name
    type
    Type
    string
    Description

    The intention type that was processed.

  • Name
    status
    Type
    string
    Description

    The processing status. One of processed, rejected, or failed.

  • Name
    entity_id
    Type
    string
    Description

    The ID of the entity that was affected.

  • Name
    events
    Type
    array
    Description

    List of domain events produced by this intention.

POST
/core/api/v1/intentions
curl -X POST https://your-sphere.example.com/core/api/v1/intentions \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "entity.create",
    "payload": {
      "family": "contact",
      "fields": {
        "first_name": "Diana",
        "last_name": "Prince",
        "email": "diana@example.com"
      }
    }
  }'

Response (entity.create)

{
  "data": {
    "id": "int-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "type": "entity.create",
    "status": "processed",
    "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
    "events": [
      {
        "type": "entity.created",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "family": "contact",
        "timestamp": "2026-02-20T14:30:00Z"
      },
      {
        "type": "entity.field_set",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "field": "first_name",
        "value": "Diana",
        "timestamp": "2026-02-20T14:30:00Z"
      },
      {
        "type": "entity.field_set",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "field": "last_name",
        "value": "Prince",
        "timestamp": "2026-02-20T14:30:00Z"
      },
      {
        "type": "entity.field_set",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "field": "email",
        "value": "diana@example.com",
        "timestamp": "2026-02-20T14:30:00Z"
      }
    ]
  }
}

POST/core/api/v1/intentions

Update intention example

Example of submitting an entity.update intention. Only the fields you include in the payload will be modified.

Payload for entity.update

  • Name
    entity_id
    Type
    string
    Description

    The ID of the entity to update.

  • Name
    fields
    Type
    object
    Description

    An object mapping field codes to their new values.

POST
/core/api/v1/intentions
curl -X POST https://your-sphere.example.com/core/api/v1/intentions \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "entity.update",
    "payload": {
      "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
      "fields": {
        "email": "diana.prince@newdomain.com",
        "phone": "+1 555 0199"
      }
    }
  }'

Response (entity.update)

{
  "data": {
    "id": "int-b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "type": "entity.update",
    "status": "processed",
    "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
    "events": [
      {
        "type": "entity.field_updated",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "field": "email",
        "old_value": "diana@example.com",
        "new_value": "diana.prince@newdomain.com",
        "timestamp": "2026-02-20T15:00:00Z"
      },
      {
        "type": "entity.field_set",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "field": "phone",
        "value": "+1 555 0199",
        "timestamp": "2026-02-20T15:00:00Z"
      }
    ]
  }
}

POST/core/api/v1/intentions

Status change intention example

Example of submitting an entity.status_change intention to move an entity through its pipeline.

Payload for entity.status_change

  • Name
    entity_id
    Type
    string
    Description

    The ID of the entity whose status to change.

  • Name
    status
    Type
    string
    Description

    The new status. Must be a valid status defined in the entity's family pipeline.

POST
/core/api/v1/intentions
curl -X POST https://your-sphere.example.com/core/api/v1/intentions \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "entity.status_change",
    "payload": {
      "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
      "status": "archived"
    }
  }'

Response (entity.status_change)

{
  "data": {
    "id": "int-c3d4e5f6-a7b8-9012-cdef-345678901bcd",
    "type": "entity.status_change",
    "status": "processed",
    "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
    "events": [
      {
        "type": "entity.status_changed",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "old_status": "active",
        "new_status": "archived",
        "timestamp": "2026-02-20T16:00:00Z"
      }
    ]
  }
}

POST/core/api/v1/intentions

Delete intention example

Example of submitting an entity.delete intention. This removes the entity and all associated relations.

Payload for entity.delete

  • Name
    entity_id
    Type
    string
    Description

    The ID of the entity to delete.

POST
/core/api/v1/intentions
curl -X POST https://your-sphere.example.com/core/api/v1/intentions \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "entity.delete",
    "payload": {
      "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc"
    }
  }'

Response (entity.delete)

{
  "data": {
    "id": "int-d4e5f6a7-b8c9-0123-def4-56789012cde3",
    "type": "entity.delete",
    "status": "processed",
    "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
    "events": [
      {
        "type": "entity.deleted",
        "entity_id": "ent-3c4d5e6f-7a8b-9012-cdef-234567890abc",
        "family": "contact",
        "timestamp": "2026-02-20T17:00:00Z"
      }
    ]
  }
}

Was this page helpful?