API Quickstart
Automate

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-here
Note

Team 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

MethodPathDescription
GET/api/v1/modelsList available AI models
POST/api/v1/chatRun an agent chat turn
GET/api/v1/sessionsList 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

MethodPathDescription
POST/api/v1/inspect/discoverResolve a domain's UCP manifest (endpoints + capabilities)
POST/api/v1/inspect/toolsList an endpoint's MCP tools with a schema-quality grade
POST/api/v1/inspect/callCall one MCP tool by hand and get the raw result

Targets

MethodPathDescription
GET/api/v1/targetsList saved targets
POST/api/v1/targetsSave 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

MethodPathDescription
POST/api/v1/collectionsCreate a collection
GET/api/v1/collectionsList 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}/cloneClone a collection
POST/api/v1/collections/{ulid}/runTrigger an eval run
GET/api/v1/collections/{ulid}/runsList runs for a collection
GET/api/v1/collection-runs/{ulid}Get run status + summary
GET/api/v1/collection-runs/{ulid}/pdfDownload 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