Quickstart for agent developers
Base URLs: sandbox https://sandbox.agents.snappy.com, production https://agents.snappy.com. Everything below uses $BASE.
1. Discover
curl $BASE/.well-known/snappy-agents.json # connector manifest
curl $BASE/.well-known/oauth-authorization-server # RFC 8414
curl $BASE/.well-known/oauth-protected-resource # RFC 9728
curl $BASE/openapi.json # OpenAPI 3.1
2. Register your client (once)
curl -X POST $BASE/oauth/register -H 'content-type: application/json' -d '{
"client_name": "My Agent",
"redirect_uris": ["https://my-agent.example/oauth/callback"],
"scope": "profile catalog:read orders:read orders:write offline_access"
}'
Public clients (PKCE only) are the default. Pass "token_endpoint_auth_method": "client_secret_post" to receive a secret for server-side agents.
3. Send the user through OAuth
Authorization code + PKCE (S256 only). The hosted page signs the user in with an email code or Google and shows a consent screen with a read-only switch.
GET $BASE/oauth/authorize?response_type=code&client_id=…&redirect_uri=…
&scope=profile%20catalog:read%20orders:read%20orders:write%20offline_access
&state=…&code_challenge=…&code_challenge_method=S256
Exchange the code at POST $BASE/oauth/token (application/x-www-form-urlencoded). Refresh tokens rotate on every use.
4. Shop
H="authorization: Bearer $TOKEN"
curl -H "$H" "$BASE/v1/search?q=coffee&budget=under%20%2450"
curl -H "$H" "$BASE/v1/products/$PRODUCT_ID"
curl -H "$H" "$BASE/v1/variants/$VARIANT_ID/availability?countries=US,CA"
availability[].price is the exact amount the user will be charged.
5. Quote each item, confirm, check out the cart
curl -H "$H" -X POST $BASE/v1/quotes -d '{"variantId":"'$VARIANT_ID'"}'
# -> { id: "qt_…", totalDisplay: "$24.99", expiresAt: … } (one quote per cart line; show the totals to the user)
curl -H "$H" -X POST $BASE/v1/checkouts -d '{
"items": [ { "quoteId": "qt_aaa", "quantity": 2 }, { "quoteId": "qt_bbb" } ],
"recipient": { "firstName": "Dana", "lastName": "Levi", "email": "dana@example.com", "phone": "+15551234567" },
"shippingAddress": { "address1": "123 Main St", "city": "New York", "provinceCode": "NY", "postalCode": "10001", "countryCode": "US" },
"notify": { "email": "buyer@example.com", "sms": "+15550001111" }, "smsConsent": true
}'
# -> { id: "chk_…", status: "pending_payment", items: [...], paymentUrl: "https://checkout.stripe.com/…", statusUrl, eventsUrl, nextStep }
smsConsent may only be true after the user agreed to the consent text (returned by the error sms_consent_required). Snappy places one order per item once the single payment clears.
Hand paymentUrl to the user. Never ask for card details.
6. Confirm in real time
Either poll statusUrl every few seconds, open eventsUrl (Server-Sent Events), or pass callbackUrl on the checkout to receive a signed POST. Terminal states: confirmed (all items placed, orderIds), partially_confirmed (some items refunded automatically, see items[].failureReason), failed/refunded, expired, cancelled.
7. After the sale
curl -H "$H" $BASE/v1/orders/$ORDER_ID # stage, tracking, nextActions
curl -H "$H" -X POST $BASE/v1/checkouts/$CHECKOUT_ID/receipt -d '{"channel":"email"}' # whole purchase
curl -H "$H" -X POST $BASE/v1/orders/$ORDER_ID/cancel # while nextActions has "cancel": refunds that item
curl -H "$H" -X POST $BASE/v1/orders/$ORDER_ID/support-requests -d '{"type":"damaged","summary":"Arrived dented","preferredResolution":"refund"}' # once shipped
Conversation tips that make users happy
- Shipping is US-only today; say so early if the user mentions another country.
- When a product has one variant,
defaultVariantIdis set: skip the variant question. - Let users build a cart: quote each item, then one checkout. Read back items, total, recipient and address before creating it.
- Use
/v1/addresses/validatewhile collecting the address; surfacesuggestionsonaddress_unverified. - Offer the receipt by email or SMS once confirmed; for SMS, read the consent text and only then send
smsConsent: true. - Use
nextActionson an order to decide betweencancelandrequest_support; never guess. - On
country_not_supported/variant_unavailable_in_country, offer the listed alternatives, not an apology.