Skip to Content
TwinsHow a twin behaves

How a twin behaves

Fidelity, determinism, coverage and transparency, and how to ask a twin what it supports.

Four properties hold for every twin.

Fidelity

Where a vendor’s documentation and its behaviour disagree, the twin implements the behaviour.

Response shapes, status codes, error codes and header behaviour are recorded from the live vendor. Some twins implement behaviour the vendor does not document, and some implement behaviour that contradicts the vendor’s own specification.

Validation is symmetric. Input the vendor rejects is rejected here; input the vendor accepts is accepted here.

Determinism

The same world and the same requests produce the same responses, generated ids included.

Handlers read time from the sandbox’s shared clock and generate ids from a deterministic sequence. Wall-clock reads and RNG are not permitted in handler code.

With the clock frozen, identical requests against identical state produce byte-identical responses, generated ids included.

Coverage

A bounded subset of the vendor’s surface, and a refusal that names itself outside it.

A twin implements a subset of the vendor’s API. A request resolves one of three ways:

  • Implemented. Handled normally.
  • Outside the vendor’s API. The vendor’s own 404 or 405.
  • Published by the vendor, not implemented here. A 501 in the vendor’s error envelope.

The 501 is conclusive. A 400 or 404 is not, since the real vendor returns those too. Check the credential, API version, payload shape and seeded rows before treating one as a coverage gap.

Transparency

Your code cannot detect a twin. Your agent can inspect all of it.

Responses carry no sandbox markers, no additional headers and no Veris metadata. The framework’s /openapi.json, /docs and /redoc routes are disabled.

The control plane is unrestricted. /veris/data returns world state, /veris/schema the table and column definitions, /veris/manual the operating notes, and /veris/requests the full request log.

Asking a twin what it supports

Each twin answers for itself, on the control_url that veris sandbox services get prints.

EndpointReturns
GET /veris/manualCredentials, API versions, and the fault statuses this twin accepts
GET /veris/schemaEvery table and column, with descriptions
GET /veris/operationsEvery operation this twin serves. ?surface=rest, graphql or mcp narrows it

To test one specific operation, arm a fault at it. The request is validated against the published surface before anything is written, so it changes no state.

$CONTROL_URL is one twin’s control URL, printed by veris sandbox services get — see the control plane.

curl -X POST "$CONTROL_URL/veris/data" \ -H 'Content-Type: application/json' \ -d '{"data": {"faults": [{"method": "POST", "path": "/v1/charges", "outcome": "error", "error": {"status": 429}}]}}'
ResponseMeaning
200 {"added":{"faults":1}}Served. Delete the row if you were only checking
422 "POST is not published for path …"Path served, method not
422 "path … does not match a published operation"Not served. Also returned for a wrong API version

For the list of twins rather than the surface of one, use veris services, GET /v1/services, or the console.

The rest of the control plane

Every twin serves the same routes on its control_url.

EndpointFor
GET /veris/dataRow counts per table, or rows with ?entity_type=
POST PATCH DELETE /veris/dataAdd, change and remove rows
POST /veris/filesUpload file bytes, on twins whose vendor holds files
GET /veris/requestsEvery request this twin served, with bodies and headers
POST /veris/snapshotA full dump of this twin’s state, table by table
POST /veris/resetReset this twin to its default world
POST /veris/reset-worldReturn the sandbox’s shared clock to live time
POST /veris/client/probeRe-check that the registered callback destination is reachable
GET /veris/healthLiveness, plus the twin’s name and state version

No API key is needed. The sandbox id in the path is the capability. Full detail in the control plane reference.