---
title: "Upsert a cart"
method: POST
path: "/commerce/carts"
tags: ["Commerce"]
---

# Upsert a cart

`POST /commerce/carts`

## Request

- Base URL: `https://sending.dev/api/v1`
- URL: `https://sending.dev/api/v1/commerce/carts`
- Auth: HTTP bearer

Idempotent on `externalId`. Queues a delayed abandonment check that emits the `cart_abandoned` event. A new cart whose email matches an existing contact emits `started_checkout` once per `externalId`. Required scope: `commerce:write`. Requires a plan with the `ecommerce` feature.

## Request body

- CommerceCartInput
  - `externalId` string, required
  - `email` string, email, required
  - `items` object[], required
    - `title` string, required
    - `quantity` integer
    - `price` number
    - `imageUrl` string
    - `url` string
    - `productId` string
  - `total` number
  - `currency` string
  - `cartUrl` string

## Response `202`

Cart accepted.

- CommerceAccepted
  - `status` 'accepted', required

## Other responses

- `401`: Missing or invalid token.
- `402`: Plan quota exceeded.
- `403`: Insufficient scope.
- `422`: Invalid input.

---

[API](https://skmtc.dev/sending/apis/sending-dev-api.md) · [All operations](https://skmtc.dev/sending/apis/sending-dev-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sending/apis/sending-dev-api/revisions/9fe78d2918a1?raw)
