Create a product
Saves something you sell, so a checkout can name it by `product_id` instead of repeating a price. Create one for anything you sell more than once, and for every plan: only a saved recurring product can start a subscription. `price` is an integer in the currency's minor unit, and `currency` must be one `GET /account` lists. `billing: "recurring"` needs a `billing_interval`, and `interval_count` bills every N intervals; a one-time product must not carry either. A price of zero is accepted, but a checkout containing that product is refused. A product created with a test key exists only in test mode. Send `Idempotency-Key` so a retried request does not save a second product.
Saves something you sell, so a checkout can name it by product_id instead of repeating a price. Create one for anything you sell more than once, and for every plan: only a saved recurring product can start a subscription.
price is an integer in the currency's minor unit, and currency must be one GET /account lists. billing: "recurring" needs a billing_interval, and interval_count bills every N intervals; a one-time product must not carry either. A price of zero is accepted, but a checkout containing that product is refused. A product created with a test key exists only in test mode. Send Idempotency-Key so a retried request does not save a second product.
Authorization
secretKey Your secret key: sk_live_… or sk_test_….
In: header
Header Parameters
Retrying with the same key returns the first response instead of creating a duplicate. 1 to 255 printable ASCII characters (INVALID_IDEMPOTENCY_KEY otherwise), remembered for 24 hours per key's merchant and mode. A replayed answer carries idempotent-replayed: true. The same key with a different body is refused with 422 IDEMPOTENCY_KEY_REUSED; while the first request is still running, 409 IDEMPOTENCY_KEY_IN_USE. A request that failed with a 5xx is not remembered, so it can simply be retried.
length <= 255Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
curl -X POST "https://example.com/products" \ -H "Content-Type: application/json" \ -d '{ "name": "string", "price": 0, "currency": "USD" }'{ "object": "product", "product_id": "pdt_3f2b8c1e9a4d4e7b8c2a1d5e6f7a8b9c", "name": "string", "description": "string", "price": 0, "currency": "AED", "billing": "one_time", "billing_interval": "day", "interval_count": 1, "status": "active", "metadata": { "property1": "string", "property2": "string" }, "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z"}Update or cancel a subscription PATCH
Send `{ "status": "cancelled" }` to cancel now, or `{ "cancel_at_period_end": true }` to let the paid period run out without renewing. `metadata` is the only other thing this endpoint changes, and it replaces what was stored. What a subscription charges — its product, amount, currency, interval, quantity and customer — is fixed when it starts: to change any of it, cancel this subscription and take a new checkout. Cancelling cannot be taken back. A subscription the card processor renews is stopped there first, and if the processor does not confirm, nothing changes here and the answer is `502 CANCELLATION_FAILED`. For such a subscription, ending it at the end of the period stops those renewals immediately (the period is paid already), so it cannot be resumed: `cancel_at_period_end: false` afterwards answers `409 CANCELLATION_FINAL`. Changing an already cancelled subscription answers `409 SUBSCRIPTION_CANCELLED`, and a renewal being charged right now answers `409 CHARGE_IN_PROGRESS` — try again in a minute.
Retrieve a product GET
Returns one product: its price in the currency's minor unit, whether it is `active`, and for a recurring product the interval it bills on. Only products belonging to the key's merchant and mode are visible.