Skip to content

Issuing commands

A command asks EvidentSource to do something. It runs a State Change at a revision: the component’s decide function reads the database, checks the command, and returns the events to append, together with the append conditions that must hold when they commit.

The examples use the TodoMVC example in a database of your own. Set it up first.

  • A State Change and its version, such as create-todo and v1.
  • A revision to run at: a number, or latest.
  • A body. It has no fixed envelope: the request body and its Content-Type go to decide as they are. TodoMVC’s components take JSON.
Terminal window
curl -X POST "https://sandbox.evidentsource.com/api/v1/db/todomvc-yourname/latest/state-changes/create-todo/v1" \
-H 'Content-Type: application/json' \
-d '{"todoId": "3f0b5a0e-1c2d-4e5f-8a9b-0c1d2e3f4a5b", "title": "Try EvidentSource", "effectiveTimestamp": "2026-09-17T00:00:00Z"}'

A command that commits answers 200 with the transaction, including the revision its last event reached:

{"id":"01a0ad3f-…","database":"todomvc-yourname","revision":"1","timestamp":"…","metadata":{"origin":{"httpStateChange":{"name":"create-todo","version":"1"}}}}

Call ExecuteStateChange, or ExecuteStateChangeAsync to return without waiting for the outcome. See gRPC API.

Each SDK’s database connection runs State Changes. See Connecting with an SDK.

Send a transaction id in the x-batch-id header. Resending a command with the same id returns the result already recorded for it instead of committing again, so a retry after a timeout can’t apply a command twice.

  • 400, validation error: decide refused the command, or its body didn’t parse. The message says which.
  • 409: an append condition decide returned no longer held when the events were appended. Nothing was committed. Read the database again, and send the command again.