Skip to content

Cart Capability - REST Binding

This document specifies the REST binding for the Cart Capability.

Businesses advertise REST transport availability through their UCP profile at /.well-known/ucp.

{
"ucp": {
"version": "2026-01-11",
"services": {
"dev.ucp.shopping": {
"version": "2026-01-11",
"spec": "https://ucp.dev/2026-01-11/specification/overview",
"rest": {
"schema": "https://ucp.dev/2026-01-11/services/shopping/rest.openapi.json",
"endpoint": "https://business.example.com/ucp/v1"
}
}
},
"capabilities": [
{
"name": "dev.ucp.shopping.checkout",
"version": "2026-01-11"
},
{
"name": "dev.ucp.shopping.cart",
"version": "2026-01-11"
}
]
}
}

All UCP REST endpoints are relative to the business’s base URL, which is discovered through the UCP profile at /.well-known/ucp. The endpoint for the cart capability is defined in the rest.endpoint field of the business profile.

  • Request: application/json
  • Response: application/json

All request and response bodies MUST be valid JSON as specified in RFC 8259.

All REST endpoints MUST be served over HTTPS with minimum TLS version 1.3.

OperationMethodEndpointDescription
Create CartPOST/cartsCreate a cart session.
Get CartGET/carts/{id}Get a cart session.
Update CartPUT/carts/{id}Update a cart session.
Cancel CartPOST/carts/{id}/cancelCancel a cart session.

=== “Request”

```json
POST /carts HTTP/1.1
UCP-Agent: profile="https://platform.example/profile"
Content-Type: application/json
{
"line_items": [
{
"item": {
"id": "item_123"
},
"quantity": 2
}
],
"context": {
"address_country": "US",
"address_region": "CA",
"postal_code": "94105"
}
}
```

=== “Response”

```json
HTTP/1.1 201 Created
Content-Type: application/json
{
"ucp": {
"version": "2026-01-11",
"capabilities": [
{"name": "dev.ucp.shopping.checkout", "version": "2026-01-11"},
{"name": "dev.ucp.shopping.cart", "version": "2026-01-11"}
]
},
"id": "cart_abc123",
"line_items": [
{
"id": "li_1",
"item": {
"id": "item_123",
"title": "Red T-Shirt",
"price": 2500
},
"quantity": 2,
"totals": [
{"type": "subtotal", "amount": 5000},
{"type": "total", "amount": 5000}
]
}
],
"currency": "USD",
"totals": [
{"type": "subtotal", "amount": 5000},
{"type": "total", "amount": 5000, "display_text": "Estimated total (taxes calculated at checkout)"}
],
"continue_url": "https://business.example.com/checkout?cart=cart_abc123",
"expires_at": "2026-01-16T12:00:00Z"
}
```

=== “Error Response”

All items out of stock — no cart resource is created:
```json
HTTP/1.1 200 OK
Content-Type: application/json
{
"ucp": { "version": "2026-01-11", "status": "error" },
"messages": [
{
"type": "error",
"code": "out_of_stock",
"content": "All requested items are currently out of stock",
"severity": "unrecoverable"
}
],
"continue_url": "https://merchant.com/"
}
```

=== “Request”

```json
GET /carts/{id} HTTP/1.1
UCP-Agent: profile="https://platform.example/profile"
```

=== “Not Found”

```json
HTTP/1.1 200 OK
Content-Type: application/json
{
"ucp": {
"version": "2026-01-11",
"status": "error",
"capabilities": [
{"name": "dev.ucp.shopping.cart", "version": "2026-01-11"}
]
},
"messages": [
{
"type": "error",
"code": "not_found",
"content": "Cart not found or has expired",
"severity": "unrecoverable"
}
],
"continue_url": "https://merchant.com/"
}
```

=== “Request”

```json
PUT /carts/{id} HTTP/1.1
UCP-Agent: profile="https://platform.example/profile"
Content-Type: application/json
{
"id": "cart_abc123",
"line_items": [
{
"item": {"id": "item_123"},
"id": "li_1",
"quantity": 3
},
{
"item": {"id": "item_456"},
"id": "li_2",
"quantity": 1
}
],
"context": {
"address_country": "US",
"address_region": "CA",
"postal_code": "94105"
}
}
```

=== “Request”

```json
POST /carts/{id}/cancel HTTP/1.1
UCP-Agent: profile="https://platform.example/profile"
Content-Type: application/json
{}
```
  • UCP-Agent: All requests MUST include the UCP-Agent header containing the platform profile URI using Dictionary Structured Field syntax (RFC 8941). Format: profile="https://platform.example/profile".
  • Idempotency-Key: Operations that modify state SHOULD support idempotency. When provided, the server MUST:
    1. Store the key with the operation result for at least 24 hours.
    2. Return the cached result for duplicate keys.
    3. Return 409 Conflict if the key is reused with different parameters.
Status CodeDescription
200 OKThe request was successful.
201 CreatedThe cart was successfully created.
400 Bad RequestThe request was invalid or cannot be served.
401 UnauthorizedAuthentication is required and has failed or has not been provided.
403 ForbiddenThe request is authenticated but the user does not have the necessary permissions.
409 ConflictThe request could not be completed due to a conflict (e.g., idempotent key reuse).
422 Unprocessable EntityThe profile content is malformed (discovery failure).
424 Failed DependencyThe profile URL is valid but fetch failed (discovery failure).
429 Too Many RequestsRate limit exceeded.
500 Internal Server ErrorAn unexpected condition was encountered on the server.
503 Service UnavailableTemporary unavailability.
  • Protocol errors: Return appropriate HTTP status code (401, 403, 409, 429, 503) with JSON body containing code and content.
  • Business outcomes: Return HTTP 200 with UCP envelope and messages array.

Authentication is optional and depends on business requirements. When authentication is required, the REST transport MAY use:

  1. Open API: No authentication required for public operations.
  2. API Keys: Via X-API-Key header.
  3. OAuth 2.0: Via Authorization: Bearer {token} header, following RFC 6749.
  4. Mutual TLS: For high-security environments.