---
title: "Create immutable quote (verified renter)"
method: POST
path: "/api/v1/quotes"
tags: ["jobs"]
---

# Create immutable quote (verified renter)

`POST /api/v1/quotes`

## Request

- Base URL: `https://amplerun-api.spiry.org`
- URL: `https://amplerun-api.spiry.org/api/v1/quotes`
- Auth: HTTP bearer

Returns an immutable quote with 60s expiry, terms version, machine manifest hash and total rate. Refresh stale catalog quotes before charging. Quoting is free and holds nothing; POST /api/v1/jobs reserves. The Idempotency-Key is not deduplicated on this route, so a retry returns a fresh quote. 409 CONFLICT when the offer's machine is not admitted: an unverified listing (OfferSummary admitted false) is shown but cannot be quoted or reserved until it passes qualification.

## Headers

- `Idempotency-Key` string, uuid, required

## Request body

- object: Exactly one of template_id, image_digest or image_ref (422 otherwise). With template_id the server resolves the published template's pinned image_digest and requires the offer to fit (422). An image_ref, or an image_digest no published template pins, is a custom image: it is accepted only while the marketplace enables custom images (422 otherwise), is resolved anonymously against an allowed public registry (docker.io, ghcr.io, quay.io, nvcr.io, public.ecr.aws) and quoted by its digest (422 when private, missing, not linux/amd64 or over the size cap), and only on a machine whose host opted in (422).
  - `offer_id` string, uuid, required
  - `image_digest` string
  - `image_ref` string: Custom public image by tag or digest ([registry/]repository[:tag][@sha256:...]); the server pins it to a digest at quote time.
  - `duration_limit_s` integer, required: Maximum runtime in seconds, metered from verified readiness.
  - `budget_micro` string, required: Unsigned base-10 integer as string; never a float.
  - `template_id` string, uuid
  - `asset` 'USDC' | 'USDT': Additive. Settlement asset whose balance the reservation holds; unknown values are 422.

## Response `201`

Immutable quote.

- Quote
  - `quote_id` string, uuid, required
  - `expires_at` string, date-time, required
  - `machine_id` string, uuid, required
  - `gpu_count` integer, required
  - `machine_rate_micro_per_hour` string, required: Unsigned base-10 integer as string; never a float.
  - `platform_fee_bps` integer, required
  - `budget_micro` string, required: Unsigned base-10 integer as string; never a float.
  - `duration_limit_s` integer, required
  - `included_disk_gib` integer
  - `included_egress_gib` integer
  - `manifest_hash` string, required
  - `image_digest` string, required
  - `terms_version` string, required
  - `meter_start` 'verified_ready', required
  - `template_id` string, uuid
  - `image_ref` string: Echoed when the request named a custom image by image_ref; image_digest is what it was pinned to.
  - `estimated_total_micro` string: Unsigned base-10 integer as string; never a float.
  - `asset` 'USDC' | 'USDT': Additive. Settlement asset whose balance the reservation holds; USDC unless the request chose USDT.
  - `availability_class` 'dedicated' | 'interruptible': D-22. dedicated (the default) is never preempted. interruptible is sold only from idle or co-listed hosts: the host may take the machine back after preemption_notice_s seconds of notice, and billing stops at the notice.
  - `preemption_notice_s` integer, nullable: D-22. Notice in seconds before an interruptible rental is stopped; null for dedicated.
  - `interruption_estimate` InterruptionEstimate: D-22, interruptible offers only. Plain observed counts, never a prediction. A run is one continuous period in which the host reported the machine offerable (from heartbeats); it counts when it ended, or has already lasted horizon_h. uninterrupted is null below the sample gate (20 runs): not enough history.
    - `runs` integer, required: Most recent decided runs counted (at most 40).
    - `uninterrupted` integer, nullable, required: Of those runs, how many lasted horizon_h without interruption; null below the sample gate.
    - `horizon_h` integer, required
    - `computed_at` string, date-time, required
    - `summary` string, required: The counts in words, e.g. "34 of the last 40 runs lasted 4 h without interruption" or "Not enough history (12 runs so far)".

## Other responses

- `default`: Error envelope. 401 unauthenticated, 403/404 forbidden, 409 conflict, 422 invalid input, 429 rate limited (code UNAVAILABLE, retryable:true, no Retry-After header), 503 unavailable money/provider state with retryable:true.

---

[API](https://skmtc.dev/amplerun/apis/amplerun-business-api.md) · [All operations](https://skmtc.dev/amplerun/apis/amplerun-business-api/llms.txt) · [OpenAPI document](https://skmtc.dev/amplerun/apis/amplerun-business-api/revisions/40944687fa52?raw)
