---
title: "Price a run without submitting it"
method: POST
path: "/v1/runs/quote"
tags: ["Runs"]
---

# Price a run without submitting it

`POST /v1/runs/quote`

## Request

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

Validates and prices exactly the run `POST /v1/runs` would create — same engine, same
per-shot rate (including any negotiated org pricing), same shot-range and circuit checks —
and charges nothing. `POST /v1/quote` is the same handler under the path the SDKs called
first; both stay.

## Request body

- RunRequest: The body of `POST /v1/runs` and `POST /v1/runs/quote`, and each item of `POST /v1/runs/batch`.
  - `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`

The price and validity of the run, and whether your balance covers it

- Quote: `POST /v1/runs/quote` — the price of a run, with nothing charged.
  - `machineTargetId` string
  - `machineName` string
  - `shots` integer
  - `perShotMilli` integer: Per-shot price in milli-credits (your org's negotiated rate when one exists; always 0 on a free machine).
  - `costMilli` integer: Total price in milli-credits.
  - `costCredits` number, double: Total price in credits (`costMilli / 1000`) — what `POST /v1/runs` would debit.
  - `free` boolean: The run charges nothing: the machine is free by catalogue policy (RoRo's own simulators) or by the plan of the organization it bills. A free run needs no balance, so `sufficient` is true at any balance whenever `valid` is; a free run can still be refused (`valid` false, with the reason in `validationError`), for example when an institution's daily cloud-simulator allowance is used up.
  - `valid` boolean: False when the run would be rejected (see `validationError`).
  - `validationError` string, nullable: Why the run would be rejected — bad shots, empty or malformed circuit, shots outside the machine's range, or a resilience set this machine does not offer (the same text `POST /v1/runs` answers with).
  - `balanceCredits` number, double: The best single account that could fund the run.
  - `sufficient` boolean: `valid` and the balance covers `costCredits` (always true for a 0-cost run).
  - `effectiveShots` integer: Shot-equivalents priced. On a `per-shot` quote, `costMilli == effectiveShots × perShotMilli`; equal to `shots` for a plain run.
  - `circuits` integer: Circuits in the set (1 for a plain run).
  - `baseCostMilli` integer: What the run costs without resilience.
  - `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[]
  - `preflight` Preflight: The machine fit a quote carries. `state`: `ok`; `warn` (it fits, see `warnings`); `unavailable` (it could not be checked now — the run is checked when it starts, and the price stands).
    - `state` 'ok' | 'warn' | 'unavailable'
    - `qubits` integer, nullable
    - `depth` integer, nullable: Circuit depth — after routing onto the device where the server routes it.
    - `gateCount` integer, nullable
    - `twoQubitGates` integer, nullable
    - `layout` integer[], nullable: Not published today (null).
    - `estimatedSeconds` number, double, nullable: A device-time projection when the service computes one (informational; the price uses the quote's own `estimatedSeconds`).
    - `warnings` string[]
  - `priceModel` 'free' | 'per-shot' | 'per-second' | 'per-job': Which basis priced this quote.
  - `estimatedSeconds` number, double, nullable: On a `per-second` quote, the quantum-seconds the price assumed (billed in whole seconds, rounded up). The charge is this quote's `costMilli`; the provider's own seconds are recorded after the run and never re-billed.
  - `perSecondMilli` integer: Milli-credits per quantum-second (0 on a machine without a time rate).
  - `perJobMilli` integer: Milli-credits added per job (0 when none).
  - `minJobMilli` integer: The least the job costs, in milli-credits (0 when there is no floor). On a `per-second` quote `costMilli = max(minJobMilli, perJobMilli + effectiveShots × perShotMilli + ceil(estimatedSeconds) × perSecondMilli)`.

## Other responses

- `400`: Unknown target, neither `machineTargetId` nor `targetId` given, or a body whose fields have the wrong type (a malformed `resilience` is refused, never ignored — it changes the price)
- `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)
