Skip to Content
TwinsTwins

Twins

A stateful replica of a vendor API: endpoints, state, auth, scopes, webhooks and error handling, all measured.

A twin is a stateful replica of a vendor’s API. Requests hit real handlers over a real relational schema, so writes persist, subsequent reads reflect them, and lifecycle rules are enforced the way the vendor enforces them.

Each twin reproduces:

  • Endpoints and payloads. The vendor’s paths, methods, request shapes and response shapes, including which fields come back null and which are omitted entirely.
  • State and transitions. Entities carrying the vendor’s own constraints and lifecycle rules, so an operation that is invalid for the current state is refused rather than accepted.
  • Authentication. The credential kinds the vendor accepts, whether that is an API key, a personal access token, an OAuth grant or a signed token minted by a sibling identity twin, plus the exact shape of each refusal.
  • Scopes. Where the vendor hangs permissions on a credential, a token missing one gets that vendor’s 403 rather than a generic 401.
  • Error handling. The vendor’s error envelope, statuses and error codes, and the order it checks things in. Some vendors route before they check the credential and some after, and serving the wrong one turns a correct assertion into a failure.
  • Webhooks. Vendors that originate callbacks deliver them, with the payload and signature the real one sends.
  • Failure modes. Rate limits, timeouts, 5xx and lost responses, armed as data rather than invented.

All of it measured against the live vendor rather than derived from its specification, because vendor specifications are routinely wrong about their own behaviour.

Nothing about your request changes: same hostname, same credential, same SDK.

Twins, mocks, and the real vendor

Real vendorMockTwin
Statefulness
Fidelity
Speed
Safety
Resets
Fault arming
Isolation

The real vendor is accurate but uncontrollable: shared state, live credentials, and no way to trigger a failure. A mock is controllable but reproduces only what its author encoded.

A twin runs as a real service with its own database, created and destroyed per run.

Measured, not guessed

Every response shape, error code and refusal came from driving the real API. Four examples, none of which appear in the vendor’s own documentation:

  • Stripe returns 404 for a trailing slash. Slack redirects the same trailing slash. Asana ignores it, except on two paths.
  • GitHub refuses a request with no User-Agent before it routes the request or checks your credential.
  • Airtable answers 403 INVALID_PERMISSIONS_OR_MODEL_NOT_FOUND for a record that does not exist, because it will not confirm whether it exists. A malformed id gets a 404.
  • Marqeta returns card declines as 201 Created with a real response code, not as an error.