Batch Create Debts
curl --request POST \
--url https://getbill.io/external-api/v1/debts/batch \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"batch_name": "<string>",
"accept_expensive_destination": true,
"detect_civility": true,
"validate_emails": true,
"debts": [
{
"firstname": "<string>",
"lastname": "<string>",
"civility": "<string>",
"phone": "<string>",
"amount": 123,
"currency": "<string>",
"email": "<string>",
"birthdate": "<string>",
"object": "<string>",
"internal_id": "<string>",
"invoice_reference": "<string>",
"credited_invoice_reference": "<string>",
"debtor_reference": "<string>",
"invoice_date": "<string>",
"due_date": "<string>",
"address": "<string>",
"iban": "<string>",
"company": "<string>",
"debtor_company": "<string>",
"street_address": "<string>",
"street_number": "<string>",
"postal_code": "<string>",
"city": "<string>",
"country": "<string>",
"payment_link": "<string>",
"timeline_id": "<string>",
"timeline_start_mode": "<string>",
"metadata": {},
"temp_id": "<string>",
"accept_expensive_destination": true
}
]
}
'import requests
url = "https://getbill.io/external-api/v1/debts/batch"
payload = {
"batch_name": "<string>",
"accept_expensive_destination": True,
"detect_civility": True,
"validate_emails": True,
"debts": [
{
"firstname": "<string>",
"lastname": "<string>",
"civility": "<string>",
"phone": "<string>",
"amount": 123,
"currency": "<string>",
"email": "<string>",
"birthdate": "<string>",
"object": "<string>",
"internal_id": "<string>",
"invoice_reference": "<string>",
"credited_invoice_reference": "<string>",
"debtor_reference": "<string>",
"invoice_date": "<string>",
"due_date": "<string>",
"address": "<string>",
"iban": "<string>",
"company": "<string>",
"debtor_company": "<string>",
"street_address": "<string>",
"street_number": "<string>",
"postal_code": "<string>",
"city": "<string>",
"country": "<string>",
"payment_link": "<string>",
"timeline_id": "<string>",
"timeline_start_mode": "<string>",
"metadata": {},
"temp_id": "<string>",
"accept_expensive_destination": True
}
]
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({
batch_name: '<string>',
accept_expensive_destination: true,
detect_civility: true,
validate_emails: true,
debts: [
{
firstname: '<string>',
lastname: '<string>',
civility: '<string>',
phone: '<string>',
amount: 123,
currency: '<string>',
email: '<string>',
birthdate: '<string>',
object: '<string>',
internal_id: '<string>',
invoice_reference: '<string>',
credited_invoice_reference: '<string>',
debtor_reference: '<string>',
invoice_date: '<string>',
due_date: '<string>',
address: '<string>',
iban: '<string>',
company: '<string>',
debtor_company: '<string>',
street_address: '<string>',
street_number: '<string>',
postal_code: '<string>',
city: '<string>',
country: '<string>',
payment_link: '<string>',
timeline_id: '<string>',
timeline_start_mode: '<string>',
metadata: {},
temp_id: '<string>',
accept_expensive_destination: true
}
]
})
};
fetch('https://getbill.io/external-api/v1/debts/batch', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://getbill.io/external-api/v1/debts/batch",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'batch_name' => '<string>',
'accept_expensive_destination' => true,
'detect_civility' => true,
'validate_emails' => true,
'debts' => [
[
'firstname' => '<string>',
'lastname' => '<string>',
'civility' => '<string>',
'phone' => '<string>',
'amount' => 123,
'currency' => '<string>',
'email' => '<string>',
'birthdate' => '<string>',
'object' => '<string>',
'internal_id' => '<string>',
'invoice_reference' => '<string>',
'credited_invoice_reference' => '<string>',
'debtor_reference' => '<string>',
'invoice_date' => '<string>',
'due_date' => '<string>',
'address' => '<string>',
'iban' => '<string>',
'company' => '<string>',
'debtor_company' => '<string>',
'street_address' => '<string>',
'street_number' => '<string>',
'postal_code' => '<string>',
'city' => '<string>',
'country' => '<string>',
'payment_link' => '<string>',
'timeline_id' => '<string>',
'timeline_start_mode' => '<string>',
'metadata' => [
],
'temp_id' => '<string>',
'accept_expensive_destination' => true
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://getbill.io/external-api/v1/debts/batch"
payload := strings.NewReader("{\n \"batch_name\": \"<string>\",\n \"accept_expensive_destination\": true,\n \"detect_civility\": true,\n \"validate_emails\": true,\n \"debts\": [\n {\n \"firstname\": \"<string>\",\n \"lastname\": \"<string>\",\n \"civility\": \"<string>\",\n \"phone\": \"<string>\",\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"email\": \"<string>\",\n \"birthdate\": \"<string>\",\n \"object\": \"<string>\",\n \"internal_id\": \"<string>\",\n \"invoice_reference\": \"<string>\",\n \"credited_invoice_reference\": \"<string>\",\n \"debtor_reference\": \"<string>\",\n \"invoice_date\": \"<string>\",\n \"due_date\": \"<string>\",\n \"address\": \"<string>\",\n \"iban\": \"<string>\",\n \"company\": \"<string>\",\n \"debtor_company\": \"<string>\",\n \"street_address\": \"<string>\",\n \"street_number\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"city\": \"<string>\",\n \"country\": \"<string>\",\n \"payment_link\": \"<string>\",\n \"timeline_id\": \"<string>\",\n \"timeline_start_mode\": \"<string>\",\n \"metadata\": {},\n \"temp_id\": \"<string>\",\n \"accept_expensive_destination\": true\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://getbill.io/external-api/v1/debts/batch")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"batch_name\": \"<string>\",\n \"accept_expensive_destination\": true,\n \"detect_civility\": true,\n \"validate_emails\": true,\n \"debts\": [\n {\n \"firstname\": \"<string>\",\n \"lastname\": \"<string>\",\n \"civility\": \"<string>\",\n \"phone\": \"<string>\",\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"email\": \"<string>\",\n \"birthdate\": \"<string>\",\n \"object\": \"<string>\",\n \"internal_id\": \"<string>\",\n \"invoice_reference\": \"<string>\",\n \"credited_invoice_reference\": \"<string>\",\n \"debtor_reference\": \"<string>\",\n \"invoice_date\": \"<string>\",\n \"due_date\": \"<string>\",\n \"address\": \"<string>\",\n \"iban\": \"<string>\",\n \"company\": \"<string>\",\n \"debtor_company\": \"<string>\",\n \"street_address\": \"<string>\",\n \"street_number\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"city\": \"<string>\",\n \"country\": \"<string>\",\n \"payment_link\": \"<string>\",\n \"timeline_id\": \"<string>\",\n \"timeline_start_mode\": \"<string>\",\n \"metadata\": {},\n \"temp_id\": \"<string>\",\n \"accept_expensive_destination\": true\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://getbill.io/external-api/v1/debts/batch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"batch_name\": \"<string>\",\n \"accept_expensive_destination\": true,\n \"detect_civility\": true,\n \"validate_emails\": true,\n \"debts\": [\n {\n \"firstname\": \"<string>\",\n \"lastname\": \"<string>\",\n \"civility\": \"<string>\",\n \"phone\": \"<string>\",\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"email\": \"<string>\",\n \"birthdate\": \"<string>\",\n \"object\": \"<string>\",\n \"internal_id\": \"<string>\",\n \"invoice_reference\": \"<string>\",\n \"credited_invoice_reference\": \"<string>\",\n \"debtor_reference\": \"<string>\",\n \"invoice_date\": \"<string>\",\n \"due_date\": \"<string>\",\n \"address\": \"<string>\",\n \"iban\": \"<string>\",\n \"company\": \"<string>\",\n \"debtor_company\": \"<string>\",\n \"street_address\": \"<string>\",\n \"street_number\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"city\": \"<string>\",\n \"country\": \"<string>\",\n \"payment_link\": \"<string>\",\n \"timeline_id\": \"<string>\",\n \"timeline_start_mode\": \"<string>\",\n \"metadata\": {},\n \"temp_id\": \"<string>\",\n \"accept_expensive_destination\": true\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"error": false,
"message": "Batch operation completed",
"data": {
"import_id": "enc_imp_abc123xyz",
"created": [
{
"index": 0,
"temp_id": "import-001",
"debt_id": "abc123def456",
"status": "valid",
"data": {
"firstname": "John",
"lastname": "Doe",
"phone": "+33123456789",
"email": "john.doe@example.com",
"amount": 1250.00,
"currency": "EUR"
}
},
{
"index": 1,
"temp_id": "import-002",
"debt_id": "ghi789jkl012",
"status": "valid",
"data": {
"firstname": "Jane",
"lastname": "Smith",
"phone": "+33987654321",
"email": "jane.smith@example.com",
"amount": 750.00,
"currency": "EUR"
}
}
],
"failed": [],
"skipped": [],
"summary": {
"total": 2,
"created": 2,
"failed": 0,
"skipped": 0,
"valid": 2,
"error": 0,
"email_validation": {
"valid": 0,
"invalid": 0,
"unverifiable": 0,
"charged": 0
}
}
}
}
Debts API
Batch Create Debts
Create multiple debts and credit notes in a single request
POST
/
external-api
/
v1
/
debts
/
batch
Batch Create Debts
curl --request POST \
--url https://getbill.io/external-api/v1/debts/batch \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"batch_name": "<string>",
"accept_expensive_destination": true,
"detect_civility": true,
"validate_emails": true,
"debts": [
{
"firstname": "<string>",
"lastname": "<string>",
"civility": "<string>",
"phone": "<string>",
"amount": 123,
"currency": "<string>",
"email": "<string>",
"birthdate": "<string>",
"object": "<string>",
"internal_id": "<string>",
"invoice_reference": "<string>",
"credited_invoice_reference": "<string>",
"debtor_reference": "<string>",
"invoice_date": "<string>",
"due_date": "<string>",
"address": "<string>",
"iban": "<string>",
"company": "<string>",
"debtor_company": "<string>",
"street_address": "<string>",
"street_number": "<string>",
"postal_code": "<string>",
"city": "<string>",
"country": "<string>",
"payment_link": "<string>",
"timeline_id": "<string>",
"timeline_start_mode": "<string>",
"metadata": {},
"temp_id": "<string>",
"accept_expensive_destination": true
}
]
}
'import requests
url = "https://getbill.io/external-api/v1/debts/batch"
payload = {
"batch_name": "<string>",
"accept_expensive_destination": True,
"detect_civility": True,
"validate_emails": True,
"debts": [
{
"firstname": "<string>",
"lastname": "<string>",
"civility": "<string>",
"phone": "<string>",
"amount": 123,
"currency": "<string>",
"email": "<string>",
"birthdate": "<string>",
"object": "<string>",
"internal_id": "<string>",
"invoice_reference": "<string>",
"credited_invoice_reference": "<string>",
"debtor_reference": "<string>",
"invoice_date": "<string>",
"due_date": "<string>",
"address": "<string>",
"iban": "<string>",
"company": "<string>",
"debtor_company": "<string>",
"street_address": "<string>",
"street_number": "<string>",
"postal_code": "<string>",
"city": "<string>",
"country": "<string>",
"payment_link": "<string>",
"timeline_id": "<string>",
"timeline_start_mode": "<string>",
"metadata": {},
"temp_id": "<string>",
"accept_expensive_destination": True
}
]
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({
batch_name: '<string>',
accept_expensive_destination: true,
detect_civility: true,
validate_emails: true,
debts: [
{
firstname: '<string>',
lastname: '<string>',
civility: '<string>',
phone: '<string>',
amount: 123,
currency: '<string>',
email: '<string>',
birthdate: '<string>',
object: '<string>',
internal_id: '<string>',
invoice_reference: '<string>',
credited_invoice_reference: '<string>',
debtor_reference: '<string>',
invoice_date: '<string>',
due_date: '<string>',
address: '<string>',
iban: '<string>',
company: '<string>',
debtor_company: '<string>',
street_address: '<string>',
street_number: '<string>',
postal_code: '<string>',
city: '<string>',
country: '<string>',
payment_link: '<string>',
timeline_id: '<string>',
timeline_start_mode: '<string>',
metadata: {},
temp_id: '<string>',
accept_expensive_destination: true
}
]
})
};
fetch('https://getbill.io/external-api/v1/debts/batch', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://getbill.io/external-api/v1/debts/batch",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'batch_name' => '<string>',
'accept_expensive_destination' => true,
'detect_civility' => true,
'validate_emails' => true,
'debts' => [
[
'firstname' => '<string>',
'lastname' => '<string>',
'civility' => '<string>',
'phone' => '<string>',
'amount' => 123,
'currency' => '<string>',
'email' => '<string>',
'birthdate' => '<string>',
'object' => '<string>',
'internal_id' => '<string>',
'invoice_reference' => '<string>',
'credited_invoice_reference' => '<string>',
'debtor_reference' => '<string>',
'invoice_date' => '<string>',
'due_date' => '<string>',
'address' => '<string>',
'iban' => '<string>',
'company' => '<string>',
'debtor_company' => '<string>',
'street_address' => '<string>',
'street_number' => '<string>',
'postal_code' => '<string>',
'city' => '<string>',
'country' => '<string>',
'payment_link' => '<string>',
'timeline_id' => '<string>',
'timeline_start_mode' => '<string>',
'metadata' => [
],
'temp_id' => '<string>',
'accept_expensive_destination' => true
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://getbill.io/external-api/v1/debts/batch"
payload := strings.NewReader("{\n \"batch_name\": \"<string>\",\n \"accept_expensive_destination\": true,\n \"detect_civility\": true,\n \"validate_emails\": true,\n \"debts\": [\n {\n \"firstname\": \"<string>\",\n \"lastname\": \"<string>\",\n \"civility\": \"<string>\",\n \"phone\": \"<string>\",\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"email\": \"<string>\",\n \"birthdate\": \"<string>\",\n \"object\": \"<string>\",\n \"internal_id\": \"<string>\",\n \"invoice_reference\": \"<string>\",\n \"credited_invoice_reference\": \"<string>\",\n \"debtor_reference\": \"<string>\",\n \"invoice_date\": \"<string>\",\n \"due_date\": \"<string>\",\n \"address\": \"<string>\",\n \"iban\": \"<string>\",\n \"company\": \"<string>\",\n \"debtor_company\": \"<string>\",\n \"street_address\": \"<string>\",\n \"street_number\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"city\": \"<string>\",\n \"country\": \"<string>\",\n \"payment_link\": \"<string>\",\n \"timeline_id\": \"<string>\",\n \"timeline_start_mode\": \"<string>\",\n \"metadata\": {},\n \"temp_id\": \"<string>\",\n \"accept_expensive_destination\": true\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://getbill.io/external-api/v1/debts/batch")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"batch_name\": \"<string>\",\n \"accept_expensive_destination\": true,\n \"detect_civility\": true,\n \"validate_emails\": true,\n \"debts\": [\n {\n \"firstname\": \"<string>\",\n \"lastname\": \"<string>\",\n \"civility\": \"<string>\",\n \"phone\": \"<string>\",\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"email\": \"<string>\",\n \"birthdate\": \"<string>\",\n \"object\": \"<string>\",\n \"internal_id\": \"<string>\",\n \"invoice_reference\": \"<string>\",\n \"credited_invoice_reference\": \"<string>\",\n \"debtor_reference\": \"<string>\",\n \"invoice_date\": \"<string>\",\n \"due_date\": \"<string>\",\n \"address\": \"<string>\",\n \"iban\": \"<string>\",\n \"company\": \"<string>\",\n \"debtor_company\": \"<string>\",\n \"street_address\": \"<string>\",\n \"street_number\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"city\": \"<string>\",\n \"country\": \"<string>\",\n \"payment_link\": \"<string>\",\n \"timeline_id\": \"<string>\",\n \"timeline_start_mode\": \"<string>\",\n \"metadata\": {},\n \"temp_id\": \"<string>\",\n \"accept_expensive_destination\": true\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://getbill.io/external-api/v1/debts/batch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"batch_name\": \"<string>\",\n \"accept_expensive_destination\": true,\n \"detect_civility\": true,\n \"validate_emails\": true,\n \"debts\": [\n {\n \"firstname\": \"<string>\",\n \"lastname\": \"<string>\",\n \"civility\": \"<string>\",\n \"phone\": \"<string>\",\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"email\": \"<string>\",\n \"birthdate\": \"<string>\",\n \"object\": \"<string>\",\n \"internal_id\": \"<string>\",\n \"invoice_reference\": \"<string>\",\n \"credited_invoice_reference\": \"<string>\",\n \"debtor_reference\": \"<string>\",\n \"invoice_date\": \"<string>\",\n \"due_date\": \"<string>\",\n \"address\": \"<string>\",\n \"iban\": \"<string>\",\n \"company\": \"<string>\",\n \"debtor_company\": \"<string>\",\n \"street_address\": \"<string>\",\n \"street_number\": \"<string>\",\n \"postal_code\": \"<string>\",\n \"city\": \"<string>\",\n \"country\": \"<string>\",\n \"payment_link\": \"<string>\",\n \"timeline_id\": \"<string>\",\n \"timeline_start_mode\": \"<string>\",\n \"metadata\": {},\n \"temp_id\": \"<string>\",\n \"accept_expensive_destination\": true\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"error": false,
"message": "Batch operation completed",
"data": {
"import_id": "enc_imp_abc123xyz",
"created": [
{
"index": 0,
"temp_id": "import-001",
"debt_id": "abc123def456",
"status": "valid",
"data": {
"firstname": "John",
"lastname": "Doe",
"phone": "+33123456789",
"email": "john.doe@example.com",
"amount": 1250.00,
"currency": "EUR"
}
},
{
"index": 1,
"temp_id": "import-002",
"debt_id": "ghi789jkl012",
"status": "valid",
"data": {
"firstname": "Jane",
"lastname": "Smith",
"phone": "+33987654321",
"email": "jane.smith@example.com",
"amount": 750.00,
"currency": "EUR"
}
}
],
"failed": [],
"skipped": [],
"summary": {
"total": 2,
"created": 2,
"failed": 0,
"skipped": 0,
"valid": 2,
"error": 0,
"email_validation": {
"valid": 0,
"invalid": 0,
"unverifiable": 0,
"charged": 0
}
}
}
}
Overview
This endpoint creates multiple debts and credit notes in a single API call. It’s designed for bulk imports and can process up to 1,000 rows per request. Each row is validated individually, and the endpoint returns both successful creations and any failures.Authentication
Requires a valid OAuth 2.0 access token with thedebts:write scope.
Request
string
required
Bearer token for authentication
string
required
Must be
application/jsonRequest Body
string
Custom name for this import batch (optional). Appears in the dashboard import filter. Default: “API Batch - DD/MM/YYYY HH:mm”
boolean
Default choice for costly phone destinations in this batch.
true permits phone communications; false restricts SMS, RCS, calls, WhatsApp, and voicemail while retaining the debt and its email/postal reminders. A per-debt explicit boolean overrides this value, including false overriding a batch-level true. For debt synchronized through a campaign, the GetBill campaign configuration takes priority.boolean
Enables automatic civility/title completion for created debts where
civility is missing and firstname is present. Default: true. Charged at 1 credit per 100 debts needing civility detection, rounded up.boolean
Enables email deliverability validation for created debts in the batch. Default:
false. Emails are deduplicated before validation. Charged at 1 credit per 5 billable validation results. Invalid addresses are saved but marked as suppressed to prevent sending.array
required
Array of debt or credit note objects. Maximum 1,000 rows per request. Each object has the same structure as the Create Debt endpoint.
Show row fields
Show row fields
string
Debtor’s first name. Required for debts; optional for credit notes.
string
Debtor’s last name. Required for debts; optional for credit notes.
string
Civility/title (optional). Possible values:
"Mr" or "Ms"string
Debtor’s phone number (international format recommended). For debts, at least one of phone or email must be valid. Optional for credit notes.
number
required
Positive debt amount or negative credit note amount. Zero is invalid.
string
required
Currency code (ISO 4217 format, e.g., “EUR”, “USD”)
string
Debtor’s email address. For debts, at least one of phone or email must be valid. Optional for credit notes.
string
Debtor’s birth date in YYYY-MM-DD format (optional)
string
Description of what the debt is for (optional)
string
Your internal reference ID. For a credit note, either
internal_id or invoice_reference is required as its stable identity.string
Invoice reference number. For a credit note, either
internal_id or invoice_reference is required as its stable identity.string
Invoice reference to credit. For a credit note, either
credited_invoice_reference or debtor_reference is required as its target.string
Your reference for the debtor. For a credit note, either
credited_invoice_reference or debtor_reference is required as its target. When a credit note targets only debtor_reference, provide timeline_id unless the row can use the batch’s resolved timeline or your company has exactly one timeline.string
Original invoice date in YYYY-MM-DD format (optional)
string
Payment due date in YYYY-MM-DD format (optional)
string
Debtor’s full address (optional)
string
IBAN where payment should be made (optional)
string
Name of the creditor company you are collecting on behalf of (optional). Only used by debt collection agencies who manage debts for multiple client companies. If you are collecting your own debts, leave this field empty.
string
Debtor’s company name, if the debtor is a business (optional)
string
Street address (optional). Can be used with other address fields for structured address data
string
Street number (optional)
string
Postal/ZIP code (optional)
string
City name (optional)
string
Country code in ISO 3166-1 alpha-2 format, e.g. “FR”, “US” (optional)
string
Custom payment link URL for this debt (optional)
string
Encrypted timeline ID to enable AI-powered collection workflows (optional). It is required for a credit note that targets only
debtor_reference when no unambiguous batch or company timeline can be resolved. See the Using Timelines guide for how to obtain timeline IDs (requires administrator access).string
When to start timeline processing (optional):
"immediate" (default) or "next_day"object
Custom metadata object for storing arbitrary JSON data (optional). Use this to store any additional information that your system needs to track. Returned in API responses and webhook payloads.
string
Temporary ID you can use to track which debt this is in the response (optional)
boolean
Explicit choice for costly phone destinations on this debt. It overrides the batch-level value, including
false overriding true. For a new costly phone, an omitted value restricts phone communications and produces a warning rather than failing the debt.A batch may mix debts and credit notes. For a credit note, send a negative
amount, one identity field (internal_id or invoice_reference), and one target field (credited_invoice_reference or debtor_reference). A debtor-only target must resolve an unambiguous timeline from timeline_id, the batch, or the company’s single timeline. Debtor names and contact details are not required.Example Request
curl -X POST "/external-api/v1/debts/batch" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"batch_name": "January 2025 Invoices",
"detect_civility": true,
"validate_emails": false,
"debts": [
{
"temp_id": "import-001",
"firstname": "John",
"lastname": "Doe",
"civility": "Mr",
"phone": "+33123456789",
"email": "john.doe@example.com",
"amount": 1250.00,
"currency": "EUR",
"object": "Invoice #INV-2024-001",
"internal_id": "DEBT-2024-001",
"due_date": "2023-12-31",
"timeline_id": "YOUR_TIMELINE_ID",
"timeline_start_mode": "next_day",
"metadata": {"crm_id": "CRM-001", "source": "batch_import"}
},
{
"temp_id": "import-002",
"firstname": "Jane",
"lastname": "Smith",
"civility": "Ms",
"phone": "+33987654321",
"email": "jane.smith@example.com",
"amount": 750.00,
"currency": "EUR",
"object": "Invoice #INV-2024-002",
"internal_id": "DEBT-2024-002",
"due_date": "2023-12-31",
"timeline_id": "YOUR_TIMELINE_ID",
"timeline_start_mode": "immediate",
"metadata": {"crm_id": "CRM-002", "source": "batch_import"}
}
]
}'
const debtsData = {
debts: [
{
temp_id: "import-001",
firstname: "John",
lastname: "Doe",
civility: "Mr",
phone: "+33123456789",
email: "john.doe@example.com",
amount: 1250.00,
currency: "EUR",
object: "Invoice #INV-2024-001",
internal_id: "DEBT-2024-001",
due_date: "2023-12-31",
timeline_id: "YOUR_TIMELINE_ID",
timeline_start_mode: "next_day",
metadata: { crm_id: "CRM-001", source: "batch_import" }
},
{
temp_id: "import-002",
firstname: "Jane",
lastname: "Smith",
civility: "Ms",
phone: "+33987654321",
email: "jane.smith@example.com",
amount: 750.00,
currency: "EUR",
object: "Invoice #INV-2024-002",
internal_id: "DEBT-2024-002",
due_date: "2023-12-31",
timeline_id: "YOUR_TIMELINE_ID",
timeline_start_mode: "immediate",
metadata: { crm_id: "CRM-002", source: "batch_import" }
}
]
};
const response = await fetch('/external-api/v1/debts/batch', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify(debtsData)
});
const result = await response.json();
import requests
debts_data = {
"debts": [
{
"temp_id": "import-001",
"firstname": "John",
"lastname": "Doe",
"civility": "Mr",
"phone": "+33123456789",
"email": "john.doe@example.com",
"amount": 1250.00,
"currency": "EUR",
"object": "Invoice #INV-2024-001",
"internal_id": "DEBT-2024-001",
"due_date": "2023-12-31",
"timeline_id": "YOUR_TIMELINE_ID",
"timeline_start_mode": "next_day",
"metadata": {"crm_id": "CRM-001", "source": "batch_import"}
},
{
"temp_id": "import-002",
"firstname": "Jane",
"lastname": "Smith",
"civility": "Ms",
"phone": "+33987654321",
"email": "jane.smith@example.com",
"amount": 750.00,
"currency": "EUR",
"object": "Invoice #INV-2024-002",
"internal_id": "DEBT-2024-002",
"due_date": "2023-12-31",
"timeline_id": "YOUR_TIMELINE_ID",
"timeline_start_mode": "immediate",
"metadata": {"crm_id": "CRM-002", "source": "batch_import"}
}
]
}
headers = {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
response = requests.post(
'/external-api/v1/debts/batch',
headers=headers,
json=debts_data
)
result = response.json()
Response
boolean
Always
false for successful batch requests (even if some individual debts failed)string
Success message
object
Batch operation results
Show data object
Show data object
string
Encrypted ID of the Import record created for this batch. Use this to filter debts by import in the dashboard or track batches programmatically.
array
Array of successfully created debts
Show created item
Show created item
integer
Original position in the input array
string
Your temporary ID (if provided)
string
Encrypted debt ID for a created debt. Omitted for credit notes.
string
"debt" or "credit_note" when the batch contains credit notesinteger
Credit note identifier. Present only when
type is "credit_note".string
Credit note identity supplied through
internal_id or invoice_referencestring
"applied" or "pending" for credit notesnumber
Remaining accounting balance after a credit note, or
null while pendingnumber
Remaining collectible amount after a credit note, or
null while pendingobject
Original input data for this debt
object
Present only when
validate_emails is true and the created debt has an email address. Contains status (valid, invalid, or unverifiable), reason, charged, and email.integer
Number of credits an AI call to this debtor will cost (25 for France, higher for expensive destinations)
array
Array of debts that failed validation or creation
Show failed item
Show failed item
integer
Original position in the input array
string
Always
"error" for failed debtsobject
Detailed validation errors by field. Common error fields:
contact: At least one valid contact method requiredphone: Invalid phone number format or unsupported prefixemail: Invalid email formatamount: Invalid or zero amountfirstname: First name is required for debtslastname: Last name is required for debtscurrency: Currency is required
object
Original input data for this debt (so you can identify which row failed)
array
object
Summary statistics
Show summary
Show summary
integer
Total debts in the batch request
integer
Number successfully created
integer
Number that failed validation
integer
Number of rows skipped (empty/instruction rows)
integer
Number of valid rows (same as created)
integer
Number of rows with errors (same as failed)
object
Email validation summary for this batch. Contains
valid, invalid, unverifiable, and charged counts. Counts are based on unique email validations, not duplicate rows.Success Response
{
"error": false,
"message": "Batch operation completed",
"data": {
"import_id": "enc_imp_abc123xyz",
"created": [
{
"index": 0,
"temp_id": "import-001",
"debt_id": "abc123def456",
"status": "valid",
"data": {
"firstname": "John",
"lastname": "Doe",
"phone": "+33123456789",
"email": "john.doe@example.com",
"amount": 1250.00,
"currency": "EUR"
}
},
{
"index": 1,
"temp_id": "import-002",
"debt_id": "ghi789jkl012",
"status": "valid",
"data": {
"firstname": "Jane",
"lastname": "Smith",
"phone": "+33987654321",
"email": "jane.smith@example.com",
"amount": 750.00,
"currency": "EUR"
}
}
],
"failed": [],
"skipped": [],
"summary": {
"total": 2,
"created": 2,
"failed": 0,
"skipped": 0,
"valid": 2,
"error": 0,
"email_validation": {
"valid": 0,
"invalid": 0,
"unverifiable": 0,
"charged": 0
}
}
}
}
Partial Success Response
{
"error": false,
"message": "Batch operation completed",
"data": {
"import_id": "enc_imp_def456ghi",
"created": [
{
"index": 0,
"temp_id": "import-001",
"debt_id": "abc123def456",
"status": "valid",
"data": {
"firstname": "John",
"lastname": "Doe",
"phone": "+33123456789",
"email": "john.doe@example.com",
"amount": 1250.00,
"currency": "EUR"
}
}
],
"failed": [
{
"index": 1,
"status": "error",
"errors": {
"phone": "Invalid phone number",
"contact": "At least one valid contact method (email or phone) is required"
},
"data": {
"firstname": "Jane",
"lastname": "Smith",
"phone": "0690123456",
"email": "invalid-email",
"amount": 750.00,
"currency": "EUR"
}
},
{
"index": 3,
"status": "error",
"errors": {
"firstname": "First name is required",
"lastname": "Last name is required",
"amount": "Valid amount (greater than 0) is required"
},
"data": {
"phone": "+33123456789",
"amount": 0,
"currency": "EUR"
}
},
{
"index": 2,
"errors": [
"Invalid phone number: \"12345\" - phone number too short"
]
},
],
"skipped": [
{
"index": 2,
"reason": "Empty or instruction row",
"data": {}
}
],
"summary": {
"total": 4,
"created": 1,
"failed": 2,
"skipped": 1,
"valid": 1,
"error": 2
}
}
}
Error Responses
{
"error": true,
"message": "No debts provided in payload",
"code": 400
}
{
"error": true,
"message": "Maximum 1000 debts per batch request",
"code": 400
}
{
"error": true,
"message": "Authentication credentials are missing or invalid",
"code": 401
}
{
"error": true,
"message": "Required scope \"debts:write\" not found in token",
"code": 403
}
{
"error": true,
"message": "Failed to process batch request",
"code": 500
}
Validation Rules
Validation Update (2025): Phone number validation is now strictly enforced to match the web interface behavior. Phone numbers are validated using international standards (libphonenumber library). If you were previously sending phone numbers without proper formatting or French overseas mobile numbers (069X prefix), these will now be rejected. You can now use
email as an alternative to phone.Batch Limits
Batch Limits
- Maximum 1,000 debts per batch request
- Each debt is validated individually
- Failed debts don’t stop processing of successful ones
Individual Debt Validation
Individual Debt Validation
Each debt is validated using the same rules as the web import interface:Debt (
amount > 0):firstnameandlastname: Requiredphoneoremail: At least one valid contact method
amount < 0):internal_idorinvoice_reference: Stable credit note identitycredited_invoice_referenceordebtor_reference: Debt targettimeline_id: Required for a debtor-only target when no unambiguous batch or company timeline can be resolved
amount must not be zero and currency must be a valid ISO 4217 code.Debt contact information (at least one required):phoneORemail: At least one must be validphone: Must be a valid phone number. International format recommended (e.g.,+33123456789)- Unsupported: French overseas mobile numbers with 069X prefix (e.g.,
0690123456) - Supported: French mainland, most international numbers, French overseas fixed lines
- Unsupported: French overseas mobile numbers with 069X prefix (e.g.,
email: Must be a valid email format
- Date fields: Must be in YYYY-MM-DD format if provided
phone: Validated and normalized to E.164 format. French numbers without country code are automatically normalized. Invalid phones are rejected with specific error messages.- All other fields are optional
- Empty rows are automatically skipped
- Instruction rows (starting with
*, containing “champs obligatoires”, etc.) are skipped
Expensive Destinations
Expensive Destinations
A costly phone destination does not fail an otherwise valid debt. The debt appears in
created with an expensive_destination_not_accepted item in its warnings array when phone communications are restricted. Email and postal reminders remain available.Set "accept_expensive_destination": true at the batch level for the default, or set it on an individual debt to override the default. This is based on configured pricing, not on every foreign number.Timeline Processing
Timeline Processing
timeline_id: Must be valid and belong to your companytimeline_start_mode: Applies individually to each debt- Invalid timeline IDs are ignored for debts and rejected for credit notes
- Public holidays and excluded days are respected for
next_daymode
Rate Limiting
This endpoint is subject to rate limiting. See the Rate Limits documentation for details. Rate Limit: 50 requests per hour (batch operations) Note: Each batch request can contain up to 1,000 debts, making this much more efficient than individual creation.Best Practices
Use temp_id
Always provide a
temp_id for each debt to easily match responses to your original data.Handle Partial Success
Always check
created, failed, and skipped arrays. Process successful debts, identify why failures occurred using the detailed errors field, and retry or fix validation issues.Batch Size Strategy
While you can send 1,000 debts, consider batches of 100-500 for better error handling and progress tracking.
Validate Before Sending
Pre-validate data on your side to minimize API failures. Key checks: phone and email formats for debts, non-zero amounts, and the required identity and target references for credit notes.
Use Detailed Error Messages
Each failed debt includes the original data and specific field-level errors. Use this to build error reports for manual correction or automated retry logic.
Timeline Assignment
Assign the same
timeline_id to all debts in a batch for consistent AI-powered collection workflows.Monitor Progress
Use the
summary object to track overall success rate and identify issues quickly.Performance Considerations
- All debts in a batch are processed in a single database transaction
- Failed validations don’t affect successful creations
- Expected processing time: ~100-500ms for 100 debts
- Timeline calculations (next_day mode) add minimal overhead
After Batch Creation
Once debts are created via batch:- Store Debt IDs: Map returned
debt_idvalues to yourtemp_idorinternal_id - Process Failures: Review the
failedarray for validation errors. Each failed item includes:- Original data (
datafield) to identify which row failed - Detailed field-level errors (
errorsfield) to understand why - Common fixes: Update invalid phone numbers (avoid 069X), fix email formats, ensure required fields
- Original data (
- Handle Skipped Rows: Check the
skippedarray for empty or instruction rows that were automatically filtered - Monitor Workflows: If timelines are assigned, collection actions will start automatically for successfully created debts
- Track Progress: Use the statistics endpoints to monitor collection progress
Related Endpoints
- Create Debt - Create a single debt
- List Debts - Get all debts for your company
- Update Debt - Modify individual debts
- Get Debt - Retrieve specific debt details