---
name: ada-diamonds-commerce
description: Overview of agentic checkout at Ada Diamonds, covering OpenAI Agentic Commerce Protocol (ACP) checkout sessions at https://www.adadiamonds.com/api/acp/checkout_sessions, the ACP product feed, Google Universal Commerce Protocol (UCP) discovery at /.well-known/ucp, sandbox behaviour, and the delegated Stripe SharedPaymentToken needed to complete a live purchase. Use when an agent platform wants to buy from Ada Diamonds programmatically or when you need to explain what a checkout session can and cannot do.
license: MIT
metadata:
  author: Ada Diamonds
  homepage: https://www.adadiamonds.com/developers
  version: "1.0.0"
---

# Agentic checkout at Ada Diamonds

Ada Diamonds implements the two open agentic commerce protocols on top of its existing Stripe and order pipeline. Both reduce to the same flow: create a session from item ids, get an authoritative priced cart, add buyer and shipping details, complete with a payment credential, receive an order id and permalink.

| Protocol | Discovery | Endpoint base | Who calls it |
| --- | --- | --- | --- |
| OpenAI ACP (Agentic Checkout) | `https://www.adadiamonds.com/.well-known/acp.json` | `https://www.adadiamonds.com/api/acp` | ChatGPT and other ACP-speaking agent platforms |
| Google UCP | `https://www.adadiamonds.com/.well-known/ucp` | advertised in the discovery document (`services["dev.ucp.shopping"]`, transport `rest`) | Google AI Mode, Gemini, and other UCP platforms |

Product feed for both: `https://www.adadiamonds.com/feeds/acp-products.jsonl` (one JSON object per line, ACP Product Feed spec fields, same stable item ids as checkout).

## Money

All amounts are US dollars. The ACP and UCP wire formats define their own numeric representation for `amount`, `subtotal`, `tax`, and `total` fields; read `https://www.adadiamonds.com/openapi.json` for the exact type on each field before doing arithmetic, and never assume a checkout total and a catalog `price` share a unit without checking. An engagement ring is a setting item plus a diamond item, priced separately, in checkout as everywhere else on Ada Diamonds.

## ACP checkout sessions

Base: `https://www.adadiamonds.com/api/acp`

| Method | Path | Success |
| --- | --- | --- |
| `POST` | `/checkout_sessions` | 201 with the full cart state |
| `POST` | `/checkout_sessions/{id}` | 200 (update buyer, address, fulfillment choice, items) |
| `GET` | `/checkout_sessions/{id}` | 200 or 404 |
| `POST` | `/checkout_sessions/{id}/complete` | 200 with `status: "completed"` and an `order` |
| `POST` | `/checkout_sessions/{id}/cancel` | 200, or 405 if already completed or canceled |

Headers on every request:

- `Authorization: Bearer <token>`: an Ada API key. Live sessions need a credential carrying the `cart:write` scope (a partner key issued by Ada, or a customer-consented OAuth token). Any sandbox key, including the public `ada_test_public_sandbox_key`, opens sandbox sessions.
- `API-Version` (required; Ada accepts the versions listed in `/.well-known/acp.json`)
- `Idempotency-Key` on every POST (max 255 chars, UUID v4 recommended). Same key with a different body is rejected; same key while the original is in flight returns 409 with `Retry-After`.
- `Content-Type: application/json`, and ideally `Request-Id`, `Accept-Language`, `User-Agent`.

Ada echoes `Idempotency-Key` and `Request-Id` on responses.

### Minimal flow

```bash
# 1. Create a session for a loose diamond
curl -X POST https://www.adadiamonds.com/api/acp/checkout_sessions \
  -H "Authorization: Bearer ada_test_public_sandbox_key" \
  -H "API-Version: 2026-04-17" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"id":"<item_id from the feed>","quantity":1}]}'

# 2. Add the buyer and a shipping address, pick a fulfillment option
curl -X POST https://www.adadiamonds.com/api/acp/checkout_sessions/<id> \
  -H "Authorization: Bearer ada_test_public_sandbox_key" \
  -H "API-Version: 2026-04-17" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"buyer":{"first_name":"Sam","last_name":"Lee","email":"sam@example.com"},"fulfillment_details":{"address":{"line_one":"1 Main St","city":"New York","state":"NY","postal_code":"10017","country":"US"}}}'

# 3. Complete
curl -X POST https://www.adadiamonds.com/api/acp/checkout_sessions/<id>/complete \
  -H "Authorization: Bearer ada_test_public_sandbox_key" \
  -H "API-Version: 2026-04-17" -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"payment_data":{"handler_id":"stripe","instrument":{"credential":{"token":"spt_..."}}}}'
```

Session `status` moves through `not_ready_for_payment`, `ready_for_payment`, `completed`, `canceled` (plus `in_progress` while a payment is processing). Validation problems are reported in `messages[]` with a `code` (`missing`, `invalid`, `out_of_stock`, `payment_declined`, and so on) and a `param` pointing at the field. `requires_buyer_input` plus a `continue_url` means the shopper must finish on the product page (typically a made-to-order ring whose configuration is incomplete).

## Sandbox vs live completion

- **Sandbox** (`ada_test_*` key, including the public one): the whole flow runs against the real catalog, and `complete` returns a completed session and an order **without charging anyone or notifying a jeweler**. Sandbox keys also receive the order webhooks for their sandbox sessions, so a partner can exercise the handler end to end before going live.
- **Live** (`ada_live_*` key with `cart:write`): `complete` requires a delegated payment token issued by the agent platform's payment service provider, a **Stripe SharedPaymentToken** (`spt_...`) scoped to Ada Diamonds' Stripe account and to the session's total. Ada charges it with a PaymentIntent; the order then flows into the same fulfillment pipeline as a website purchase. Ada never receives raw card data from the agent. Without a valid token, `complete` fails with a `messages[]` entry on `payment_data`.

Live traffic from ChatGPT or Google requires Ada to be an approved merchant on that platform, which is a business onboarding step, not something an agent can trigger.

## Made-to-order items

Loose diamonds and ready-to-ship jewelry check out directly. Engagement rings are made to order: the item id must encode the full configuration (setting, metal, ring size, center stone). If it does not, the session reports `messages[].code: "missing"` with a `param` naming the option and a `continue_url` to the configurator. In that case hand the shopper the URL or book a consultation (`POST /api/v1/consultations`, see the `ada-diamonds-api` skill) rather than guessing an option.

## UCP

`GET https://www.adadiamonds.com/.well-known/ucp` returns Ada's business profile: `ucp.version`, `ucp.services["dev.ucp.shopping"]` (REST transport with the checkout endpoint base and the OpenAPI schema URL), `ucp.capabilities` (`dev.ucp.shopping.checkout`, `dev.ucp.shopping.fulfillment`, `dev.ucp.shopping.order`), `ucp.payment_handlers`, and `keys[]` (JWK Set used to verify Ada's signed order webhooks). Every UCP response carries a `ucp` envelope with the negotiated capability intersection. Platforms identify themselves with `UCP-Agent: profile="<their profile URL>"`.

The UCP checkout binding mirrors ACP with different names (`checkout-sessions`, `PUT` for update, `USD` uppercase, `line_items[].totals[]`, `messages[].path`). Read the discovery document and the linked OpenAPI schema; do not transliterate ACP field names by hand.

## Order webhooks

A partner that completes a session receives order events at the webhook URL registered for its API key (write to it@adadiamonds.com to register one):

- `order_create`: once, when a checkout session is completed and an Ada Diamonds order exists for it.
- `order_update`: whenever that order changes state (confirmed, in production, shipped, delivered, canceled) or a refund is recorded.

```
POST https://partner.example.com/webhooks/ada
Content-Type: application/json
Merchant-Signature: <HMAC-SHA256 of the raw body, hex, keyed with the webhook secret>

{ "type": "order_update", "data": { "type": "order", "checkout_session_id": "cs_01J...", "permalink_url": "https://www.adadiamonds.com/orders/AD-2026-000000", "status": "shipped", "refunds": [] } }
```

Verify the signature before trusting a payload, answer 2xx promptly, and treat delivery as at-least-once (key your handling on `checkout_session_id` plus `status`). Failed deliveries are retried with backoff for 24 hours. UCP platforms receive the UCP order webhook instead, signed per RFC 9421 with the key in `keys[]`. Customers can also read their own orders through the `orders:read` OAuth scope.

## Reference

- Developer docs: `https://www.adadiamonds.com/developers/commerce` (markdown for agents at `https://www.adadiamonds.com/developers/commerce/llms.txt`)
- Webhooks: `https://www.adadiamonds.com/developers/webhooks`
- ACP spec: `https://developers.openai.com/commerce` and `github.com/agentic-commerce-protocol/agentic-commerce-protocol`
- UCP spec: `https://ucp.dev`
- Stripe SharedPaymentToken: `https://docs.stripe.com/agentic-commerce`
- Questions: it@adadiamonds.com
