Skip to main content
A Simulator is an immutable implementation of one API, built from an OpenAPI, WSDL or GraphQL document. Every Simulation runs one Simulator.

When to use one

Use a catalog Simulator when the Continuous catalog already serves the API you need. Build your own when it does not, or when you need a filtered set of operations or your own build instructions.

Lifecycle

A build starts in pending, becomes building when a slot is free, and ends in ready, failed, or canceled. Only a ready Simulator can start a Simulation, join a World, or serve as the base of an incremental build. Every build has an immutable smr_ ID from the moment POST /v1/simulators accepts it; the 202 response carries the Simulator in pending. A ready Simulator’s behavior never changes; a behavior change is a new build with a new ID. A name is a label. It need not be unique, it never identifies a Simulator, and no operation looks a Simulator up by name. A build that names parent_id creates a new Simulator with its own ID; its parent_id points at the Simulator it was built from. A failed or canceled build carries diagnostics in error. See resource errors for recovery guidance and the generated Simulator schema for its fields.

Build a Simulator

Send an OpenAPI, WSDL or GraphQL document with build instructions. An OpenAPI document can be Swagger 2.0, OpenAPI 3.0, or OpenAPI 3.1. The build converts Swagger 2.0 to OpenAPI 3.0 and keeps the converted document as the Simulator’s spec. A GraphQL document is SDL, sent with spec_kind graphql, or an introspection result that includes deprecated input fields and arguments, which the build converts to SDL. Worlds do not take GraphQL Simulators yet. The generated build endpoint owns the multipart shape, model choices, field constraints, and defaults. Quotas and limits owns queue behavior, request-size limits, and the build budget.

Correct the specification

A vendor document can omit behavior that the vendor documents elsewhere or that its SDKs rely on. The builder follows the document, so omitted behavior cannot be built. To correct it, add a top-level x-continuous-corrections list to the OpenAPI document. Each entry names one operation by its operationId (a widenResponse of a component schema names none), makes exactly one change, and cites evidence with an http(s) source URL and a quote from that source:
  • addMethods also serves the operation under the listed methods: get, post, put, patch, or delete. A request on an added method can send the operation’s query arguments in a form or JSON body. It applies only to an operation without a request body, and the path must not already declare the method.
  • widenInput makes the input name also accept schema. A name that starts with / is a JSON pointer to a nested body property, such as /profile/email, and can pass through $ref. Values the document already accepts stay valid.
  • addInput declares an optional input the document omits: name, schema, and in, which is body (the default), query, or header. The input must not already exist.
  • serializeInput sets how the array query input name is encoded: style is form, and explode is false for one comma-separated value, such as ids=1,2, or true for the input repeated.
  • widenResponse widens the component schema schema, wherever the document references it, or, with operation, that operation’s inline response schemas. An optional field names a property inside it by a dot-separated path that steps through arrays; the path cannot pass through a $ref, so widen a referenced schema by name. It can add a pattern, which the value may match instead of the declared one; add enum values; or set nullable to true. The schema must already declare the pattern or enum it widens. Values the document already accepts stay valid, and nothing is removed.
  • addResponse declares a status the vendor documents for the operation and the document omits, such as 412. An optional schema names the component schema its JSON body meets; without it, the response has no body. The operation must not already declare the status, and the evidence quote becomes the response’s description.
The build applies the corrections when it accepts the request and keeps the corrected document as the Simulator’s spec. Each corrected operation records its corrections, which the build model lists; a widened schema records its own. Everything else keeps the document’s validation. The build answers 422 with the correction issue code when an entry names no operation in the document, sets zero or several changes, lacks evidence, or cannot apply as described. It also answers 422 when an operation or schema already carries x-continuous-corrections; declare every correction in the top-level list. For an incremental build, omit spec and send parent_id and instructions. filter and spec_kind are not allowed. The parent must be ready; otherwise the build answers 409 simulator_not_ready. The build runs asynchronously. Read the Simulator with GET /v1/simulators/{id} until its status is terminal. Set CONTINUOUS_API_KEY to your API key, or run continuous auth login for the CLI. Save your API document as openapi.yaml, then run:

Let the build call a live system

When you have a tenant on the real system, such as a sandbox or test-mode account, the builder and QA can call it to see how it really behaves. Create a credential with POST /v1/credentials: a base_url, the header that carries the credential (default Authorization), and the header value, such as Bearer sk_test_…. The API never returns the value. Then list up to 5 credential IDs in the build’s credential_ids. A credential can instead hold a login for the vendor’s web app: its sign-in url, the username, and any further hosts the app loads from, with the password as the value. Only an App build uses a login credential. The pinned spec still defines the operations. What the agents observe on the live system ranks above public documentation as evidence of how they behave. The builder sends only GET, HEAD, and OPTIONS requests to a system with a header credential, the reviewer never calls it, and QA also writes to it and deletes what it creates; none of this is enforced, so use a test tenant. The value is available inside the build sandbox and to the model provider. Exchanges the builder relies on are saved with the value removed, and a build refuses to publish a Simulator whose files contain it.

Build the vendor’s web app

A build with mode web_app simulates the vendor’s logged-in web app and the private API behind it, instead of its public API. It takes no spec, spec_kind or filter, and needs exactly one Web App login credential in credential_ids. Its first stage, Discovery, signs in with that credential and captures the app’s screens and the calls it makes, which become the build’s recorded spec. Discovery, the builder, and QA also create, edit, upload, and delete records in the live app through its screens, each named with the build’s prefix, and delete through the app what they create, so use a test account. The builder then builds the app and its private API, and every journey Discovery captured must run on it as it ran on the vendor’s app. The Simulator serves no sign-in page: every visitor acts as the login’s account. A Web App Simulator reports spec_kind recorded, its operations are the calls each journey step made, and Worlds do not take Web App Simulators yet. With parent_id and instructions, a Web App build starts from a ready Web App Simulator and its captures instead of running Discovery; an incremental build always has its parent’s mode. A Web App build runs on a Claude model or combined. A Web App Simulation serves the app and its private API at a host of its own, {simulation}.continuouslabs.app, a domain apart from the console’s, with live’s paths and cookies. The host is open to anyone with its URL, with no sign-in; the console’s Open app button opens it. Its endpoint under /sim/{id}/ refuses it.

Give the build documentation

When you hold the vendor’s documentation, including pages behind a sign-in, attach it to the build as repeated document file parts. The builder and every reviewer read it before they start and can cite it as evidence; they still research the vendor’s public pages. It ranks below a live system and above public documentation. The build endpoint’s reference lists the accepted formats; the documents share the request body limit in Quotas and limits with the spec. Each document gets a safe, unique file name. The documents are available inside the build sandbox and to the model provider. An incremental build inherits its parent’s documents and index; a document you attach with the same name replaces the parent’s, and research extends the index.

Catalog Simulators

source is workspace for a Simulator your workspace built and catalog for a read-only Simulator that Continuous publishes. Catalog Simulators are readable from every workspace. You can use one as simulator_id, in a World, and as parent_id. To find a catalog Simulator, list ready Simulators and read the id of the entry whose source is catalog. Every reference uses the smr_ ID. A catalog Simulator cannot be deleted (403 auth_forbidden), and only the owning workspace can cancel a build.

Manage a Simulator

Cancel requests cancellation of a pending or active build. A build can finish before cancellation takes effect; canceling a settled build returns its current state. Delete succeeds only when no Worlds, Simulations, or child Simulators depend on it. Use the API reference for routes, filters, and response schemas.

Clone a Simulator into another workspace

POST /v1/simulators/{id}/clone copies a ready Simulator from your workspace into another workspace, such as from development to staging. The source is the API key’s workspace, or X-Workspace-Id for a browser session, and the body names the target. The clone is a new ready Simulator with its own smr_ ID, the source’s image digest, and the source’s name and instructions unless you set name. It has no parent, and the source and its Simulations are unchanged. Retrying with the same idempotency_key and target returns the same clone; reusing the key for a different source or name returns 409 simulator_import_conflict. An API key can clone into any other workspace of its organization. Cloning into another organization’s workspace is refused. Catalog Simulators cannot be cloned.

Simulations

Run a ready Simulator with isolated state.

Worlds

Build a World from ready Simulators. Starting it creates their Simulations.