> This page is for API, version 2026-01-01 (Stable) (default).
> For other versions, use one of these documentation indexes:
> - 2026-01-01 (Stable) (default): https://developer.deel.com/api/stable/llms.txt

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

# Create and pay a payment statement

POST https://api.letsdeel.com/rest/payments/statements
Content-Type: application/json

Creates a payment statement for the requested invoices and pays it by bank transfer in a single call, instead of creating and paying in two separate steps. Use it when all invoices belong in one statement, grouped by statement type and legal entity. Every invoice must also be pending and not already locked in another payment. Submit invoices that span more than one statement in separate calls.

 **Token scopes**: `payment-statements:write`

Reference: https://developer.deel.com/api/reference/endpoints/payments/create-payment-statement-v-2026-07-23

## Authentication

- `Authorization` header (bearer token, required) — ## Authentication The Deel API uses bearer tokens to authenticate requests. All API calls must be made over HTTPS — calls over plain HTTP or without authentication will fail. ```curl curl -X GET 'https://api.letsdeel.com/rest/v2/contracts' \ -H 'Authorization: Bearer YOUR-TOKEN-HERE' ``` [Learn more about authentication](/api/authentication)
- `Authorization` header (bearer token, required) — Standard OAuth2 security scheme based on https://swagger.io/docs/specification/authentication/

## Servers

- `https://api.letsdeel.com/rest` (Production, default)
- `https://api-staging.letsdeel.com/rest` (Demo)

## Request

### Headers

- `Idempotency-Key` (string, required) — Unique key that makes the request idempotent. Replaying the same key returns the original response without creating a duplicate statement. Reusing a key with a different body returns 409 idempotency_conflict.

### Body (application/json)

This endpoint expects an object.

- `data` (PaymentsStatementsPostRequestBodyContentApplicationJsonSchemaData, required)

## Response

### 201

Successfully created and initiated payment of the statement.

- `data` (PaymentsStatementsPostResponsesContentApplicationJsonSchemaData, required)

## Errors

### 400 Bad Request Error

Bad request. Codes: too_many_invoices (invoice_ids exceeds the maximum of 100), currency_not_supported (the requested country does not support the requested currency for bank transfer), invalid_parameter (request validation failed), INVALID_IDEMPOTENCY_KEY (the Idempotency-Key header is missing, empty, or longer than 64 characters).

- `errors` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems, required)

### 401 Unauthorized Error

The authentication is missing or is invalid.

- `errors` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems, required)

### 403 Forbidden Error

The organization is not permitted to use this endpoint.

- `errors` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems, required)

### 404 Not Found Error

One or more referenced resources could not be found.

- `errors` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems, required)

### 409 Conflict Error

Conflict. Codes: invoices_not_payable (some invoices are already in a statement or not pending), invoices_locked (invoices are in an active payment process), no_payable_invoices (none of the invoices are payable), cor_preparation_failed (shielded/contract-of-record preparation failed), idempotency_conflict (the Idempotency-Key was reused with a different request body), multiple_statements (the invoices resolve to more than one statement — submit each group separately), payment_failed (the statement was created but the synchronous payment could not be completed).

- `errors` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems, required)

### 429 Too Many Requests Error

Too many requests. Another request with the same Idempotency-Key is currently in progress.

- `errors` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems, required)

### 500 Internal Server Error

An unexpected error occurred while creating and paying the payment statement.

- `errors` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems, required)

## Types

### PaymentsStatementsPostRequestBodyContentApplicationJsonSchemaData

- `payment` (PaymentsStatementsPostRequestBodyContentApplicationJsonSchemaDataPayment, required) — Settlement details for the payment.
- `invoice_ids` (list of string, required) — Identifiers of the invoices to include in the payment statement. A maximum of 100 invoices can be paid in one request.

### PaymentsStatementsPostResponsesContentApplicationJsonSchemaData

- `id` (string, required) — Unique identifier of the payment statement.
- `amount` (string, required, nullable) — Total amount of the payment statement before any balance is applied. Null until the amount is set.
- `status` (enum, required) — Normalized status of the payment statement. 'PROCESSING' covers any in-flight state (pending, preprocessing, awaiting payment); 'paid', 'cancelled' and 'failed' are terminal.
  - Allowed values: `PROCESSING`, `PAID`, `CANCELLED`, `FAILED`
- `invoices` (list of PaymentsStatementsPostResponsesContentApplicationJsonSchemaDataInvoicesItems, required) — Authoritative superset of invoices settled by this payment statement. It always contains the requested invoices and may include additional overdue or required fee invoices that Deel attaches automatically.
- `amount_due` (string, required, nullable) — Amount still due after any applied balance and fee credits. Null until the amount is set.
- `payment_currency` (string, required, nullable) — Three-letter currency code of the payment statement, following ISO 4217. Null until a payment method is attached.
- `paid_at` (string, optional, nullable) — Date and time when the client paid, in ISO-8601 format. For bank transfers this can be set while the status is still processing. Null until payment is captured.
- `reference` (string, optional, nullable) — Reference to use when reconciling this payment statement against incoming wires.
- `created_at` (string, optional) — Date and time when the payment statement was created, in ISO-8601 format.
- `payment_method` (string, optional, nullable) — Method used to settle the payment statement. Null until a payment method is attached.
- `balance_applied` (string, optional) — Amount of client balance applied to the payment statement.
- `beneficiary_details` (PaymentsStatementsPostResponsesContentApplicationJsonSchemaDataBeneficiaryDetails, optional, nullable) — Beneficiary bank details the payment is settled to. Null when not yet resolved.
- `fee_credits_applied` (string, optional) — Amount of fee credits applied to the payment statement.

### PaymentsStatementsPostResponsesContentApplicationJsonSchemaErrorsItems

- `code` (string, required) — Machine-readable error code.
- `message` (string, required) — Human-readable explanation of the error.

### PaymentsStatementsPostRequestBodyContentApplicationJsonSchemaDataPayment

Settlement details for the payment.

- `country` (string, required) — Two-letter country code for the bank transfer method, following ISO 3166-1 alpha-2.
- `currency` (string, required) — Three-letter currency code of the payment statement, following ISO 4217. Must match the currency of the created statement.

### PaymentsStatementsPostResponsesContentApplicationJsonSchemaDataInvoicesItems

- `id` (string, required) — Unique identifier of the invoice.
- `amount` (string, required) — Amount of the invoice.
- `currency` (string, required) — Three-letter currency code of the invoice, following ISO 4217.
- `label` (string, optional, nullable) — Descriptive label for the invoice.
- `is_auto_added` (boolean, optional) — True when Deel automatically attached this invoice (e.g. an overdue or required fee invoice) beyond the requested set.

### PaymentsStatementsPostResponsesContentApplicationJsonSchemaDataBeneficiaryDetails

Beneficiary bank details the payment is settled to. Null when not yet resolved.

- `iban` (string, optional, nullable) — IBAN of the beneficiary account. Null on non-IBAN rails.
- `swift` (string, optional, nullable) — SWIFT/BIC code of the beneficiary bank. Null when not applicable.
- `address` (string, optional, nullable) — Address to include on the transfer for this rail. Null when not applicable.
- `country` (string, optional, nullable) — Two-letter country code of the beneficiary. Best-effort; null when not modeled.
- `bsb_code` (string, optional, nullable) — BSB code of the beneficiary bank, used for AUD transfers. Null when not applicable.
- `currency` (string, optional, nullable) — Three-letter currency code of the beneficiary account, following ISO 4217. Null when not modeled on the rail.
- `bank_code` (string, optional, nullable) — Local bank code or institution number of the beneficiary bank. Null when not applicable.
- `bank_name` (string, optional, nullable) — Name of the beneficiary bank.
- `ifsc_code` (string, optional, nullable) — IFSC code of the beneficiary bank, used for INR transfers. Null when not applicable.
- `sort_code` (string, optional, nullable) — Sort code of the beneficiary bank. Best-effort; null on most rails.
- `branch_code` (string, optional, nullable) — Branch code or transit number of the beneficiary bank. Null when not applicable.
- `account_type` (string, optional, nullable) — Type of the beneficiary account. Null when not applicable.
- `bank_address` (string, optional, nullable) — Address of the beneficiary bank. Null when not applicable.
- `account_holder` (string, optional, nullable) — Name of the beneficiary account holder. Null when not modeled on the rail.
- `account_number` (string, optional, nullable) — Beneficiary account number. Null on IBAN-only rails.
- `routing_number` (string, optional, nullable) — Routing number of the beneficiary bank when the rail uses one number for both ACH and wire. Null when not applicable.
- `intermediary_bank` (PaymentsStatementsPostResponsesContentApplicationJsonSchemaDataBeneficiaryDetailsIntermediaryBank, optional, nullable) — Intermediary bank to route the transfer through. Null when the rail has none.
- `ach_routing_number` (string, optional, nullable) — Routing number to use for ACH transfers. Null when not applicable.
- `wire_routing_number` (string, optional, nullable) — Routing number to use for wire transfers. Null when not applicable.

### PaymentsStatementsPostResponsesContentApplicationJsonSchemaDataBeneficiaryDetailsIntermediaryBank

Intermediary bank to route the transfer through. Null when the rail has none.

- `swift` (string, optional, nullable) — SWIFT/BIC code of the intermediary bank.
- `bank_name` (string, optional, nullable) — Name of the intermediary bank.

## Examples

**Request**

```json
{
  "data": {
    "payment": {
      "country": "GB",
      "currency": "GBP"
    },
    "invoice_ids": [
      "34d7Y48Ymu44g66fghN9F",
      "BHF2gkMEMT8D9UQDmty66"
    ]
  }
}
```

**Response**

```json
{
  "data": {
    "id": "34d7Y48Ymu44g66fghN9F",
    "amount": "1500.00",
    "status": "PROCESSING",
    "invoices": [
      {
        "id": "34d7Y48Ymu44g66fghN9F",
        "amount": "500.00",
        "currency": "USD",
        "label": "INV-2024-3",
        "is_auto_added": false
      }
    ],
    "amount_due": "1200.00",
    "payment_currency": "USD",
    "paid_at": "2022-05-24T09:38:46.235Z",
    "reference": "DEEL-REF-0001",
    "created_at": "2022-05-24T09:38:46.235Z",
    "payment_method": "bank_transfer",
    "balance_applied": "300.00",
    "beneficiary_details": {
      "iban": "GB29NWBK60161331926819",
      "swift": "NWBKGB2L",
      "address": "100 Main St, San Francisco, CA 94105, United States",
      "country": "GB",
      "bsb_code": "082-902",
      "currency": "USD",
      "bank_code": "001",
      "bank_name": "JPMorgan Chase",
      "ifsc_code": "CHAS0INBX01",
      "sort_code": "04-00-04",
      "branch_code": "00012",
      "account_type": "Checking",
      "bank_address": "200 King Street West, Toronto, ON M5H 3T4, Canada",
      "account_holder": "Deel Inc.",
      "account_number": "1234567890",
      "routing_number": "026073150",
      "intermediary_bank": {
        "swift": "CHASUS33",
        "bank_name": "JPMorgan Chase Bank, N.A."
      },
      "ach_routing_number": "028000024",
      "wire_routing_number": "021000021"
    },
    "fee_credits_applied": "50.00"
  }
}
```

**SDK Code**

```python
import requests

url = "https://api.letsdeel.com/rest/payments/statements"

payload = { "data": {
        "payment": {
            "country": "GB",
            "currency": "GBP"
        },
        "invoice_ids": ["34d7Y48Ymu44g66fghN9F", "BHF2gkMEMT8D9UQDmty66"]
    } }
headers = {
    "Idempotency-Key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript
const url = 'https://api.letsdeel.com/rest/payments/statements';
const options = {
  method: 'POST',
  headers: {
    'Idempotency-Key': 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"data":{"payment":{"country":"GB","currency":"GBP"},"invoice_ids":["34d7Y48Ymu44g66fghN9F","BHF2gkMEMT8D9UQDmty66"]}}'
};

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

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.letsdeel.com/rest/payments/statements"

	payload := strings.NewReader("{\n  \"data\": {\n    \"payment\": {\n      \"country\": \"GB\",\n      \"currency\": \"GBP\"\n    },\n    \"invoice_ids\": [\n      \"34d7Y48Ymu44g66fghN9F\",\n      \"BHF2gkMEMT8D9UQDmty66\"\n    ]\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Idempotency-Key", "a1b2c3d4-e5f6-7890-abcd-ef1234567890")
	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.letsdeel.com/rest/payments/statements")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"data\": {\n    \"payment\": {\n      \"country\": \"GB\",\n      \"currency\": \"GBP\"\n    },\n    \"invoice_ids\": [\n      \"34d7Y48Ymu44g66fghN9F\",\n      \"BHF2gkMEMT8D9UQDmty66\"\n    ]\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.letsdeel.com/rest/payments/statements")
  .header("Idempotency-Key", "a1b2c3d4-e5f6-7890-abcd-ef1234567890")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"data\": {\n    \"payment\": {\n      \"country\": \"GB\",\n      \"currency\": \"GBP\"\n    },\n    \"invoice_ids\": [\n      \"34d7Y48Ymu44g66fghN9F\",\n      \"BHF2gkMEMT8D9UQDmty66\"\n    ]\n  }\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.letsdeel.com/rest/payments/statements', [
  'body' => '{
  "data": {
    "payment": {
      "country": "GB",
      "currency": "GBP"
    },
    "invoice_ids": [
      "34d7Y48Ymu44g66fghN9F",
      "BHF2gkMEMT8D9UQDmty66"
    ]
  }
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'Idempotency-Key' => 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.letsdeel.com/rest/payments/statements");
var request = new RestRequest(Method.POST);
request.AddHeader("Idempotency-Key", "a1b2c3d4-e5f6-7890-abcd-ef1234567890");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"data\": {\n    \"payment\": {\n      \"country\": \"GB\",\n      \"currency\": \"GBP\"\n    },\n    \"invoice_ids\": [\n      \"34d7Y48Ymu44g66fghN9F\",\n      \"BHF2gkMEMT8D9UQDmty66\"\n    ]\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Idempotency-Key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["data": [
    "payment": [
      "country": "GB",
      "currency": "GBP"
    ],
    "invoice_ids": ["34d7Y48Ymu44g66fghN9F", "BHF2gkMEMT8D9UQDmty66"]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.letsdeel.com/rest/payments/statements")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```