Invoices and payments
Invoices with lines, VAT breakdown and payment state: drafts, issue and payments.
Version v1.1, updated
On this page
An invoice starts as a draft that BIRP computes from its lines and their tax codes. Once issued, it has its number and never changes, and payments record what was paid.
Fields
Send says the field is in responses. Receive says a write accepts it; a reference is sent as an object, such as category for category_id. Totals, VAT, numbers and statuses are computed by BIRP and never received.
List invoices
Lists the invoices of the company.
Scope:
invoices:read.Idempotency: a read; send it as often as you need.
/v1/invoicesParameters
limitinteger, in query- Page size, 1 to 200. Default 50.Default
50 cursorstring, in query- next_cursor of the previous page. Pages are ordered by id.Example
opaque-cursor-example updated_sincestring (date-time), in query- Only records changed at or after this time: ISO 8601 date and time with an offset or Z.Example
2026-09-01T00:00:00Z external_idstring, in query- Identifier in an external system. Requires source.Example
1042 sourcestring, in query- External system of external_id, in lowercase. Requires external_id.Example
woocommerce statusstring, in query- Document status.One of
draft,issued,sent,partially_paid,paid,overdue,cancelled,refundedExampleissued customer_idstring (uuid), in query- Invoices of one customer.Example
00000000-0000-4000-8000-000000000031
curl "https://api.birp.io/v1/invoices" \
-H "Authorization: Bearer $BIRP_API_KEY"const response = await fetch("https://api.birp.io/v1/invoices", {
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
},
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/invoices");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
],
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import requests
response = requests.request(
"GET",
"https://api.birp.io/v1/invoices",
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": [
{
"amount_due": "66.80",
"amount_paid": "60.00",
"buyer": {
"address": "12 rue des Exemples",
"city": "Paris",
"country": "France",
"name": "Epicerie Exemple SARL",
"postal_code": "00000",
"registration_number": "EXAMPLE-0002",
"vat_number": "EXAMPLE-VAT-0002"
},
"created_at": "2026-09-28T09:12:40.000Z",
"currency": "EUR",
"customer_id": "00000000-0000-4000-8000-000000000031",
"due_at": "2026-10-28T00:00:00.000Z",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000061",
"issued_at": "2026-09-28T00:00:00.000Z",
"legal_footer": null,
"lines": [
{
"description": "White bread 500 g",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000071",
"line_total": "64.00",
"lot_number": "EXAMPLE-LOT-0001",
"position": 0,
"product_id": "00000000-0000-4000-8000-000000000012",
"product_kind": "finished_product",
"quantity": "20.0000",
"unit": "pcs",
"unit_price": "3.2000",
"vat_amount": "12.80",
"vat_rate": "20.00"
},
{
"description": "Wheat flour 25 kg",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000072",
"line_total": "50.00",
"lot_number": null,
"position": 1,
"product_id": "00000000-0000-4000-8000-000000000011",
"product_kind": "goods",
"quantity": "4.0000",
"unit": "kg",
"unit_price": "12.5000",
"vat_amount": "0.00",
"vat_rate": "0.00"
}
],
"notes": null,
"number": "EXAMPLE-INV-0098",
"order_id": "00000000-0000-4000-8000-000000000051",
"paid_at": null,
"payment": {
"bank_account": "EXAMPLE-IBAN-0001",
"method": "bank_transfer",
"reference": "EXAMPLE-INV-0098",
"terms_days": 30
},
"payment_status": "partially_paid",
"related_invoice_id": null,
"seller": {
"address": "Str. Exemplului 4",
"city": "Chisinau",
"country": "Moldova",
"name": "Brutaria Exemplu SRL",
"postal_code": "MD-0000",
"registration_number": "EXAMPLE-0001",
"vat_number": "EXAMPLE-VAT-0001"
},
"status": "issued",
"subtotal": "114.00",
"supplied_at": "2026-09-28T00:00:00.000Z",
"total": "126.80",
"total_discount": "0.00",
"total_vat": "12.80",
"type": "invoice",
"updated_at": "2026-09-28T14:05:12.417Z",
"vat_breakdown": [
{
"tax_code": "ZERO",
"taxable_amount": "50.00",
"vat_amount": "0.00",
"vat_rate": "0.00"
},
{
"tax_code": "STANDARD",
"taxable_amount": "64.00",
"vat_amount": "12.80",
"vat_rate": "20.00"
}
],
"vat_exemption_reason": null,
"vat_exemption_text": null
},
{
"amount_due": "0.00",
"amount_paid": "1500.00",
"buyer": {
"address": "Str. Exemplului 1",
"city": "Chisinau",
"country": "Moldova",
"name": "Panificatie Exemplu SRL",
"postal_code": "MD-0000",
"registration_number": "EXAMPLE-0003",
"vat_number": "EXAMPLE-VAT-0003"
},
"created_at": "2026-09-25T10:00:00.000Z",
"currency": "MDL",
"customer_id": "00000000-0000-4000-8000-000000000033",
"due_at": "2026-10-10T00:00:00.000Z",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000062",
"issued_at": "2026-09-25T00:00:00.000Z",
"legal_footer": null,
"lines": [
{
"description": "Wheat flour 25 kg",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000073",
"line_total": "1250.00",
"lot_number": null,
"position": 0,
"product_id": "00000000-0000-4000-8000-000000000011",
"product_kind": "goods",
"quantity": "100.0000",
"unit": "kg",
"unit_price": "12.5000",
"vat_amount": "250.00",
"vat_rate": "20.00"
}
],
"notes": null,
"number": "EXAMPLE-INV-0097",
"order_id": null,
"paid_at": "2026-09-30T00:00:00.000Z",
"payment": {
"bank_account": "EXAMPLE-IBAN-0001",
"method": "bank_transfer",
"reference": "EXAMPLE-INV-0097",
"terms_days": 15
},
"payment_status": "paid",
"related_invoice_id": null,
"seller": {
"address": "Str. Exemplului 4",
"city": "Chisinau",
"country": "Moldova",
"name": "Brutaria Exemplu SRL",
"postal_code": "MD-0000",
"registration_number": "EXAMPLE-0001",
"vat_number": "EXAMPLE-VAT-0001"
},
"status": "issued",
"subtotal": "1250.00",
"supplied_at": "2026-09-25T00:00:00.000Z",
"total": "1500.00",
"total_discount": "0.00",
"total_vat": "250.00",
"type": "invoice",
"updated_at": "2026-09-30T08:00:00.000Z",
"vat_breakdown": [
{
"tax_code": "STANDARD",
"taxable_amount": "1250.00",
"vat_amount": "250.00",
"vat_rate": "20.00"
}
],
"vat_exemption_reason": null,
"vat_exemption_text": null
}
],
"meta": {
"has_more": false,
"limit": 50,
"next_cursor": null
}
}Errors particular to this operation:
422
validation_failed
Get an invoice
Returns one invoice of the company, with its lines, VAT breakdown and payment state.
Scope:
invoices:read.Idempotency: a read; send it as often as you need.
/v1/invoices/{id}Parameters
idrequiredstring (uuid), in path- Invoice identifier.Example
00000000-0000-4000-8000-000000000061
curl "https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061" \
-H "Authorization: Bearer $BIRP_API_KEY"const response = await fetch("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061", {
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
},
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
],
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import requests
response = requests.request(
"GET",
"https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061",
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"amount_due": "66.80",
"amount_paid": "60.00",
"buyer": {
"address": "12 rue des Exemples",
"city": "Paris",
"country": "France",
"name": "Epicerie Exemple SARL",
"postal_code": "00000",
"registration_number": "EXAMPLE-0002",
"vat_number": "EXAMPLE-VAT-0002"
},
"created_at": "2026-09-28T09:12:40.000Z",
"currency": "EUR",
"customer_id": "00000000-0000-4000-8000-000000000031",
"due_at": "2026-10-28T00:00:00.000Z",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000061",
"issued_at": "2026-09-28T00:00:00.000Z",
"legal_footer": null,
"lines": [
{
"description": "White bread 500 g",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000071",
"line_total": "64.00",
"lot_number": "EXAMPLE-LOT-0001",
"position": 0,
"product_id": "00000000-0000-4000-8000-000000000012",
"product_kind": "finished_product",
"quantity": "20.0000",
"unit": "pcs",
"unit_price": "3.2000",
"vat_amount": "12.80",
"vat_rate": "20.00"
},
{
"description": "Wheat flour 25 kg",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000072",
"line_total": "50.00",
"lot_number": null,
"position": 1,
"product_id": "00000000-0000-4000-8000-000000000011",
"product_kind": "goods",
"quantity": "4.0000",
"unit": "kg",
"unit_price": "12.5000",
"vat_amount": "0.00",
"vat_rate": "0.00"
}
],
"notes": null,
"number": "EXAMPLE-INV-0098",
"order_id": "00000000-0000-4000-8000-000000000051",
"paid_at": null,
"payment": {
"bank_account": "EXAMPLE-IBAN-0001",
"method": "bank_transfer",
"reference": "EXAMPLE-INV-0098",
"terms_days": 30
},
"payment_status": "partially_paid",
"related_invoice_id": null,
"seller": {
"address": "Str. Exemplului 4",
"city": "Chisinau",
"country": "Moldova",
"name": "Brutaria Exemplu SRL",
"postal_code": "MD-0000",
"registration_number": "EXAMPLE-0001",
"vat_number": "EXAMPLE-VAT-0001"
},
"status": "issued",
"subtotal": "114.00",
"supplied_at": "2026-09-28T00:00:00.000Z",
"total": "126.80",
"total_discount": "0.00",
"total_vat": "12.80",
"type": "invoice",
"updated_at": "2026-09-28T14:05:12.417Z",
"vat_breakdown": [
{
"tax_code": "ZERO",
"taxable_amount": "50.00",
"vat_amount": "0.00",
"vat_rate": "0.00"
},
{
"tax_code": "STANDARD",
"taxable_amount": "64.00",
"vat_amount": "12.80",
"vat_rate": "20.00"
}
],
"vat_exemption_reason": null,
"vat_exemption_text": null
}
}Errors particular to this operation:
404
not_found
Create a draft invoice
Creates a draft invoice; BIRP computes the line totals, the VAT and the totals.
Scope:
invoices:write.Idempotency:
Idempotency-Keyrequired. See Idempotency.
Each line needs a tax_code from GET /v1/tax-codes. Totals and VAT are never accepted from you.
/v1/invoicesParameters
Idempotency-Keyrequiredstring, in header- Unique value for this request (for example a UUID), 1 to 128 printable ASCII characters. A retry with the same key and the same request gets the stored response for 24 hours, with Idempotency-Replayed: true; the same key with a different request answers 422 idempotency_key_reused. Required on POST, optional on PUT, PATCH and DELETE.Example
00000000-0000-4000-8000-0000000000a1
Request body
application/json
linesrequiredarray of InvoiceLineCreatelines[].unitstring- Required without product. Left out with a product: its default unit.
lines[].productProductReference- A product of the company. Left out: a free line with a description.
lines[].quantityrequiredstring- Decimal string, at most four decimals, above zero.
lines[].tax_coderequiredstring- Tax code under the rules of the company's country, valid at the document date. GET /v1/tax-codes lists them. The rate, and so the VAT, comes from that code; an exempt code gives no VAT.
lines[].unit_pricerequiredstring- Unit price excluding VAT, decimal string, at most four decimals.
lines[].descriptionstring- Required without product. Left out with a product: its name.
notesstring | nullorderReference | null- An order of the company this invoice bills.
order.idstring (uuid)- BIRP id of the record.
order.sourcestring- External system of external_id, in lowercase.
order.external_idstring- Identifier of the record in an external system. Requires source.
currencystring- ISO 4217 code. Left out on create: the company base currency.
customerrequiredReference- The customer billed. Its name, address and fiscal ids become the buyer details of the invoice.
customer.idstring (uuid)- BIRP id of the record.
customer.sourcestring- External system of external_id, in lowercase.
customer.external_idstring- Identifier of the record in an external system. Requires source.
due_datestring | null- Due date, YYYY-MM-DD. Left out: issue date plus payment_terms_days, when given.
issue_datestring- Document date the VAT is computed for, YYYY-MM-DD. Left out: the company today. Issuing sets the issue date again (the issue_date sent then, or the company today) and recomputes the VAT for it.
supply_datestring | null- Date of supply, YYYY-MM-DD.
payment_terms_daysnumber | nullvat_exemption_textstring | null- Legal mention printed with the exemption.
vat_exemption_reasonstring | null- Why VAT is zero, for the whole invoice. A zero-rate code with a right to deduct (export, intra-community, reverse charge) needs the matching reason; otherwise the line answers tax_code_mismatch.One of
intra_community,export,reverse_charge,small_business,other
curl -X POST "https://api.birp.io/v1/invoices" \
-H "Authorization: Bearer $BIRP_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"currency":"EUR","customer":{"id":"00000000-0000-4000-8000-000000000031"},"issue_date":"2026-09-28","lines":[{"product":{"sku":"FP-BREAD-500"},"quantity":"20","tax_code":"STANDARD","unit_price":"3.20"},{"product":{"sku":"SP-FLOUR-25"},"quantity":"4","tax_code":"ZERO","unit_price":"12.50"}],"order":{"id":"00000000-0000-4000-8000-000000000051"},"payment_terms_days":30}'const response = await fetch("https://api.birp.io/v1/invoices", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"currency": "EUR",
"customer": {
"id": "00000000-0000-4000-8000-000000000031"
},
"issue_date": "2026-09-28",
"lines": [
{
"product": {
"sku": "FP-BREAD-500"
},
"quantity": "20",
"tax_code": "STANDARD",
"unit_price": "3.20"
},
{
"product": {
"sku": "SP-FLOUR-25"
},
"quantity": "4",
"tax_code": "ZERO",
"unit_price": "12.50"
}
],
"order": {
"id": "00000000-0000-4000-8000-000000000051"
},
"payment_terms_days": 30
}),
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/invoices");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
"Idempotency-Key: " . bin2hex(random_bytes(16)),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"currency": "EUR",
"customer": {
"id": "00000000-0000-4000-8000-000000000031"
},
"issue_date": "2026-09-28",
"lines": [
{
"product": {
"sku": "FP-BREAD-500"
},
"quantity": "20",
"tax_code": "STANDARD",
"unit_price": "3.20"
},
{
"product": {
"sku": "SP-FLOUR-25"
},
"quantity": "4",
"tax_code": "ZERO",
"unit_price": "12.50"
}
],
"order": {
"id": "00000000-0000-4000-8000-000000000051"
},
"payment_terms_days": 30
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import uuid
import requests
response = requests.request(
"POST",
"https://api.birp.io/v1/invoices",
json={
"currency": "EUR",
"customer": {
"id": "00000000-0000-4000-8000-000000000031"
},
"issue_date": "2026-09-28",
"lines": [
{
"product": {
"sku": "FP-BREAD-500"
},
"quantity": "20",
"tax_code": "STANDARD",
"unit_price": "3.20"
},
{
"product": {
"sku": "SP-FLOUR-25"
},
"quantity": "4",
"tax_code": "ZERO",
"unit_price": "12.50"
}
],
"order": {
"id": "00000000-0000-4000-8000-000000000051"
},
"payment_terms_days": 30
},
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"amount_due": "126.80",
"amount_paid": "0.00",
"buyer": {
"address": "12 rue des Exemples",
"city": "Paris",
"country": "France",
"name": "Epicerie Exemple SARL",
"postal_code": "00000",
"registration_number": "EXAMPLE-0002",
"vat_number": "EXAMPLE-VAT-0002"
},
"created_at": "2026-09-28T09:12:40.000Z",
"currency": "EUR",
"customer_id": "00000000-0000-4000-8000-000000000031",
"due_at": null,
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000061",
"issued_at": "2026-09-28T00:00:00.000Z",
"legal_footer": null,
"lines": [
{
"description": "White bread 500 g",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000071",
"line_total": "64.00",
"lot_number": null,
"position": 0,
"product_id": "00000000-0000-4000-8000-000000000012",
"product_kind": "finished_product",
"quantity": "20.0000",
"unit": "pcs",
"unit_price": "3.2000",
"vat_amount": "12.80",
"vat_rate": "20.00"
},
{
"description": "Wheat flour 25 kg",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000072",
"line_total": "50.00",
"lot_number": null,
"position": 1,
"product_id": "00000000-0000-4000-8000-000000000011",
"product_kind": "goods",
"quantity": "4.0000",
"unit": "kg",
"unit_price": "12.5000",
"vat_amount": "0.00",
"vat_rate": "0.00"
}
],
"notes": null,
"number": null,
"order_id": "00000000-0000-4000-8000-000000000051",
"paid_at": null,
"payment": {
"bank_account": "EXAMPLE-IBAN-0001",
"method": "bank_transfer",
"reference": null,
"terms_days": 30
},
"payment_status": "unpaid",
"related_invoice_id": null,
"seller": {
"address": "Str. Exemplului 4",
"city": "Chisinau",
"country": "Moldova",
"name": "Brutaria Exemplu SRL",
"postal_code": "MD-0000",
"registration_number": "EXAMPLE-0001",
"vat_number": "EXAMPLE-VAT-0001"
},
"status": "draft",
"subtotal": "114.00",
"supplied_at": "2026-09-28T00:00:00.000Z",
"total": "126.80",
"total_discount": "0.00",
"total_vat": "12.80",
"type": "invoice",
"updated_at": "2026-09-28T14:05:12.417Z",
"vat_breakdown": [
{
"tax_code": "ZERO",
"taxable_amount": "50.00",
"vat_amount": "0.00",
"vat_rate": "0.00"
},
{
"tax_code": "STANDARD",
"taxable_amount": "64.00",
"vat_amount": "12.80",
"vat_rate": "20.00"
}
],
"vat_exemption_reason": null,
"vat_exemption_text": null
}
}Errors particular to this operation:
422
company_profile_incomplete422
no_rule_for_date422
reference_not_found422
tax_code_mismatch422
tax_rules_unavailable422
validation_failed
Update a draft invoice
Changes a draft invoice and computes it again.
Scope:
invoices:write.Idempotency:
Idempotency-Keyaccepted and recommended.
lines, when sent, replace all the lines. An issued invoice never changes.
/v1/invoices/{id}Parameters
Idempotency-Keystring, in header- Unique value for this request (for example a UUID), 1 to 128 printable ASCII characters. A retry with the same key and the same request gets the stored response for 24 hours, with Idempotency-Replayed: true; the same key with a different request answers 422 idempotency_key_reused. Required on POST, optional on PUT, PATCH and DELETE.Example
00000000-0000-4000-8000-0000000000a1 idrequiredstring (uuid), in path- Invoice identifier.Example
00000000-0000-4000-8000-000000000061
Request body
application/json
linesarray of InvoiceLineCreatelines[].unitstring- Required without product. Left out with a product: its default unit.
lines[].productProductReference- A product of the company. Left out: a free line with a description.
lines[].quantityrequiredstring- Decimal string, at most four decimals, above zero.
lines[].tax_coderequiredstring- Tax code under the rules of the company's country, valid at the document date. GET /v1/tax-codes lists them. The rate, and so the VAT, comes from that code; an exempt code gives no VAT.
lines[].unit_pricerequiredstring- Unit price excluding VAT, decimal string, at most four decimals.
lines[].descriptionstring- Required without product. Left out with a product: its name.
notesstring | nullorderReference | null- An order of the company this invoice bills.
order.idstring (uuid)- BIRP id of the record.
order.sourcestring- External system of external_id, in lowercase.
order.external_idstring- Identifier of the record in an external system. Requires source.
currencystring- ISO 4217 code. Left out on create: the company base currency.
customerReference- Another record of the company: exactly one of id, or external_id with source.
customer.idstring (uuid)- BIRP id of the record.
customer.sourcestring- External system of external_id, in lowercase.
customer.external_idstring- Identifier of the record in an external system. Requires source.
due_datestring | null- Due date, YYYY-MM-DD. Left out: issue date plus payment_terms_days, when given.
issue_datestring- Document date the VAT is computed for, YYYY-MM-DD. Left out: the company today. Issuing sets the issue date again (the issue_date sent then, or the company today) and recomputes the VAT for it.
supply_datestring | null- Date of supply, YYYY-MM-DD.
payment_terms_daysnumber | nullvat_exemption_textstring | null- Legal mention printed with the exemption.
vat_exemption_reasonstring | null- Why VAT is zero, for the whole invoice. A zero-rate code with a right to deduct (export, intra-community, reverse charge) needs the matching reason; otherwise the line answers tax_code_mismatch.One of
intra_community,export,reverse_charge,small_business,other
curl -X PATCH "https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061" \
-H "Authorization: Bearer $BIRP_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"notes":"Thank you for your order","payment_terms_days":15}'const response = await fetch("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"notes": "Thank you for your order",
"payment_terms_days": 15
}),
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
"Idempotency-Key: " . bin2hex(random_bytes(16)),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"notes": "Thank you for your order",
"payment_terms_days": 15
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import uuid
import requests
response = requests.request(
"PATCH",
"https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061",
json={
"notes": "Thank you for your order",
"payment_terms_days": 15
},
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"amount_due": "126.80",
"amount_paid": "0.00",
"buyer": {
"address": "12 rue des Exemples",
"city": "Paris",
"country": "France",
"name": "Epicerie Exemple SARL",
"postal_code": "00000",
"registration_number": "EXAMPLE-0002",
"vat_number": "EXAMPLE-VAT-0002"
},
"created_at": "2026-09-28T09:12:40.000Z",
"currency": "EUR",
"customer_id": "00000000-0000-4000-8000-000000000031",
"due_at": null,
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000061",
"issued_at": "2026-09-28T00:00:00.000Z",
"legal_footer": null,
"lines": [
{
"description": "White bread 500 g",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000071",
"line_total": "64.00",
"lot_number": null,
"position": 0,
"product_id": "00000000-0000-4000-8000-000000000012",
"product_kind": "finished_product",
"quantity": "20.0000",
"unit": "pcs",
"unit_price": "3.2000",
"vat_amount": "12.80",
"vat_rate": "20.00"
},
{
"description": "Wheat flour 25 kg",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000072",
"line_total": "50.00",
"lot_number": null,
"position": 1,
"product_id": "00000000-0000-4000-8000-000000000011",
"product_kind": "goods",
"quantity": "4.0000",
"unit": "kg",
"unit_price": "12.5000",
"vat_amount": "0.00",
"vat_rate": "0.00"
}
],
"notes": null,
"number": null,
"order_id": "00000000-0000-4000-8000-000000000051",
"paid_at": null,
"payment": {
"bank_account": "EXAMPLE-IBAN-0001",
"method": "bank_transfer",
"reference": null,
"terms_days": 30
},
"payment_status": "unpaid",
"related_invoice_id": null,
"seller": {
"address": "Str. Exemplului 4",
"city": "Chisinau",
"country": "Moldova",
"name": "Brutaria Exemplu SRL",
"postal_code": "MD-0000",
"registration_number": "EXAMPLE-0001",
"vat_number": "EXAMPLE-VAT-0001"
},
"status": "draft",
"subtotal": "114.00",
"supplied_at": "2026-09-28T00:00:00.000Z",
"total": "126.80",
"total_discount": "0.00",
"total_vat": "12.80",
"type": "invoice",
"updated_at": "2026-09-28T14:05:12.417Z",
"vat_breakdown": [
{
"tax_code": "ZERO",
"taxable_amount": "50.00",
"vat_amount": "0.00",
"vat_rate": "0.00"
},
{
"tax_code": "STANDARD",
"taxable_amount": "64.00",
"vat_amount": "12.80",
"vat_rate": "20.00"
}
],
"vat_exemption_reason": null,
"vat_exemption_text": null
}
}Errors particular to this operation:
404
not_found409
invoice_issued422
company_profile_incomplete422
no_rule_for_date422
reference_not_found422
tax_code_mismatch422
tax_rules_unavailable422
validation_failed
Issue a draft invoice
Issues a draft invoice: it gets its number, its issue date, and its VAT for that date.
Scope:
invoices:write.Idempotency:
Idempotency-Keyrequired. See Idempotency.
Without issue_date, the current day of the company applies.
/v1/invoices/{id}/issueParameters
Idempotency-Keyrequiredstring, in header- Unique value for this request (for example a UUID), 1 to 128 printable ASCII characters. A retry with the same key and the same request gets the stored response for 24 hours, with Idempotency-Replayed: true; the same key with a different request answers 422 idempotency_key_reused. Required on POST, optional on PUT, PATCH and DELETE.Example
00000000-0000-4000-8000-0000000000a1 idrequiredstring (uuid), in path- Invoice identifier.Example
00000000-0000-4000-8000-000000000061
Request body
application/json
issue_datestring- Issue date, YYYY-MM-DD. The VAT is recomputed for it.
curl -X POST "https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/issue" \
-H "Authorization: Bearer $BIRP_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"issue_date":"2026-09-28"}'const response = await fetch("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/issue", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"issue_date": "2026-09-28"
}),
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/issue");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
"Idempotency-Key: " . bin2hex(random_bytes(16)),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"issue_date": "2026-09-28"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import uuid
import requests
response = requests.request(
"POST",
"https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/issue",
json={
"issue_date": "2026-09-28"
},
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"amount_due": "126.80",
"amount_paid": "0.00",
"buyer": {
"address": "12 rue des Exemples",
"city": "Paris",
"country": "France",
"name": "Epicerie Exemple SARL",
"postal_code": "00000",
"registration_number": "EXAMPLE-0002",
"vat_number": "EXAMPLE-VAT-0002"
},
"created_at": "2026-09-28T09:12:40.000Z",
"currency": "EUR",
"customer_id": "00000000-0000-4000-8000-000000000031",
"due_at": "2026-10-28T00:00:00.000Z",
"external_ids": [],
"id": "00000000-0000-4000-8000-000000000061",
"issued_at": "2026-09-28T00:00:00.000Z",
"legal_footer": null,
"lines": [
{
"description": "White bread 500 g",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000071",
"line_total": "64.00",
"lot_number": null,
"position": 0,
"product_id": "00000000-0000-4000-8000-000000000012",
"product_kind": "finished_product",
"quantity": "20.0000",
"unit": "pcs",
"unit_price": "3.2000",
"vat_amount": "12.80",
"vat_rate": "20.00"
},
{
"description": "Wheat flour 25 kg",
"details": null,
"discount": "0.00",
"id": "00000000-0000-4000-8000-000000000072",
"line_total": "50.00",
"lot_number": null,
"position": 1,
"product_id": "00000000-0000-4000-8000-000000000011",
"product_kind": "goods",
"quantity": "4.0000",
"unit": "kg",
"unit_price": "12.5000",
"vat_amount": "0.00",
"vat_rate": "0.00"
}
],
"notes": null,
"number": "EXAMPLE-INV-0098",
"order_id": "00000000-0000-4000-8000-000000000051",
"paid_at": null,
"payment": {
"bank_account": "EXAMPLE-IBAN-0001",
"method": "bank_transfer",
"reference": null,
"terms_days": 30
},
"payment_status": "unpaid",
"related_invoice_id": null,
"seller": {
"address": "Str. Exemplului 4",
"city": "Chisinau",
"country": "Moldova",
"name": "Brutaria Exemplu SRL",
"postal_code": "MD-0000",
"registration_number": "EXAMPLE-0001",
"vat_number": "EXAMPLE-VAT-0001"
},
"status": "issued",
"subtotal": "114.00",
"supplied_at": "2026-09-28T00:00:00.000Z",
"total": "126.80",
"total_discount": "0.00",
"total_vat": "12.80",
"type": "invoice",
"updated_at": "2026-09-28T14:05:12.417Z",
"vat_breakdown": [
{
"tax_code": "ZERO",
"taxable_amount": "50.00",
"vat_amount": "0.00",
"vat_rate": "0.00"
},
{
"tax_code": "STANDARD",
"taxable_amount": "64.00",
"vat_amount": "12.80",
"vat_rate": "20.00"
}
],
"vat_exemption_reason": null,
"vat_exemption_text": null
}
}Errors particular to this operation:
404
not_found409
invoice_issued409
numbering_conflict422
company_profile_incomplete422
no_rule_for_date422
tax_code_mismatch422
tax_rules_unavailable422
validation_failed
Record a payment
Records a payment on an issued invoice.
Scope:
invoices:write.Idempotency:
Idempotency-Keyrequired. See Idempotency.
The invoice then shows its new payment_status, amount_paid and amount_due.
/v1/invoices/{id}/paymentsParameters
Idempotency-Keyrequiredstring, in header- Unique value for this request (for example a UUID), 1 to 128 printable ASCII characters. A retry with the same key and the same request gets the stored response for 24 hours, with Idempotency-Replayed: true; the same key with a different request answers 422 idempotency_key_reused. Required on POST, optional on PUT, PATCH and DELETE.Example
00000000-0000-4000-8000-0000000000a1 idrequiredstring (uuid), in path- Invoice identifier.Example
00000000-0000-4000-8000-000000000061
Request body
application/json
notesstring | nullamountrequiredstring- Decimal string, at most two decimals, above zero.
methodrequiredstring- One of
bank_transfer,cash,card,cheque,direct_debit,compensation,other paid_onrequiredstring- Date the payment was received, YYYY-MM-DD.
referencestring | null- Reference of the payment in the paying system (card transaction, bank reference).
curl -X POST "https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/payments" \
-H "Authorization: Bearer $BIRP_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"amount":"64.50","method":"card","paid_on":"2026-10-07","reference":"EXAMPLE-PAY-0042"}'const response = await fetch("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/payments", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BIRP_API_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"amount": "64.50",
"method": "card",
"paid_on": "2026-10-07",
"reference": "EXAMPLE-PAY-0042"
}),
});
if (!response.ok) throw new Error(`BIRP API error ${response.status}`);
const result = await response.json();<?php
$ch = curl_init("https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/payments");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BIRP_API_KEY"),
"Idempotency-Key: " . bin2hex(random_bytes(16)),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"amount": "64.50",
"method": "card",
"paid_on": "2026-10-07",
"reference": "EXAMPLE-PAY-0042"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);import os
import uuid
import requests
response = requests.request(
"POST",
"https://api.birp.io/v1/invoices/00000000-0000-4000-8000-000000000061/payments",
json={
"amount": "64.50",
"method": "card",
"paid_on": "2026-10-07",
"reference": "EXAMPLE-PAY-0042"
},
headers={
"Authorization": f"Bearer {os.environ['BIRP_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
timeout=10,
)
response.raise_for_status()
result = response.json(){
"data": {
"amount": "64.50",
"created_at": "2026-10-07T10:02:11.000Z",
"currency": "EUR",
"id": "d4e5f6a7-0000-4000-8000-0000000000dd",
"invoice_id": "00000000-0000-4000-8000-000000000061",
"method": "card",
"paid_on": "2026-10-07",
"reference": "EXAMPLE-PAY-0042",
"status": "confirmed"
}
}Errors particular to this operation:
404
not_found409
invoice_not_issued422
validation_failed
Related
- invoices
- me-and-tax-codes
- formats