Skip to main content
Use this endpoint to create a hosted checkout link from your backend or a no-code/AI tool, the same way you create transactions. Authentication is by API key; the tenant and company are resolved from the token. The response is just the final checkout URL.

Happy path

  1. Call POST /v2/checkout-links with your API key.
  2. Send either products[] (referenced by your own external_id) or a value-only amount.
  3. Pagou upserts each product by external_id, builds the link, and attaches the company’s active payment methods plus any eligible order bump / upsell automatically.
  4. Use the returned data.url — it already carries your custom domain when one is active.

Authentication

Send your secret API key as a Bearer token (same key used for transactions):
Authorization: Bearer YOUR_API_KEY
The x-api-key: YOUR_API_KEY header is also accepted.

Products by external_id (upsert)

Each item in products[] is keyed by external_id — your own identifier for the product. On every call Pagou upserts by (company, external_id):
  • First time: creates the product in your catalog (origin = api).
  • Next times: reuses the same product and updates its name/price/fields from the payload (reviving it if it was archived). It never duplicates.
You never need to know Pagou’s internal product ids — external_id is the only identifier you pass.
Prices are integers in cents (7990 = R$ 79.90). Re-sending the same external_id overwrites the product’s name, price, description and image from the payload, so always send the full product state you want.

Example request — products

curl --request POST \
  --url https://api.pagou.ai/v2/checkout-links \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "currency": "BRL",
    "title": "Order #1042",
    "products": [
      {
        "external_id": "SKU-TSHIRT-BLACK-M",
        "name": "Black T-Shirt M",
        "price": 7990,
        "quantity": 2,
        "type": "physical",
        "image_url": "https://cdn.example.com/tshirt.jpg",
        "compare_price": 9990
      }
    ]
  }'
Omit products and send amount (in cents) to generate a quick, value-only link. title is optional — when absent it is auto-generated.
curl --request POST \
  --url https://api.pagou.ai/v2/checkout-links \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{ "currency": "BRL", "amount": 15000 }'
Send either products or amount — not both, and not neither.

Example response

{
  "success": true,
  "requestId": "req_1201",
  "data": {
    "url": "https://checkout.pagou.ai/chk_01J8Z..."
  }
}

Request fields

FieldTypeRequiredNotes
currencystringnoLink currency. Default BRL.
titlestringnoAuto-generated when omitted.
amountinteger (cents)one ofValue-only link. Mutually exclusive with products.
products[]arrayone ofProduct-based link. Mutually exclusive with amount.
products[].external_idstringyesYour identifier; upsert key.
products[].namestringyesProduct name.
products[].priceinteger (cents)yesUnit price.
products[].quantityintegernoDefault 1.
products[].currencystringnoInherits the link currency.
products[].typestringnophysical or digital. Default physical.
products[].descriptionstringno
products[].image_urlstring (url)no
products[].compare_priceinteger (cents)no”From” price for a discount display.

Common error

Status 422 — neither amount nor products was provided (or both were):
{
  "type": "https://api.pagou.ai/problems/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "The request contains invalid data.",
  "errors": [
    {
      "field": "amount",
      "message": "Either amount or products must be provided.",
      "code": "custom"
    }
  ]
}

Use with AI

Paste this into Claude Code, Cursor, Codex, Copilot, Lovable, Bolt, or any AI coding agent:
Read https://developer.pagou.ai/llms-full.txt and https://developer.pagou.ai/api-reference/openapi-v2.json

Build a checkout link flow (Pagou-hosted checkout — no card handling on your side):
1. Backend/server function only: POST /v2/checkout-links with an Authorization: Bearer <API key>
2. Body — products: { "currency": "BRL", "title": "<order>", "products": [{ "external_id": "<your id>", "name": "<name>", "price": <cents>, "quantity": <n> }] }
3. Body — value-only: { "currency": "BRL", "amount": <cents> }. Send EITHER products OR amount, never both.
4. external_id is your own product id; re-sending the same id updates that product (no duplicates).
5. Response is { "data": { "url": "<checkout url>" } } — redirect the buyer to data.url.
6. Fulfillment: update the order only after the transaction webhook (event=transaction, data.event_type) confirms payment — not on redirect.

Prices/amount are integers in cents. Keep the API key server-side (env var), never in the browser. Validate all fields against OpenAPI.

Notes

  • Payment methods are always derived from the company’s active permissions — you don’t pass them.
  • Order bumps and upsells eligible for the products are attached automatically.
  • Custom domain is applied to the returned URL when the company has one active.
  • Out of scope (v1): product variants by external_id, subscriptions/recurring, and updating or listing links via the API.

Next steps