Skip to content
Settings

Install cyoda-go and create your first entity

This page takes you from nothing installed to a persisted entity you can query, running entirely on your own machine. The default backend is SQLite — zero operational overhead, one file on disk, data survives restarts.

cyoda-go ships as a single binary. Pick the flavour that fits your machine; the authoritative list of installers lives in the cyoda-go README.

Terminal window
# macOS / Linux via Homebrew
brew install cyoda-platform/cyoda-go/cyoda

The Homebrew formula is expected to run cyoda init automatically, enabling SQLite persistence with data at ~/.local/share/cyoda/cyoda.db on macOS/Linux. If it didn’t (or if you installed another way), run cyoda init yourself — see cyoda help cli init for what it does. A curl | sh installer, Debian packages, and Fedora RPMs are available for other environments.

Building with Cyoda is easiest with an AI coding assistant. The Cyoda Skills plugin drops in to Claude Code, Cursor, Codex, and other compatible tools, giving them the skills to set up a local instance, model entities, design workflows, and run tests against your Cyoda app. Install it from github.com/Cyoda-platform/cyoda-skills and let your assistant lead — the rest of this page walks through the same steps by hand.

SQLite is durable (data survives restarts), zero-ops (no server to run), and single-file (easy to inspect, back up, or delete). It is the right starting point for everyone except two groups: teams running functional tests where latency matters more than durability (use in-memory mode — see the callout below), and teams building production services (graduate to PostgreSQL when you need active-active HA; see Run → overview).

Start the server with the defaults:

Terminal window
cyoda

Every flag, environment variable, endpoint, error code, metric, and operation is documented in the binary. Browse the topic tree:

Terminal window
cyoda help

Drill in on anything:

Terminal window
cyoda help config # configuration model and precedence
cyoda help crud # entity CRUD over REST
cyoda help search # query predicates and search modes
cyoda help errors # the error catalogue
cyoda help telemetry # metrics, health, tracing, logs

cyoda help <topic> --format=json emits a machine-readable shape suitable for tools; --format=markdown is the default off a TTY.

Before creating an entity, import a workflow so the platform knows which state machine to apply. Save this as workflow.json — two states (draft and submitted) with one manual transition. States are keyed by name; each state owns its outgoing transitions:

{
"workflows": [
{
"version": "1",
"name": "orders-wf",
"initialState": "draft",
"active": true,
"states": {
"draft": {
"transitions": [
{ "name": "submit", "next": "submitted", "manual": true }
]
},
"submitted": {}
}
}
]
}

Post it to the import endpoint for the orders model at version 1:

Terminal window
curl -X POST http://localhost:8080/api/model/orders/1/workflow/import \
-H 'Content-Type: application/json' \
-d @workflow.json

Without this step, cyoda-go applies its default workflow (NONECREATEDDELETED with a single automatic transition), and the submit transition used below will not exist.

For the full workflow schema — processors, criteria, automatic transitions, nested conditions — see Build → workflows and processors.

Define a minimal model and push an entity. Cyoda discovers the schema from the sample you send, so you do not need to declare it up front:

Terminal window
ENTITY_ID=$(curl -s -X POST http://localhost:8080/api/entity/JSON/orders/1 \
-H 'Content-Type: application/json' \
-d '{ "orderId": "ORD-1", "amount": 42.00, "currency": "EUR" }' \
| jq -r '.[0].entityIds[0]')
echo "$ENTITY_ID"

The create response is an array; entityIds[0] on the first element is the system-assigned UUID of the new entity. Subsequent reads and transitions address the entity by that UUID (${ENTITY_ID} here), not by the business key orderId.

Automatic transitions (manual: false) fire immediately on creation, cascading the entity through applicable states until it reaches one with no outgoing auto transitions. The orders-wf workflow you just imported has none, so the entity settles in draft and waits for the manual submit transition below.

Trigger the submit transition on your entity. {entityId} (here ${ENTITY_ID}) is the system-assigned UUID captured from the create response, not the business key orderId:

Terminal window
curl -X PUT http://localhost:8080/api/entity/JSON/${ENTITY_ID}/submit

Fetch the current state and the transition log:

Terminal window
curl http://localhost:8080/api/entity/${ENTITY_ID}

The response shows the entity in its new submitted state plus a record of every revision it has been through. For the full request and response shapes, see the API reference.