> This page is for version v1 (default).
> For other versions, use one of these documentation indexes:
> - v1 (default): https://developers.truemed.com/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.truemed.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.truemed.com/_mcp/server.

# Capture Session

POST https://dev-api.truemed.com/payments/v1/payment_session/{business_id}/capture
Content-Type: application/json

The `capture_payment_session` endpoint should be called after [`create_payment_session`](/api-reference/payment-sessions/create-payment-session)
has been called with `kind` of `authorization` as outlined in [Manual/Delayed Capture](/guides/setup/api/payment-sessions/manual-delayed-capture).

The failure or success status is communicated to the partner via a [`payment_session_complete`](/api-reference/payment-sessions/payment-session-completed-webhook)
webhook as before.

## Request Notes

The `total_amount` field will often not be the sum of the `order_item[*].price` fields, as you may be charging additional
fees or including taxes.

* **`total_amount`** *(Required)* - The total amount in cents to charge the user, inclusive of taxes and fees being collected by the partner. **Must be less than or equal to the `total_amount` passed in when creating the payment session.**
  * If an amount more than the initial authorization should be captured, void the initial auth hold and create a new one.
* **`item_details`** *(Required)* - The items included in this capture. Each entry references an `item_id` from the payment session's `order_items`, and `total_amount` must equal the sum of the entries' `total` values.
  * A line keeps the same effective per-unit cost (`total / quantity`) across every capture it appears in.
* **`final`** *(Optional, defaults to `true`)* - Set to `false` to leave the uncaptured remainder of the authorization held for a later capture. This requires [multi-capture](/guides/setup/api/payment-sessions/manual-delayed-capture#capturing-in-multiple-parts): the payment session must have been created with `request_multicapture: true`, and the card network must have granted multi-capture on the authorization. Otherwise the request fails with `ValidationError`.
  * A capture with `final: true` releases whatever is still uncaptured back to the customer.
  * To release the uncaptured remainder without capturing more, send a final capture with `total_amount: 0` and empty `item_details`, or [void the session](/api-reference/payment-sessions/void-payment-session). A zero-amount final capture is accepted only after at least one earlier capture.
  * Order-level shipping, fees, and discounts are only accepted on a single capture that covers the whole order. Under multi-capture, carry them as line items instead.

## Response Notes

### Success Case

HTTP Status: `200`

* **`id`** - The ID of the payment session that was captured, the same value that `create_payment_session` returned.
* **`capture_id`** - The ID of this capture. Pass it as `capture_id` to [Create Refund](/api-reference/payment-sessions/create-refund) to refund against this capture. The same ID is returned if the endpoint is called again with the same `idempotency_key`. It is omitted for a zero-amount final capture, which only releases the uncaptured remainder.

### Bad Request

HTTP Status: `400`

If a field is missing or the request otherwise can't be processed, we'll return a `400` with the following fields:

* **`error`** - can be one of:
  * `MissingField`: One of the required fields is not present in the request.
  * `TotalAmountInvalid`: The `total_amount` field is either not greater than or equal to the sum of the `order_item` `amount` fields, is 0, is negative, or is greater than the amount still capturable on the payment session. It is also returned when a non-final capture has a zero `total_amount`, when a zero-amount final capture is not preceded by another capture, or when order-level amounts are sent on a capture that does not cover the whole order.
  * `PaymentSessionDoesNotExist`: The `payment_session_id` does not exist.
  * `ServerError`: There was an internal server error. Requests can be retried as long as the `idempotency_key` is the same.
  * `SessionVoided`: The session has already been voided via a call to [`/payment_session/{payment_session_id}/void`](/api-reference/payment-sessions/void-payment-session).
  * `SessionExpired`: The auth hold has expired and we were unable to recharge the customer for the amount requested.
  * `SessionPending`: The user hasn't completed the Truemed checkout flow (survey, CC entry form).
  * `SessionCaptured`: You're attempting to capture a payment\_session that has already been captured. This error **will never** be returned if reissuing a capture call **with the same idempotency key** - the return value will be the same as the first call.
  * `ImmediateCapture`: The caller is attempting to void a payment\_session that wasn't created with `kind=authorization`.
  * `InvalidItemizedData`: An `item_details` entry is invalid — a non-positive quantity, a negative total, a quantity or total beyond what remains capturable for that item, or a per-unit cost that differs from the item's existing captures. The `message` names the item and the rejected value.
  * `ValidationError`: The capture is not permitted in this configuration — for example `final: false` on an authorization that does not have multi-capture.
* **`message`** - Indication of which field was missing, details on how the total amount was invalid, or details on voided sessions.

Reference: https://developers.truemed.com/api-reference/payment-sessions/capture-payment-session

## Authentication

- `x-truemed-api-key` header (required) — Sales channel API key for merchant server-to-server authentication

## Servers

- `https://dev-api.truemed.com` (Development server, default)
- `https://api.truemed.com` (Production server)

## Request

### Path parameters

- `business_id` (string, required) — The UUID of the payment session returned by create_payment_session.

### Body (application/json)

This endpoint expects a PaymentSessionCaptureRequest.

- `idempotency_key` (string, required) — Allows the endpoint to be called multiple times. It must be unique to the capture session.
- `item_details` (list of CaptureItemDetails, required) — A list of items being captured in the capture request.
- `total_amount` (integer, required) — The total amount in cents to charge the user, inclusive of taxes and fees being collected by the partner. Must be less than or equal to the total_amount passed in when creating the payment session. If an amount more than the initial authorization should be captured, void the initial auth hold and create a new one.
- `final` (boolean, optional, default: true) — Whether this is the final capture for the payment session. Set to false to allow additional captures up to the authorized amount — this requires that the session was created with `request_multicapture: true` and that the card network granted multi-capture on the authorization, and otherwise fails with `ValidationError`. A final capture releases any uncaptured remainder of the authorization. To release the remainder without capturing more, send a final capture with `total_amount: 0` (allowed after at least one earlier capture) or void the session.

## Response

### 200

Successful response

- `id` (string, required) — The ID of the payment session that was captured, the same value returned by create_payment_session. Use `capture_id` to identify this capture.
- `capture_id` (string, optional, nullable) — The ID of this capture. Pass it as `capture_id` to the refund endpoint to refund against this capture. The same ID is returned if the endpoint is called again with the same idempotency_key. Omitted for a zero-amount final capture, which only releases the uncaptured remainder and cannot be refunded.

## Errors

### 400 Bad Request Error

Bad Request

- `error` (enum, required)
  - Allowed values: `ImmediateCapture`, `SessionCaptured`, `SessionExpired`, `SessionPending`, `SessionVoided`, `TotalAmountInvalid`, `ValidationError`
- `message` (string, required)

### 404 Not Found Error

Not Found

- `error` (enum, required)
  - Allowed values: `NotFound`
- `message` (string, required)

### 405 Method Not Allowed Error

Method Not Allowed

- `error` (enum, required)
  - Allowed values: `MethodNotAllowed`
- `message` (string, required)

### 500 Internal Server Error

Internal Server Error

- `error` (enum, required)
  - Allowed values: `ServerError`
- `message` (string, required)

### 501 Not Implemented Error

Not Implemented

- `error` (enum, required)
  - Allowed values: `NotImplemented`
- `message` (string, required)

## Types

### CaptureItemDetails

- `item_id` (string, required) — ID that uniquely identifies the item within the Payment; optionally specified when creating the payment and retrievable from payment session status or list payment sessions.
- `quantity` (integer, required) — The quantity to capture for this order_item, up to the quantity_capturable for the item, retrievable from payment session status or list payment sessions.
- `total` (integer, required) — The total amount in cents to capture for this order_item, up to the total_capturable for the item, retrievable from payment session status or list payment sessions.

## Examples

**Request**

```json
{
  "idempotency_key": "string",
  "item_details": [
    {
      "item_id": "string",
      "quantity": 1,
      "total": 1
    }
  ],
  "total_amount": 1
}
```

**Response**

```json
{
  "id": "string",
  "capture_id": "string"
}
```

**SDK Code**

```python
import requests

url = "https://dev-api.truemed.com/payments/v1/payment_session/business_id/capture"

payload = {
    "idempotency_key": "string",
    "item_details": [
        {
            "item_id": "string",
            "quantity": 1,
            "total": 1
        }
    ],
    "total_amount": 1
}
headers = {
    "x-truemed-api-key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://dev-api.truemed.com/payments/v1/payment_session/business_id/capture';
const options = {
  method: 'POST',
  headers: {'x-truemed-api-key': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"idempotency_key":"string","item_details":[{"item_id":"string","quantity":1,"total":1}],"total_amount":1}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```