---
title: "Create payment intent"
method: POST
path: "/payment-intents"
tags: ["Payment Intents"]
---

# Create payment intent

`POST /payment-intents`

## Request

- Base URL: `https://api.natural.com`
- URL: `https://api.natural.com/payment-intents`
- Auth: HTTP bearer

Create a payment intent with a hosted checkout link

## Headers

- `Idempotency-Key` string, required
- `X-Instance-ID` string, nullable

## Request body

- object
  - `data` object, required
    - `attributes` object, required
      - `customerPartyId` string: Customer party to act for (pty_*). Omit for your own account. Requires authorization from that customer.
      - `amount` integer, required: Total amount in US cents.
      - `currency` 'USD', required: Currency code. USD only.
      - `description` string: What the payment is for.
      - `expiresAt` string: RFC 3339 timestamp after which no new payment attempt may start.
      - `taxMode` 'exclusive' | 'inclusive': Whether tax is added to or included in line amounts.
      - `taxAmount` integer: Tax in cents when lineItems is empty. Defaults to zero.
      - `lineItems` object[]: Sale lines in display order. Totals are calculated by Natural.
        - `referenceId` string: Your reference for the line, such as a SKU.
        - `description` string, required: What this line sells.
        - `quantity` integer, required: Unit count.
        - `unitAmount` integer, required: Per-unit amount in cents.
        - `taxAmount` integer: Total tax for this line in cents. Defaults to zero.
        - `taxCode` string: Your tax code for this line.
      - `mandateId` string: Early access (mandates). Card agreement (mdt_*) to charge now, while the payer is away. Not allowed with expiresAt.
      - `captureMethod` 'automatic' | 'manual': Early access (holds). manual holds the amount on the card for a later capture. Requires mandateId. Defaults to automatic.

## Response `201`

Successful Response

- object
  - `data` PaymentIntent, required
    - `id` string, required
    - `type` 'paymentIntent', required: Resource type. Always `paymentIntent`.
    - `attributes` object, required
      - `amount` integer, required: Total amount in US cents.
      - `currency` 'USD', required: Currency code.
      - `description` string, nullable, required: What the payment is for.
      - `payUrl` string, nullable, required: Hosted checkout URL while the intent is open or processing. Null when the intent is closed or no link is available.
      - `clientSecret` string, nullable, required: Pass to natural.js in the browser to show the payment form. Available whenever `payUrl` is. Treat it like a password: send it only to the payer's browser.
      - `status` 'open' | 'processing' | 'authorized' | 'completed' | 'canceled' | 'declined' | 'expired', required: Payment collection status. A completed intent has a successful payment, but funds may not be settled yet. Early access (holds): `authorized`.
      - `captureMethod` 'manual': Early access (holds). `manual` on a hold: the card is charged only when you capture it.
      - `captureBefore` string, nullable: Early access (holds). RFC 3339 deadline to capture a hold. Null until the card issuer approves the hold. It stays set after the hold is captured, canceled or expires; only an `authorized` hold can be captured.
      - `taxMode` 'exclusive' | 'inclusive', required: Whether tax is added to or included in line amounts.
      - `taxAmount` integer, required: Tax in cents.
      - `lineItems` object[], required: Line items in display order. Replaceable while the intent is open.
        - `id` string, required: Line item ID (pli_*). Replacing the lines issues new IDs.
        - `position` integer, required: Zero-based display order.
        - `referenceId` string, nullable, required: Your own reference for the line, such as a SKU.
        - `description` string, required: What this line sells.
        - `quantity` integer, required: Unit count.
        - `unitAmount` integer, required: Per-unit amount in cents.
        - `subtotalAmount` integer, required: Line total before tax, in cents. Equals totalAmount minus taxAmount.
        - `taxAmount` integer, required: Line tax in cents.
        - `totalAmount` integer, required: Line total in cents.
        - `taxCode` string, nullable, required: Your tax code for this line.
      - `expiresAt` string, nullable, required: RFC 3339 timestamp after which no new payment attempt may start.
      - `canceledAt` string, nullable, required: RFC 3339 timestamp when the intent was canceled.
      - `createdAt` string, required: RFC 3339 creation timestamp.
      - `updatedAt` string, required: RFC 3339 update timestamp.
    - `relationships` object, required
      - `customerParty` object, required: The party being paid.
        - `data` object, required: Related resource identifier.
          - `type` 'party', required: Resource type. Always `party`.
          - `id` string, required
      - `cardPayment` object, required: The card payment the issuer approved. Null until one is approved.
        - `data` object, nullable, required: Related resource identifier.
          - `type` 'cardPayment', required: Resource type. Always `cardPayment`.
          - `id` string, required
      - `mandate` object: Early access (mandates). Card agreement (mdt_*) the intent was charged under. Only on an intent you created with `mandateId`.
        - `data` object, required: Related resource identifier.
          - `type` 'mandate', required: Resource type. Always `mandate`.
          - `id` string, required
      - `voiceSession` object, required: Latest voice session for this intent. Null when no session has been created.
        - `data` object, nullable, required: Related resource identifier.
          - `type` 'voiceSession', required: Resource type. Always `voiceSession`.
          - `id` string, required

## Other responses

- `400`: Validation Error
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not Found. Returned when the resource does not exist, or when it exists but is not accessible to your account. The two cases are intentionally indistinguishable, so that resource IDs cannot be enumerated by probing.
- `409`: Conflict
- `422`: Validation Error. The response contains one error object for each invalid request value.
- `428`: Precondition Required
- `429`: Too Many Requests
- `500`: Internal Server Error
- `501`: Not Implemented
- `502`: Bad Gateway
- `503`: Service Unavailable

## Changes

- **2026-10-29** `59c1208fa5dc`: 1 info
  - added the optional property `data/relationships/mandate` to the response with the `201` status
- **2026-10-28** `46c3e5516668`: 1 warning, 4 info
  - added the new `authorized` enum value to the `data/attributes/status` response property for the response status `201`
  - added the new optional request property `data/attributes/captureMethod`
  - added the new optional request property `data/attributes/mandateId`
  - added the optional property `data/attributes/captureBefore` to the response with the `201` status
  - …1 more
- **2026-09-30** `6663cdab7a7c`: 1 info
  - added the required property `data/attributes/clientSecret` to the response with the `201` status
- **2026-09-29** `4fab756be152`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/natural/apis/natural-api/changes/payment-intents/post.md)

---

[API](https://skmtc.dev/natural/apis/natural-api.md) - [All operations](https://skmtc.dev/natural/apis/natural-api/llms.txt) - [OpenAPI document](https://skmtc.dev/natural/apis/natural-api/revisions/59c1208fa5dc?raw)
