3 API3.5
Cancel before submission
Stop an invoice before it is submitted.
- In the sandbox
In plain words
This call stops an invoice that has not yet reached the route; after that, the correction is a credit note.
POST /invoices/{id}/cancel stops an invoice that the route does not have yet. It works while the invoice is received, validated or queued and no send is under way. After that, the cancellation is a business document: issue a credit note.
The call needs a key with the submit scope and an Idempotency-Key (8 to 100 characters). It takes no body.
Cancelled in time
The invoice goes to cancelled, and its queued job is dropped.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices/inv_ae4d9834bf251353532fe5ee/cancel" \
-H "Authorization: Bearer <your-api-key>" \
-H "Idempotency-Key: cancel-2026-0001"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/inv_ae4d9834bf251353532fe5ee/cancel"))
.header("Authorization", "Bearer <your-api-key>")
.header("Idempotency-Key", "cancel-2026-0001")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/inv_ae4d9834bf251353532fe5ee/cancel', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Idempotency-Key': 'cancel-2026-0001',
},
});
console.log(response.status);
console.log(await response.text());{
"invoice_ref": "FRESH-mux3dlqm-0",
"environment": "sandbox",
"document_sha256": "b341c81da6fe297787829a8c26fd4b25106b5b34e67482d38c1039651bbfed65",
"route": "DE-XRECHNUNG",
"updated_at": "2026-10-06T19:49:10.992Z",
"client": "acme-srl",
"created_at": "2026-10-06T19:49:10.816Z",
"id": "inv_ae4d9834bf251353532fe5ee",
"state": "cancelled",
"invoice_number": "FRESH-mux3dlqm-0"
}Too late
Once the route has the invoice, or a send is under way, the answer is 409.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices/inv_936a93e38de84e7b0a1d7681/cancel" \
-H "Authorization: Bearer <your-api-key>" \
-H "Idempotency-Key: cancel-2026-0002"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/inv_936a93e38de84e7b0a1d7681/cancel"))
.header("Authorization", "Bearer <your-api-key>")
.header("Idempotency-Key", "cancel-2026-0002")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/inv_936a93e38de84e7b0a1d7681/cancel', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Idempotency-Key': 'cancel-2026-0002',
},
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/already-submitted",
"title": "Already submitted to the route; issue a credit note instead",
"status": 409
}Answers
| Status | Meaning |
|---|---|
200 | Cancelled. The body is the invoice. |
400 | The Idempotency-Key is missing or not 8 to 100 characters. |
401 | No key, or an unknown key. |
403 | The key lacks the submit scope. |
404 | No such invoice for this client. |
409 | Already submitted (already-submitted), or a send is under way (send-in-progress). Issue a credit note, or wait for the result. A dead_letter invoice answers dead-letter to a client's key: we decide on those. |
429 | Too many requests for the key. Wait for Retry-After seconds. |
A cancel of an invoice that is already cancelled answers 200 with it again, so a retry after a lost answer is safe. A queued invoice is picked up within seconds, so the window to cancel is short. If a send was tried and its answer was lost, the invoice reads submitting and a cancel answers send-in-progress, because the route may hold it.