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
404or405. - Published by the vendor, not implemented here. A
501in 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.
| Endpoint | Returns |
|---|---|
GET /veris/manual | Credentials, API versions, and the fault statuses this twin accepts |
GET /veris/schema | Every table and column, with descriptions |
GET /veris/operations | Every 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}}]}}'| Response | Meaning |
|---|---|
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.
| Endpoint | For |
|---|---|
GET /veris/data | Row counts per table, or rows with ?entity_type= |
POST PATCH DELETE /veris/data | Add, change and remove rows |
POST /veris/files | Upload file bytes, on twins whose vendor holds files |
GET /veris/requests | Every request this twin served, with bodies and headers |
POST /veris/snapshot | A full dump of this twin’s state, table by table |
POST /veris/reset | Reset this twin to its default world |
POST /veris/reset-world | Return the sandbox’s shared clock to live time |
POST /veris/client/probe | Re-check that the registered callback destination is reachable |
GET /veris/health | Liveness, 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.