API Quickstart
Run agent sessions programmatically via the REST API. Team-scoped tokens ensure all results are shared with your workspace.
The full machine-readable contract lives at /openapi/v1.yaml (OpenAPI 3.1) — point your client generator or API tooling at it. Tokens carry scoped abilities (shown per endpoint in the spec) and expire; with a team token, write operations additionally require the admin or owner role.
Authentication
The headless API uses Sanctum bearer tokens. Create a team-scoped token from Team Settings > API Tokens, then include it in every request:
Authorization: Bearer your-token-hereTeam tokens scope all queries to the team. Sessions created via a team token are visible to all team members. Personal tokens (created under Settings > API tokens) scope to your individual account only.
Endpoints
Agent Sessions
| Method | Path | Description |
|---|---|---|
GET | /api/v1/models | List available AI models |
POST | /api/v1/chat | Run an agent chat turn |
GET | /api/v1/sessions | List sessions (filterable) |
GET | /api/v1/sessions/{ulid} | Get full session detail |
GET /api/v1/models is the one exception to ability scoping — it requires a valid token but no ability.
Inspector
| Method | Path | Description |
|---|---|---|
POST | /api/v1/inspect/discover | Resolve a domain's UCP manifest (endpoints + capabilities) |
POST | /api/v1/inspect/tools | List an endpoint's MCP tools with a schema-quality grade |
POST | /api/v1/inspect/call | Call one MCP tool by hand and get the raw result |
Targets
| Method | Path | Description |
|---|---|---|
GET | /api/v1/targets | List saved targets |
POST | /api/v1/targets | Save a target (or seed one with from_session) |
GET | /api/v1/targets/{ulid} | Get a target |
PATCH | /api/v1/targets/{ulid} | Update a target |
DELETE | /api/v1/targets/{ulid} | Delete a target |
Collections & Evals
| Method | Path | Description |
|---|---|---|
POST | /api/v1/collections | Create a collection |
GET | /api/v1/collections | List collections |
GET | /api/v1/collections/{ulid} | Get collection detail + recent runs |
PATCH | /api/v1/collections/{ulid} | Update collection config |
DELETE | /api/v1/collections/{ulid} | Delete a collection |
POST | /api/v1/collections/{ulid}/clone | Clone a collection |
POST | /api/v1/collections/{ulid}/run | Trigger an eval run |
GET | /api/v1/collections/{ulid}/runs | List runs for a collection |
GET | /api/v1/collection-runs/{ulid} | Get run status + summary |
GET | /api/v1/collection-runs/{ulid}/pdf | Download PDF report |
Running a Session
Send a domain and message -- the API handles endpoint discovery, the connection, and tool listing automatically:
curl -X POST https://ucpplayground.com/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"domain": "everlane.com",
"message": "Find me a white t-shirt and add it to cart"
}'Multi-Turn Sessions
Pass the session_id from the first response to continue the conversation. The API automatically loads conversation history, reuses the store endpoint, and skips tool re-discovery:
curl -X POST https://ucpplayground.com/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"domain": "everlane.com",
"message": "Add it to my cart in size M",
"session_id": "01KM8HXYXFM3VD8E2RC00TWW5S"
}'Connection
The API connects to the store over UCP's MCP transport when the store declares one, and over REST when it declares only REST. To use REST on a store that offers both, set "use_rest_transport": true. The response's use_rest_transport says which one the turn used.
Runs through the tools a store's own page registers (WebMCP) are not available through the API; they run from the Agent page only. See WebMCP: the store page.
Buyer Context
Catalog searches carry the spec context signals. The saved context for your account or workspace applies automatically; override it per run with buyer_context, or pass {} to send none:
curl -X POST https://ucpplayground.com/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"domain": "everlane.com",
"message": "Find me a white t-shirt",
"buyer_context": { "address_country": "GB", "currency": "GBP", "language": "en-GB" }
}'Whether the merchant honours the hint is the merchant's call; read the tool results to see what came back. The session record keeps the buyer_context it ran with, alongside the negotiation readout of the connect handshake -- both come back on GET /api/v1/sessions/{ulid}, and POST /api/v1/inspect/discover returns the negotiation for any domain without running a session. See the API Reference for the field shapes.
Listing Sessions
Filter by domain, model, or outcome. Results are paginated:
curl -H "Authorization: Bearer $TOKEN" \
"https://ucpplayground.com/api/v1/sessions?domain=everlane.com&outcome=checkout_reached&per_page=10"Running Collections
Collections run multi-turn eval sequences across multiple stores and models. Create one, then trigger runs whenever you need:
# Create a collection
curl -X POST https://ucpplayground.com/api/v1/collections \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Q1 Benchmark",
"config": {
"stores": ["oakywood.shop", "ugmonk.com"],
"models": ["gemini-3-flash", "gemini-3-1-pro"],
"sequences": [{
"name": "browse_and_buy",
"turns": [
{ "message": "Show me two products under $60" },
{ "message": "Add both to my cart" },
{ "message": "Proceed to checkout" }
]
}]
}
}'
# Run it
curl -X POST -H "Authorization: Bearer $TOKEN" \
https://ucpplayground.com/api/v1/collections/{ulid}/run
# Poll for results
curl -H "Authorization: Bearer $TOKEN" \
https://ucpplayground.com/api/v1/collection-runs/{run_id}For more detail on writing sequences and reading reports, see the Evals & Collections help section.
CI/CD Integration
Use collections in your deployment pipeline to catch regressions. Trigger a run, poll until complete, then assert on the checkout rate:
# Trigger run
RUN_ID=$(curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
https://ucpplayground.com/api/v1/collections/$COLLECTION_ID/run \
| jq -r '.run_id')
# Poll until complete (max 5 minutes)
for i in $(seq 1 30); do
STATUS=$(curl -s -H "Authorization: Bearer $TOKEN" \
https://ucpplayground.com/api/v1/collection-runs/$RUN_ID \
| jq -r '.status')
[ "$STATUS" = "complete" ] && break
sleep 10
done
# Check checkout rate
RATE=$(curl -s -H "Authorization: Bearer $TOKEN" \
https://ucpplayground.com/api/v1/collection-runs/$RUN_ID \
| jq '.summary.checkout_rate')
if (( $(echo "$RATE < 80" | bc -l) )); then
echo "Checkout rate $RATE% below 80% threshold"
exit 1
fi