API v1 preview

# Get a quote

`GET /api/v1/quotes/{quote_id}`

## Overview

Retrieve the saved quote and original commercial terms with a current open/expired status. Prices and the 30-minute expiry never change. Unordered quotes become unavailable 30 days after expiry; order-linked quotes are retained. Only the owning account can retrieve a quote.

Requires `quotes:read`.

[Shipping quote guide](https://ottomfg.com/docs/quotes.md)

[Errors and retries](https://ottomfg.com/docs/errors.md)

Request

```
#!/usr/bin/env bash
# Bash + curl. Key needs quotes:read.
set -euo pipefail
: "${API_BASE_URL:?Set your API origin}"
: "${OTTOMFG_API_KEY:?Set your server-side key}"
: "${QUOTE_ID:?Set the quote ID returned by creation}"
curl --fail-with-body --silent --show-error --max-time 30 \
  "${API_BASE_URL%/}/api/v1/quotes/$QUOTE_ID" \
  -H "Authorization: Bearer $OTTOMFG_API_KEY"
# Check status: open/expired is current; prices and expiry stay fixed.
# Unordered quotes remain readable for 30 days after expiry, then return 404.
```

Use quotes:read. Set QUOTE_ID to the returned quote ID; lookup does not refresh prices or expiry.

[Quote setup and examples](https://ottomfg.com/docs/quotes.md)

## Parameters

`quote_id` path · required

Public quote ID returned in id; pass unchanged.

Server-generated public quote ID: quote_ plus 32 lowercase hexadecimal digits representing an opaque random value. Immutable and opaque; not a storage path or content hash.

string

## Responses

Saved quote with manufacturing and shipping totals in USD cents. Tax excluded; no charge is made. Shipping prices in this example are illustrative.

200 response

```
{
  "id": "quote_6c82bd3e319b4bb099310d54a761879e",
  "created_at": "2026-09-17T18:00:00.000000Z",
  "expires_at": "2026-09-17T18:30:00.000000Z",
  "currency": "usd",
  "items": [
    {
      "model_id": "MD-739YQ549",
      "longest_dimension_mm": 100,
      "quantity": 2,
      "dimensions_mm": {
        "x": 100,
        "y": 50,
        "z": 20
      },
      "unit_price": 2460,
      "subtotal": 4920,
      "repair": {
        "required": false,
        "applied": false,
        "reason": null,
        "status": "not_applied",
        "fee": 0,
        "covered_by_order_id": null
      }
    }
  ],
  "shipping_address": {
    "name": "Test Recipient",
    "line1": "123 EXAMPLE ST",
    "city": "SEATTLE",
    "state": "WA",
    "postal_code": "98101",
    "country": "US"
  },
  "buyer": {
    "company": "Example Store",
    "email": "orders@example.com"
  },
  "estimated_production_business_days": {
    "min": 3,
    "max": 3
  },
  "shipping_options": [
    {
      "id": "shipopt_6c82bd3e319b4bb099310d54a761879e",
      "name": "UPS Ground",
      "totals": {
        "subtotal": 4920,
        "shipping": 1000,
        "total": 5920
      },
      "estimated_transit_business_days": {
        "min": 3,
        "max": 3
      },
      "estimated_ship_date": "2026-09-21",
      "estimated_delivery": {
        "earliest": "2026-09-24",
        "latest": "2026-09-24"
      },
      "carrier": "UPS"
    },
    {
      "id": "shipopt_8c1f25d94e3142f8b9a70635d42c81e0",
      "name": "USPS Priority Mail Express",
      "totals": {
        "subtotal": 4920,
        "shipping": 2000,
        "total": 6920
      },
      "estimated_transit_business_days": {
        "min": 1,
        "max": 1
      },
      "estimated_ship_date": "2026-09-21",
      "estimated_delivery": {
        "earliest": "2026-09-22",
        "latest": "2026-09-22"
      },
      "carrier": "USPS"
    }
  ],
  "pricing_version": "pv_20261001_model_repair_01",
  "estimates_valid_until": "2026-09-17T21:00:00.000000Z",
  "status": "open"
}
```

Returns [the Quote object](https://ottomfg.com/docs/quote-object.md).

**Response headers**

`X-Request-ID`

Request identifier for support. Send X-Request-ID with 8–64 ASCII letters, digits or hyphens to reuse that value; otherwise the server generates a UUID4 hex value. Include the returned X-Request-ID in support requests. Do not put secrets or account IDs in this value.

## Errors

| HTTP | Code | What to do |
| --- | --- | --- |
| 401 Unauthorized | `unauthenticated` | The API key is missing, invalid or revoked. Send a valid business API key in Authorization: Bearer. |
| 403 Forbidden | `permission_denied` | The key lacks the endpoint's scope, or payments lack spending consent. Check the scope listed on the endpoint. |
| 404 Not Found | `quote_not_found` | No quote with this ID exists in the account, or it is past retention. Check the ID. |
| 429 Too Many Requests | `resource_exhausted` | A rate or account limit was reached. Wait at least Retry-After seconds, then retry. |
| 500 Internal Server Error | `internal` | The server failed unexpectedly. Retry with backoff; contact support with X-Request-ID if it persists. |
| 503 Service Unavailable | `unavailable` | A required service is briefly unavailable. Retry with backoff, reusing the same Idempotency-Key. |

[Idempotent requests](https://ottomfg.com/docs/idempotency.md)

API v1 preview

Source: https://ottomfg.com/docs/get-quote
