Get shipping quote
Shipping
Get shipping quote
Returns shipping cost and ETA estimates for one or more items to a given destination.
POST
Get shipping quote
Returns carrier rates and ETAs for shipping one or more items to a destination. Use this to display shipping options before the user commits.
When Google can suggest a corrected address, it’s returned under
Where
No payment is required. Quotes are informational and shipping fees are settled B2B with the partner.
Request body
Item identifiers from
/api/v1/vm/buy/status (nfts[].id) or /api/v1/inventory/:user_id (items[].id).Shipping address.
Example request
Response
Quote session identifier (groups the returned
quotes[]).ISO timestamp after which all quotes in this session are no longer valid.
Rate identifier. Pass as
quote_id in /api/v1/ship/request.Shipping carrier (for example
USPS, FedEx).Carrier service level (for example
Priority Mail, 2Day).Shipping cost in USD. Billed B2B to the partner.
ETA in business days (lower bound).
ETA in business days (upper bound).
Whether the rate includes carrier insurance.
Errors
| Status | Body | Cause |
|---|---|---|
400 | { "error": "item_ids is required" } | Missing or empty item_ids |
400 | { "error": "Invalid destination address", "details": "...", "suggested": { ... } } | Address validation failed. The body includes a human-readable details string and, when available, a suggested normalized address object (Google’s correction). See Address validation below. |
400 | { "error": "Item not found" } | One or more item_ids are unknown or not owned by this partner’s user |
400 | { "error": "No shippable items in request" } | All items are non-shippable |
422 | { "error": "Country not supported" } | Production: destination country is not currently serviced. Sandbox: the country field is not a 2-character string. The sandbox does not check against an actual country allow-list, so any 2-character value (including "ZZ") is accepted. |
500 | { "error": "Failed to fetch shipping rates" } | Carrier rate lookup failed |
Address validation
Destinations submitted to/ship/quote are validated server-side via the Google Address Validation API before any rate lookup runs. The validator runs against both production and sandbox.
Pass criteria:
- Required fields are present and non-empty:
name,line1,city,country. countryis exactly 2 characters (ISO 3166-1 alpha-2).- Google returns
validationGranularityofPREMISEorSUB_PREMISE.PREMISE_PROXIMITYis rejected — it indicates Google is uncertain about the exact location, which carriers misroute or refuse for graded-card-grade shipments. - No address components are flagged as
unconfirmed.
400
suggested so the partner can prompt the end user to confirm. suggested may be absent when validation fails on a structural check (e.g. missing name).
Outage behavior: if the Google API is unreachable or returns a non-2xx response, /ship/quote fails closed with 400 { "error": "Invalid destination address", "details": "Validation failed: internal error" }. Same behavior applies if GOOGLE_MAPS_API_KEY is not configured server-side. Address validation is a hard dependency of /ship/quote — partners should retry with backoff on this specific details value rather than treat the address as invalid.
Sandbox notes
In sandbox, everyship/quote call returns exactly three rates in this order:
| Service | Carrier | Insured | Days | Amount formula (USD) |
|---|---|---|---|---|
| Ground Advantage | USPS | no | 3–5 | 5.95 + (n − 1) × 1.50 |
| Priority Mail | USPS | yes | 1–3 | 9.75 + (n − 1) × 2.00 |
| 2Day | FedEx | yes | 2–2 | 18.50 + (n − 1) × 3.00 |
n = item_ids.length. Quotes expire 15 minutes after issuance.
Sandbox session_id format: quote_<16-char uppercase base64url>. Quote IDs follow ${session_id}_rate_${"standard"|"priority"|"express"}.