The generated API
Every contract gets an API derived from its artifact. Actions and queries are internal unless marked api authenticated or api public.
Mandala's routes (simplest)
Inside the Workspace and for scripts on your tailnet, Mandala signs for you, as the acting identity, under your delegation:
| Route | Does |
|---|---|
GET /api/data | Every contract with its state, queries and actions, typed |
POST /api/data/query | Runs a query for the acting identity |
POST /api/data/preview | Shows exactly what an action will sign |
POST /api/data/act | Signs and submits an action |
GET /api/personal/{contract}/query/{query} | Queries a personal contract (?as=<identity> acts for another identity) |
POST /api/personal/{contract}/act/{action} | Acts on a personal contract |
GET /api/business/{contract}/query/{query}, POST /api/business/{contract}/act/{action} | The same for business contracts |
The engine's API (/v1)
The engine's own interface is served on the same address under /v1. Here the client signs: commands carry the original signed assertion, and the API never signs on anyone's behalf.
| Request | Purpose |
|---|---|
GET /v1/{tenant}/{namespace}/openapi.json, …/schema.graphql, …/api.proto, …/descriptors.pb | Discover the interface |
POST /v1/{tenant}/{namespace}/actions/{Action} | Submit {command, args} |
POST /v1/{tenant}/{namespace}/queries/{Query} | Run a query with its arguments |
POST /v1/{tenant}/{namespace}/graphql | GraphQL |
JSON requests carry x-dhl-artifact naming the active artifact. Command metadata holds subject, expected_version, actor, idempotency_key and the hex-encoded signed_assertion_cbor. A tenant-scoped bearer credential authenticates the actor; the contract still decides whether the action is allowed.
Integers, timestamps and decimals are decimal strings; identities are lowercase hex (DHL types).
Receipts
An accepted action returns a receipt with the record's new revision. A refused one returns the refusal, with the rule that refused it when the contract can tell (UI files). A timeout leaves the outcome uncertain: recover the original intent and receipt before submitting a replacement.
Describe offline
dhl-engine describe contracts/com/acme/orders/order.dhl /tmp/order-api
writes openapi.json, schema.graphql, api.proto and the contract description. See Command line.