Products
What you sell.
GET /v1/products
List products
Cursor-paginated (limit, starting_after).
- Authentication
- Merchant API key
- Effect
- Read-only.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | no | Page size (1–100). · ≥ 1, ≤ 100, default 20 |
starting_after | string | no | Object ID; return objects after it (ascending ID order). · 26 chars |
Responses
| Status | Meaning | Body / error codes |
|---|---|---|
| 200 | Success. | object |
| 401 | Missing or invalid API key. | authentication_error |
| 429 | Rate limited; honor retry-after. | rate_limit_exceeded too_many_auth_failures |
| 500 | Server error. | api_error |
Example response
{
"object": "list",
"url": "string",
"has_more": false,
"data": [
{
"object": "product",
"id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"name": "string",
"description": "string",
"active": false,
"metadata": {},
"created_at": "2026-10-25T18:00:00.000Z",
"updated_at": "2026-10-25T18:00:00.000Z"
}
]
}POST /v1/products
Create a product
- Authentication
- Merchant API key
- Effect
- Creates a product.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | no | Makes retries safe: same key + body replays the stored response (idempotency-replayed: true); a different body returns 409 idempotency_key_in_use. · ≤ 96 chars |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | ≤ 255 chars |
description | string | no | |
active | boolean | no | default true |
metadata | object | no | Free-form key/value data. Each value ≤16 KiB of JSON, ≤8 nesting levels, ≤100 properties/elements. |
Example request
{
"name": "string",
"description": "string",
"active": true,
"metadata": {}
}Responses
| Status | Meaning | Body / error codes |
|---|---|---|
| 201 | Product created. | Product |
| 400 | Invalid body. | validation_failed invalid_json |
| 401 | Missing or invalid API key. | authentication_error |
| 429 | Rate limited; honor retry-after. | rate_limit_exceeded too_many_auth_failures |
| 500 | Server error. | api_error |
Example response
{
"object": "product",
"id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"name": "string",
"description": "string",
"active": false,
"metadata": {},
"created_at": "2026-10-25T18:00:00.000Z",
"updated_at": "2026-10-25T18:00:00.000Z"
}GET /v1/products/:id
Retrieve a product
- Authentication
- Merchant API key
- Effect
- Read-only.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | Object ID (ULID). · 26 chars |
Responses
| Status | Meaning | Body / error codes |
|---|---|---|
| 200 | Success. | Product |
| 401 | Missing or invalid API key. | authentication_error |
| 404 | Not found, or not yours. | resource_missing |
| 429 | Rate limited; honor retry-after. | rate_limit_exceeded too_many_auth_failures |
| 500 | Server error. | api_error |
Example response
{
"object": "product",
"id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"name": "string",
"description": "string",
"active": false,
"metadata": {},
"created_at": "2026-10-25T18:00:00.000Z",
"updated_at": "2026-10-25T18:00:00.000Z"
}POST /v1/products/:id
Update a product
Partial update.
- Authentication
- Merchant API key
- Effect
- Updates the product.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | Object ID (ULID). · 26 chars |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | no | Makes retries safe: same key + body replays the stored response (idempotency-replayed: true); a different body returns 409 idempotency_key_in_use. · ≤ 96 chars |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | ≤ 255 chars |
description | string | no | |
active | boolean | no | default true |
metadata | object | no | Free-form key/value data. Each value ≤16 KiB of JSON, ≤8 nesting levels, ≤100 properties/elements. |
Example request
{
"name": "string",
"description": "string",
"active": true,
"metadata": {}
}Responses
| Status | Meaning | Body / error codes |
|---|---|---|
| 200 | Success. | Product |
| 400 | Invalid body or no fields to update. | validation_failed invalid_json empty_update |
| 401 | Missing or invalid API key. | authentication_error |
| 404 | Not found, or not yours. | resource_missing |
| 429 | Rate limited; honor retry-after. | rate_limit_exceeded too_many_auth_failures |
| 500 | Server error. | api_error |
Example response
{
"object": "product",
"id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"name": "string",
"description": "string",
"active": false,
"metadata": {},
"created_at": "2026-10-25T18:00:00.000Z",
"updated_at": "2026-10-25T18:00:00.000Z"
}DELETE /v1/products/:id
Archive a product
Archives rather than removes: sets active=false and returns the product. Archived products cannot be newly subscribed to.
- Authentication
- Merchant API key
- Effect
- Sets
active=false.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes | Object ID (ULID). · 26 chars |
Headers
| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | no | Makes retries safe: same key + body replays the stored response (idempotency-replayed: true); a different body returns 409 idempotency_key_in_use. · ≤ 96 chars |
Responses
| Status | Meaning | Body / error codes |
|---|---|---|
| 200 | The archived product. | Product |
| 401 | Missing or invalid API key. | authentication_error |
| 404 | Not found, or not yours. | resource_missing |
| 429 | Rate limited; honor retry-after. | rate_limit_exceeded too_many_auth_failures |
| 500 | Server error. | api_error |
Example response
{
"object": "product",
"id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"merchant_id": "01JB9XK3M2R7TQ8N4V6Y0ZPA1C",
"name": "string",
"description": "string",
"active": false,
"metadata": {},
"created_at": "2026-10-25T18:00:00.000Z",
"updated_at": "2026-10-25T18:00:00.000Z"
}