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

Snappy Agents · agents.snappy.com · support@snappy.com