Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: SMKlog Quote Checkout API
version: 1.4.0
summary: Live parcel rates from a US origin, a checkout handed to a human, and where that checkout stands.
description: 'Live parcel rates from USPS, UPS, FedEx and DHL Express for a single shipment sent from a US origin: inside the US, or to Canada, the UK, Germany or Australia.'
termsOfService: https://smklog.com/terms
contact:
name: SMKlog
email: info@smklog.com
url: https://smklog.com/developers/
x-publisher: SMKlog (SMKLOG-2022 LLC)
servers:
- url: https://quote-api.smklog.com
description: 'Production. There is no sandbox host: quoting is free and read-only, so production is the place to try it.'
security:
- {}
- clientCredentials:
- quote
tags:
- name: Checkout
description: Agent-prepared payment sessions completed by a human on smklog.com.
paths:
/agent/checkout-session:
post:
operationId: createPaymentSession
tags:
- Checkout
summary: Create a payment session for one parcel label (MPP intent "session")
description: 'Prices the shipment live, anchors the amount to one service, and returns a handoff URL opening the SMKlog checkout prefilled with the shipment. The human confirms the contents certification and the carrier-adjustment consent there and pays on Stripe hosted checkout. This operation never charges: the agent prepares, the human pays. Pass the quote_id from getParcelQuote and the session reuses that quote instead of spending a second carrier call.'
x-payment-info:
intent: session
method: stripe
amount: '0'
currency: USD
description: Creating the session is free. The label amount is set by the live quote in the response and paid by the human on Stripe hosted checkout behind the site consent gates; no autonomous charge is possible through this API.
offers:
- intent: session
method: stripe
amount: null
currency: USD
description: Amount is set by the live quote returned in the response; null per the draft means dynamic pricing.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutSessionRequest'
examples:
fromQuote:
summary: Reuse a quote_id (no second carrier call)
value:
quote_id: q_8f3c2e1a4b7d
service: USPS Ground Advantage
fromShipment:
summary: Price live and open checkout in one call
value:
product: Yamaha FG800 acoustic guitar in a hard case
from_zip: '07102'
to_zip: '30303'
to_country: US
quantity: 1
responses:
'200':
description: 'The session: intent, method, amount, currency, service, handoff_url, session_id, note. Keep session_id for getCheckoutStatus.'
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutSession'
example:
intent: session
session_id: as_3f9c1b2e-7d64-4a8e-9c0f-5b2d1e8a7c33
method:
- stripe
- card
amount: 38.42
currency: USD
service: USPS Ground Advantage
handoff_url: https://smklog.com/assets/calculator?product=Yamaha+FG800+acoustic+guitar+in+a+hard+case&from_postal_code=07102&to_postal_code=30303&agent_session=as_3f9c1b2e-7d64-4a8e-9c0f-5b2d1e8a7c33
identified_product_title: Yamaha FG800 acoustic guitar in a hard case
quote_reused: true
note: 'Live quote at this moment, not a hold. The human confirms the shipping consents and pays on the checkout page. Keep session_id: get_checkout_status reports when the human has paid and when the label exists.'
'400':
description: invalid_json or invalid_request — the body is not the documented shape.
content:
application/json:
schema:
$ref: '#/components/schemas/Problem'
example:
error: invalid_request
message: JSON object body required.
'422':
description: session_failed — unpriceable, restricted, not a parcel, or more than one box.
content:
application/json:
schema:
$ref: '#/components/schemas/Problem'
example:
error: session_failed
message: This shipment is past parcel limits; SMKlog sells parcel labels only.
'429':
description: rate_limited. Slow down; the same buckets cover /quote and /mcp (about 80 quote requests an hour per client).
content:
application/json:
schema:
$ref: '#/components/schemas/Problem'
example:
error: rate_limited
message: Too many Smart Quote API requests from this client. Try again later.
/agent/checkout-session/{session_id}:
get:
operationId: getCheckoutStatus
tags:
- Checkout
summary: Read where a payment session stands
description: 'The stage of the checkout a payment session led to: awaiting_checkout, checkout_started, paid, label_ready (with the tracking number), delivered or refunded. Reads SMKlog order records only, no carrier call. Sessions live 30 days; an unknown or expired id answers 404 session_not_found. The answer never carries names, addresses or emails.'
parameters:
- name: session_id
in: path
required: true
schema:
type: string
pattern: ^as_[A-Za-z0-9-]{8,80}$
description: The session_id returned by createPaymentSession.
example: as_3f9c1b2e-7d64-4a8e-9c0f-5b2d1e8a7c33
responses:
'200':
description: session_id, status, created_at, expires_at, amount, currency, service, checkout (order_id, paid, label_ready, carrier, service, tracking_number, tracking_status, estimated_delivery, delivered_at) and next.
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutStatus'
example:
session_id: as_3f9c1b2e-7d64-4a8e-9c0f-5b2d1e8a7c33
status: label_ready
created_at: '2026-10-12T15:04:05.000Z'
expires_at: '2026-11-11T15:04:05.000Z'
amount: 38.42
currency: USD
service: USPS Ground Advantage
quote_reused: true
checkout:
order_id: c1d2e3f4-5a6b-4c7d-8e9f-0a1b2c3d4e5f
started_at: '2026-10-12T15:09:41.000Z'
paid: true
label_ready: true
refunded: false
carrier: USPS
service: Ground Advantage
tracking_number: '9400100000000000000000'
tracking_status: in_transit
estimated_delivery: '2026-10-16'
delivered_at: null
next: Label bought. Pass tracking_number to track_parcel for scan events.
'404':
description: session_not_found — unknown, malformed or expired session_id.
content:
application/json:
schema:
$ref: '#/components/schemas/Problem'
example:
error: session_not_found
message: No payment session with this id. Sessions answer for 30 days.
'429':
description: rate_limited — 60 checks an hour per client.
content:
application/json:
schema:
$ref: '#/components/schemas/Problem'
example:
error: rate_limited
message: Too many Smart Quote API requests from this client. Try again later.
components:
schemas:
Problem:
type: object
description: 'Every error answer on this host: a stable machine-readable code in error, a sentence for the human in message, and the missing field names when the code is missing_required_fields.'
required:
- error
properties:
error:
type: string
description: 'Stable code: invalid_json, invalid_request, missing_required_fields, product_not_recognized, product_url_not_detected, session_failed, session_not_found, rate_limited, invalid_token'
message:
type: string
description: What went wrong, in a sentence
missing:
type: array
items:
type: string
description: Field names still needed, with missing_required_fields and product_not_recognized
CheckoutSessionRequest:
type: object
description: 'The shipment to open a checkout for: a quote_id from a previous quote, or the shipment itself.'
properties:
quote_id:
type: string
description: The quote_id a getParcelQuote answer carries (the get_parcel_quote tool returns the same handle), valid 15 minutes. When given, the shipment comes from that quote and product, from_zip, to_zip, to_country and quantity are ignored; an expired handle prices the fields live.
product:
type: string
maxLength: 2000
description: Required unless quote_id is given.
from_zip:
type: string
pattern: ^[0-9]{5}$
description: 5-digit US ZIP. Required unless quote_id is given.
to_zip:
type: string
maxLength: 12
description: 5-digit US ZIP, or the destination country's own postal code. Required unless quote_id is given.
to_country:
type: string
enum:
- US
- CA
- GB
- DE
- AU
default: US
description: Two-letter destination country
quantity:
type: integer
minimum: 1
default: 1
description: How many of the item ship together. Default 1. Units that fit one box get a session for that box; more than one box, or a quantity above 1 sent with exact dimensions, returns no session — one label per box, so create one session per box.
service:
type: string
description: Optional service to anchor the amount, matched as a case-insensitive fragment of the display name; cheapest when omitted or unmatched.
CheckoutStatus:
type: object
description: The stage of the checkout a session led to, derived from the order record. Never carries names, addresses or emails.
required:
- session_id
- status
properties:
session_id:
type: string
description: The session asked about
status:
type: string
enum:
- awaiting_checkout
- checkout_started
- paid
- label_ready
- delivered
- refunded
description: Stage, in that order
created_at:
type: string
format: date-time
description: When the session was made
expires_at:
type: string
format: date-time
description: When the session stops answering
amount:
type: number
description: The amount the session was anchored to, USD
currency:
type: string
enum:
- USD
description: ISO currency, USD
service:
type: string
description: The service the session was anchored to
quote_reused:
type: boolean
description: Whether the session reused a quote_id
checkout:
type:
- object
- 'null'
description: The checkout the human started, null while awaiting_checkout
properties:
order_id:
type: string
description: SMKlog order id, the reference for support
started_at:
type: string
format: date-time
description: When the checkout was created
paid:
type: boolean
label_ready:
type: boolean
refunded:
type: boolean
carrier:
type:
- string
- 'null'
description: USPS, UPS, FedEx or DHL
service:
type:
- string
- 'null'
description: The service the human actually chose
tracking_number:
type:
- string
- 'null'
description: Present from label_ready on
tracking_status:
type:
- string
- 'null'
description: Latest carrier status when known
estimated_delivery:
type:
- string
- 'null'
description: ISO date when the carrier gives one
delivered_at:
type:
- string
- 'null'
format: date-time
next:
type: string
description: What, if anything, the agent should do now
CheckoutSession:
type: object
description: 'A payment session, not a charge: the amount and the handoff URL where the human pays. The amount is a live quote at this moment, not a hold or a reservation, and no money moves until the human completes the page.'
required:
- intent
- amount
- currency
- handoff_url
properties:
intent:
type: string
enum:
- session
description: Always "session" — this operation never charges
session_id:
type:
- string
- 'null'
pattern: ^as_[A-Za-z0-9-]{8,80}$
description: Handle for getCheckoutStatus, shaped as_ plus a UUID, good for 30 days. Null only when the session record could not be stored.
method:
type: array
items:
type: string
description: Payment rails behind the checkout, e.g. stripe, card
amount:
type: number
description: Live-quoted checkout total for the anchored service, USD
currency:
type: string
enum:
- USD
description: ISO currency, USD
service:
type: string
description: The service the amount is anchored to
handoff_url:
type: string
format: uri
description: Opens the SMKlog checkout prefilled with this shipment
identified_product_title:
type: string
description: What the estimator understood the item to be
quote_reused:
type: boolean
description: True when the amount came from a quote_id you supplied, so no carrier call was spent
note:
type: string
description: 'Standing caveats: live quote, human confirms consents and pays'
securitySchemes:
clientCredentials:
type: oauth2
description: 'Optional. Every operation works without a token. A client that wants its own hourly rate-limit bucket holds OAuth 2.0 client_credentials issued by hand (registration instructions at https://smklog.com/auth.md) and sends the opaque bearer it gets from /oauth/token. Discovery: /.well-known/oauth-authorization-server.'
flows:
clientCredentials:
tokenUrl: https://quote-api.smklog.com/oauth/token
scopes:
quote: Price parcels and prepare checkouts from a dedicated per-client rate-limit bucket
externalDocs:
description: 'Developer portal: docs, schemas, playground, rate limits, status'
url: https://smklog.com/developers/
x-provenance:
method: published
publisher: SMKlog (SMKLOG-2022 LLC)
source: https://quote-api.smklog.com/openapi.json
published: '2026-10-12'
x-mcp:
transport: streamable-http
endpoint: https://quote-api.smklog.com/mcp
serverCard: https://quote-api.smklog.com/.well-known/mcp/server-card.json