Campos:currency y version son opcionales y toman EUR y 3.2.1. En cada línea, tipoImpuesto, claveRegimen, calificacion, causaExencion y recargoEquivalenciaRate son opcionales.
La cabecera Location apunta a /api/v1/registros/{id}. aeat es null hasta que haya un envío.
La misma llamada, en tu lenguaje
Emitir una factura no es más que una petición HTTP con JSON. Estos tres ejemplos hacen exactamente lo mismo que el cURL de arriba: leen la API key de una variable de entorno y mandan una Idempotency-Key nueva en cada intento, sin escribir nunca la clave secreta dentro del código.
Python · requests
import os
import uuid
import requests
url = "https://api.datapilotax.es/api/v1/facturae/json"
api_key = os.environ["DATAPILOTAX_API_KEY"]
invoice = {
"series": "F2026",
"number": "0001",
"issueDate": "2026-09-05",
"issuer": {
"taxIdNumber": "B12345674",
"legalName": "INTEGRADOR SL",
"address": {
"address": "Calle Mayor 1",
"postCode": "28001",
"town": "Madrid",
"province": "Madrid"
}
},
"receiver": {
"taxIdNumber": "A58818501",
"legalName": "CLIENTE DE PRUEBA SL",
"address": {
"address": "Gran Via 2",
"postCode": "28013",
"town": "Madrid",
"province": "Madrid"
}
},
"lines": [
{
"description": "Servicios de desarrollo de software",
"quantity": 1.00,
"unitPriceWithoutTax": 100.00,
"totalAmountWithoutTax": 100.00,
"taxRate": 21.00
}
],
"totals": {
"totalGrossAmount": 100.00,
"totalTaxAmount": 21.00,
"totalPayableAmount": 121.00
}
}
response = requests.post(
url,
headers={
"X-API-Key": api_key,
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4())
},
json=invoice
)
if response.status_code == 201:
receipt = response.json()
print("Factura emitida:", receipt["id"])
print("Huella:", receipt["huella"])
print("Estado:", receipt["status"])
else:
raise Exception(f"Error {response.status_code}: {response.text}")Node.js · fetch nativo (Node 18+)
const url = 'https://api.datapilotax.es/api/v1/facturae/json';
const apiKey = process.env.DATAPILOTAX_API_KEY;
const invoice = {
series: 'F2026',
number: '0001',
issueDate: '2026-09-05',
issuer: {
taxIdNumber: 'B12345674',
legalName: 'INTEGRADOR SL',
address: {
address: 'Calle Mayor 1',
postCode: '28001',
town: 'Madrid',
province: 'Madrid'
}
},
receiver: {
taxIdNumber: 'A58818501',
legalName: 'CLIENTE DE PRUEBA SL',
address: {
address: 'Gran Via 2',
postCode: '28013',
town: 'Madrid',
province: 'Madrid'
}
},
lines: [
{
description: 'Servicios de desarrollo de software',
quantity: 1.00,
unitPriceWithoutTax: 100.00,
totalAmountWithoutTax: 100.00,
taxRate: 21.00
}
],
totals: {
totalGrossAmount: 100.00,
totalTaxAmount: 21.00,
totalPayableAmount: 121.00
}
};
async function issueInvoice() {
const response = await fetch(url, {
method: 'POST',
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID()
},
body: JSON.stringify(invoice)
});
if (response.status === 201) {
const receipt = await response.json();
console.log('Factura emitida:', receipt.id);
console.log('Huella:', receipt.huella);
console.log('Estado:', receipt.status);
} else {
throw new Error(`Error ${response.status}: ${await response.text()}`);
}
}
issueInvoice();PHP · cURL
<?php
function uuidv4(): string
{
$data = random_bytes(16);
$data[6] = chr((ord($data[6]) & 0x0f) | 0x40);
$data[8] = chr((ord($data[8]) & 0x3f) | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
$url = 'https://api.datapilotax.es/api/v1/facturae/json';
$apiKey = getenv('DATAPILOTAX_API_KEY');
$invoice = [
'series' => 'F2026',
'number' => '0001',
'issueDate' => '2026-09-05',
'issuer' => [
'taxIdNumber' => 'B12345674',
'legalName' => 'INTEGRADOR SL',
'address' => [
'address' => 'Calle Mayor 1',
'postCode' => '28001',
'town' => 'Madrid',
'province' => 'Madrid'
]
],
'receiver' => [
'taxIdNumber' => 'A58818501',
'legalName' => 'CLIENTE DE PRUEBA SL',
'address' => [
'address' => 'Gran Via 2',
'postCode' => '28013',
'town' => 'Madrid',
'province' => 'Madrid'
]
],
'lines' => [
[
'description' => 'Servicios de desarrollo de software',
'quantity' => 1.00,
'unitPriceWithoutTax' => 100.00,
'totalAmountWithoutTax' => 100.00,
'taxRate' => 21.00
]
],
'totals' => [
'totalGrossAmount' => 100.00,
'totalTaxAmount' => 21.00,
'totalPayableAmount' => 121.00
]
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($invoice, JSON_UNESCAPED_UNICODE),
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $apiKey,
'Content-Type: application/json',
'Idempotency-Key: ' . uuidv4()
],
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => true
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 201) {
$receipt = json_decode($response, true);
echo "Factura emitida: {$receipt['id']}\n";
echo "Huella: {$receipt['huella']}\n";
echo "Estado: {$receipt['status']}\n";
} else {
throw new RuntimeException("Error {$status}: {$response}");
} No hace falta ninguna librería de TaxPilot: la API es HTTP y JSON, así que cualquier cliente que ya uses en tu lenguaje sirve.