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:

RouteDoes
GET /api/dataEvery contract with its state, queries and actions, typed
POST /api/data/queryRuns a query for the acting identity
POST /api/data/previewShows exactly what an action will sign
POST /api/data/actSigns 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.

RequestPurpose
GET /v1/{tenant}/{namespace}/openapi.json, …/schema.graphql, …/api.proto, …/descriptors.pbDiscover 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}/graphqlGraphQL

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.