> ## Documentation Index
> Fetch the complete documentation index at: https://docs.retempo.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /api/v1/checkout-sessions — Create Checkout Session

> POST /api/v1/checkout-sessions — creates a checkout session linking a payment plan to a subscriber. Returns a PENDING session with expiry options.

A checkout session is the entry point for subscriber onboarding. You create one by linking a service to a payment plan, and optionally pre-associating an existing user. Retempo always creates the session in `PENDING` status and returns it immediately — the session transitions to `PAID` only after the subscriber completes payment.

```
POST https://api.retempo.xyz/api/v1/checkout-sessions
```

## Request Body

<ParamField body="serviceId" type="string" required>
  The ID of the service the subscriber is signing up for.
</ParamField>

<ParamField body="paymentPlanId" type="string" required>
  The ID of the payment plan to attach to this checkout session. The plan must belong to the specified service; a mismatch returns a `404`.
</ParamField>

<ParamField body="userId" type="string">
  The ID of an existing Retempo user to pre-associate with this session. If omitted, the user is identified during the checkout flow.
</ParamField>

<ParamField body="expiresAt" type="string">
  An ISO 8601 datetime string specifying when the session expires. If omitted, the session does not expire automatically.
</ParamField>

## Response

A successful request returns HTTP `201 Created` with the new checkout session object. The `status` is always `PENDING`.

<ResponseField name="checkoutSession" type="object">
  The newly created checkout session.

  <Expandable title="checkoutSession fields">
    <ResponseField name="id" type="string">Unique identifier for the checkout session.</ResponseField>
    <ResponseField name="serviceId" type="string">ID of the associated service.</ResponseField>
    <ResponseField name="paymentPlanId" type="string">ID of the associated payment plan.</ResponseField>
    <ResponseField name="userId" type="string | null">ID of the pre-associated user, or `null` if not yet known.</ResponseField>
    <ResponseField name="status" type="string">Always `PENDING` on creation.</ResponseField>
    <ResponseField name="expiresAt" type="string | null">Expiry datetime, or `null` if not set.</ResponseField>
    <ResponseField name="createdAt" type="string">ISO 8601 datetime the session was created.</ResponseField>
    <ResponseField name="service" type="object">Nested service object with `id`, `name`, and `status`.</ResponseField>
    <ResponseField name="paymentPlan" type="object">Nested payment plan with `id`, `name`, `amount`, and `currency`.</ResponseField>
    <ResponseField name="user" type="object | null">Nested user object if `userId` was provided, otherwise `null`.</ResponseField>
  </Expandable>
</ResponseField>

### 201 — Checkout session created

```json theme={null}
{
  "checkoutSession": {
    "id": "clz1checkout789",
    "serviceId": "clz1abc2def3ghi4",
    "paymentPlanId": "clz1plan567",
    "userId": null,
    "status": "PENDING",
    "expiresAt": "2025-06-02T10:00:00.000Z",
    "createdAt": "2025-06-01T10:10:00.000Z",
    "service": {
      "id": "clz1abc2def3ghi4",
      "name": "DataStream Pro",
      "status": "ACTIVE"
    },
    "paymentPlan": {
      "id": "clz1plan567",
      "name": "Pro Monthly",
      "amount": "49.000000",
      "currency": "USDC"
    },
    "user": null
  }
}
```

## Example Request

```bash theme={null}
curl -X POST https://api.retempo.xyz/api/v1/checkout-sessions \
  -H "Content-Type: application/json" \
  -d '{
    "serviceId": "clz1abc2def3ghi4",
    "paymentPlanId": "clz1plan567",
    "expiresAt": "2025-06-02T10:00:00.000Z"
  }'
```

## Error Codes

| Status            | Message                                                      | Condition                                                            |
| ----------------- | ------------------------------------------------------------ | -------------------------------------------------------------------- |
| `400 Bad Request` | `serviceId is required.`                                     | `serviceId` was omitted.                                             |
| `400 Bad Request` | `paymentPlanId is required.`                                 | `paymentPlanId` was omitted.                                         |
| `400 Bad Request` | `Checkout sessions can only be created with PENDING status.` | A non-`PENDING` value was passed for `status`.                       |
| `404 Not Found`   | `Payment plan was not found for the service.`                | The plan does not exist or does not belong to the specified service. |
| `404 Not Found`   | `Referenced database record was not found.`                  | The `userId` was not found.                                          |

<Note>
  Checkout sessions are always created with status `PENDING`. The session transitions to `PAID` when the subscriber completes payment. Attempting to create a session with any other initial status returns a `400` error.
</Note>
