---
title: "Submit up to 20 independent runs"
method: POST
path: "/v1/runs/batch"
tags: ["Runs"]
---

# Submit up to 20 independent runs

`POST /v1/runs/batch`

## Request

- Base URL: `https://api.roroquantum.com`
- URL: `https://api.roroquantum.com/v1/runs/batch`
- Auth: HTTP bearer

Each item is submitted exactly as `POST /v1/runs` would submit it — validated, priced and
charged on its own. Items are independent: a failure (bad circuit, unknown target, not
enough credits) is reported per item with its HTTP status, and the runs that succeeded are
NOT rolled back. `partial` is true when some, but not all, items failed.

Rate limiting is per item too: every item costs one unit of the same per-minute run budget a
single `POST /v1/runs` costs. When fewer units remain than the batch has items, the items that
fit are submitted and the rest fail on their own with `errorStatus` 429 (`partial` = true);
a batch that arrives with no budget left is refused as a whole with 429, as a single submit
would be.

## Request body

- BatchRunRequest
  - `runs` RunRequest[], required
    - `machineTargetId` string, required: The target's `targetId` (codename). `targetId` below is an accepted alias; send one or the other (both only if they agree).
    - `targetId` string: Alias for `machineTargetId` — same meaning, same value.
    - `shots` integer, required: Also bounded by the machine's own `minShots`..`maxShots` (see properties).
    - `qasm` string, required: OpenQASM 2.0 source for the circuit. A run must carry a circuit: omitting the field is not rejected server-side (the simulators execute a demo Bell circuit and charge for it), which is why every SDK refuses to submit without one.
    - `tags` object, nullable: Optional origin labels for an application submitting on behalf of its own users (opaque ids only, e.g. `{"user": "u_42", "job": "nightly"}`). Stored for the operator view, never billed on, never used for authorisation, and never echoed back — a run's `tags` cannot be read from the API. Invalid entries are dropped, not rejected; a label can never fail a paid run.
    - `resilience` Resilience: Error mitigation requested for a run. `level` is sugar — `1` = `{readout: true}`, `2` = `{readout: true, zne: {scales: [1,3,5], extrapolator: linear}}` — and explicit fields override it. Level 1 is TENSORED per-qubit readout mitigation (not TREX); level 2 adds zero-noise extrapolation by global unitary folding. A request a machine does not offer is refused (quote `validationError` == submit 400, byte for byte). Unknown fields are refused with a 400, not ignored: a misspelled field would silently change the price.
      - `level` 0 | 1 | 2
      - `readout` boolean: Two calibration circuits (all-zero and all-one) measured in the same run, on the same classical bits.
      - `zne` Zne: Zero-noise extrapolation. Each scale k runs the circuit folded to k× its length and is billed k×. Unknown fields are refused with a 400.
        - `scales` integer[]: Odd, strictly increasing, starting at 1, each at most 7.
        - `extrapolator` 'linear' | 'richardson': `richardson` only with an `observable`.
        - `observable` string, nullable: A Z/I string; its rightmost character is the rightmost character of a counts key; a Z on a classical bit the circuit never measures is refused. Null → histogram mode (a heuristic, extrapolated outcome by outcome).
      - `dd` string, nullable: Provider-executed dynamical decoupling. Not offered on any machine yet — refused with the machine's reason.
      - `twirling` boolean: Provider-executed twirling. Not offered on any machine yet — refused with the machine's reason.

## Response `200`

One result per item, in order

- BatchRunResponse
  - `results` BatchRunItem[]
    - `index` integer
    - `ok` boolean
    - `run` Run
      - `id` string
      - `machineTargetId` string: The target's codename.
      - `machineName` string: Friendly display name of the target.
      - `shots` integer
      - `status` 'queued' | 'running' | 'completed' | 'failed' | 'cancelled'
      - `cost` number, double: Credits charged for this run.
      - `counts` object, nullable: Measured bitstring counts (present when completed).
      - `probabilities` object, nullable: Normalized probabilities per bitstring (present when completed).
      - `error` string, nullable: Failure reason (present when status is failed).
      - `createdAt` string, date-time
      - `qasm` string, nullable: The submitted OpenQASM 2.0 source.
      - `providerJobId` string, nullable: Upstream provider job id
      - `providerStatus` string, nullable: Live raw provider status while running (e.g. 'Running'); null for instant simulator runs.
      - `queuePosition` integer, nullable: Jobs ahead on the backend while queued; null for instant simulator runs.
      - `refundable` boolean: True when a failed, charged run has a machine-side error — you may `POST /v1/runs/{id}/refund`.
      - `refundStatus` 'pending' | 'approved' | 'rejected', nullable: The refund audit trail: null (no refund involved), `pending` (requested), `approved` (credited — automatic refunds appear here), `rejected`.
      - `notebookId` string, nullable: Set when the run was submitted from a console notebook.
      - `labProjectId` string, nullable: Set when the run was submitted from a lab project.
      - `countsProvenance` 'measured' | 'provider-corrected', nullable: Where `counts` came from: `measured` as read out, or `provider-corrected` (the provider already applied its own readout correction). Null for runs that predate the label — read them as received.
      - `effectiveShots` integer, nullable: Shot-equivalents billed — equal to `shots` for a plain run.
      - `resilience` ResilienceInfo: The resolved, expanded set a quote priced and a run was charged for, with its settled outcome.
        - `readout` boolean
        - `calibrationShots` integer: Shots per calibration circuit (0 without readout).
        - `zneScales` integer[], nullable
        - `zneExtrapolator` string, nullable
        - `zneObservable` string, nullable
        - `zneMode` 'histogram-heuristic' | 'observable', nullable
        - `dd` string, nullable
        - `twirling` boolean
        - `circuits` integer: 1 + 2·readout + (scales − 1).
        - `effectiveShots` integer: shots × Σscales + 2 × calibrationShots.
        - `baseCostMilli` integer: What the same run would cost with no resilience.
        - `resilienceCostMilli` integer: The extra, in milli-credits.
        - `calibrationSource` 'measured-this-run', nullable: On a simulator the calibration measures the family model's readout rate, not a device.
        - `transpiledToNoiseBasis` boolean, nullable: Simulators: the whole set was translated to the noise basis. Null on hardware.
        - `projectedSeconds` number, nullable: Simulators: projected wall time from the measured throughput. Null on hardware.
        - `status` 'planned' | 'applied' | 'partially-applied' | 'zne-measured-not-extrapolated' | 'readout-measured-not-applied' | 'not-applied-refunded': `zne-measured-not-extrapolated` / `readout-measured-not-applied`: the circuits ran and are charged, the estimate was skipped (see notes). `partially-applied` / `not-applied-refunded`: circuits that did not run were refunded (`refundedMilli`).
        - `refundedMilli` integer: Milli-credits returned for circuits of the set that did not run.
        - `notes` string[]
      - `mitigated` Mitigated: The DERIVED distribution and how it was derived. `counts` on the run are never altered.
        - `probabilities` object, nullable
        - `method` 'readout' | 'zne' | 'readout+zne', nullable: `readout+zne`: each scale's counts are readout-corrected, then extrapolated.
        - `negativityClipped` number, nullable: Probability mass clipped below zero by the inversion.
        - `calibration` Calibration, nullable: Readout error rates measured in this run. Index i is the i-th character from the RIGHT of a counts key.
          - `source` 'measured-this-run', nullable
          - `shots` integer, nullable
          - `bits` integer, nullable
          - `qubits` integer[]
          - `p01` number[]: P(read 1 | prepared 0) per bit.
          - `p10` number[]: P(read 0 | prepared 1) per bit.
        - `zne` ZneResult, nullable
          - `scales` integer[]
          - `extrapolator` string, nullable
          - `mode` 'histogram-heuristic' | 'observable', nullable
          - `observable` string, nullable
          - `values` number[], nullable: Observable mode: ⟨O⟩ per scale.
          - `stderrs` number[], nullable
          - `extrapolated` number, nullable: Null when the extrapolation was skipped.
          - `tvdToScale1` number[], nullable
          - `shotNoiseTvd` number, nullable
          - `foldGateRatio` number[], nullable
        - `warnings` string[]
      - `resilienceDetail` ResilienceDetail: Raw histograms behind `mitigated` — only on `GET /v1/runs/{id}` and the stream's `done` frame; null in lists and on `POST` responses.
        - `calibration` object, nullable
          - `zeroStateCounts` object, nullable
          - `oneStateCounts` object, nullable
        - `zne` object, nullable
          - `perScaleCounts` object[]: One histogram per scale, in `zneScales` order, never readout-corrected.
    - `error` string, nullable: Why this item failed (when not `ok`).
    - `errorStatus` integer, nullable: The HTTP status `POST /v1/runs` would have returned for this item (400, 402, 429, …).
  - `submitted` integer: Items that became runs.
  - `failed` integer: Items that did not.
  - `partial` boolean: True when some, but not all, items failed — the successes stay submitted and charged.

## Other responses

- `400`: The batch is empty or has more than 20 items
- `401`: Missing or invalid API key

---

[API](https://skmtc.dev/roroquantum/apis/roro-quantum-api.md) · [All operations](https://skmtc.dev/roroquantum/apis/roro-quantum-api/llms.txt) · [OpenAPI document](https://skmtc.dev/roroquantum/apis/roro-quantum-api/revisions/d6e194352018?raw)
