Transmitting an E-Invoice
Check the recipient, deliver a signed invoice through NRS or by email, retry safely, and confirm delivery.
Signing makes an invoice valid. Transmitting is what delivers it, and it is a separate, explicit call, so a signed invoice sits with you until you make it.
This guide picks up where Issuing an E-Invoice leaves off, with a signed invoice and its IRN.
Checking the recipient
An invoice can only go through NRS to a recipient whose TIN is connected to it. Before you transmit, make a request to the recipient lookup endpoint with the IRN. It reads the recipient's TIN from the invoice and asks NRS about it:
curl --request GET \
--url https://spend-api.tryduplo.com/api/v1/e-invoicing/invoices/DUP00000001-2A3A045D-20240123/recipient-lookup \
--header 'Authorization: Bearer <your-api-key>'On a successful request, you should receive a response similar to the one below:
{
"statusCode": 200,
"timestamp": "2024-01-23T10:12:09.640Z",
"path": "/api/v1/e-invoicing/invoices/DUP00000001-2A3A045D-20240123/recipient-lookup",
"message": "Recipient is connected to NRS",
"data": {
"invoiceId": "9c1f3b2a-77e4-4c1d-9b6a-2f5d8e0a4c73",
"tin": "87654321-0001",
"receiverConnected": true,
"hasWebhookSetup": false,
"lookupCompleted": true
}
}receiverConnected tells you whether you can transmit through NRS at all. hasWebhookSetup tells you whether NRS will notify the recipient when the invoice arrives, or whether they will only see it the next time they look.
If NRS is slow or unavailable, the lookup does not fail. It returns receiverConnected: false with lookupCompleted: false and the message Could not verify NRS connection for the recipient; recommend emailing a copy, so read lookupCompleted: false as "unknown" rather than "not connected". If the recipient has no TIN on file, the call returns 400 instead.
The lookup endpoint answers the same question by asking NRS about the IRN directly, and returns receiverConnected and hasWebhookSetup too, but without that fallback. Neither call changes the invoice, and both are free.
If the recipient is not connected, transmit with firsTransmit: false and an email address instead, as the next section shows.
Sending the invoice
Make a request to the Transmit an invoice endpoint with the same IRN once the invoice is signed:
curl --request POST \
--url https://spend-api.tryduplo.com/api/v1/e-invoicing/invoices/DUP00000001-2A3A045D-20240123/transmit \
--header 'Authorization: Bearer <your-api-key>' \
--header 'Content-Type: application/json' \
--data '{ "firsTransmit": true }'On a successful request, you should receive a response similar to the one below:
{
"statusCode": 200,
"timestamp": "2024-01-23T10:41:02.317Z",
"path": "/api/v1/e-invoicing/invoices/DUP00000001-2A3A045D-20240123/transmit",
"message": "Invoice transmitted",
"data": {
"invoiceId": "9c1f3b2a-77e4-4c1d-9b6a-2f5d8e0a4c73",
"transmissionStatus": "transmitted",
"emailedTo": []
}
}firsTransmit defaults to true, which delivers through NRS to a recipient that is connected to it. If your recipient is not on NRS, set firsTransmit to false and pass at least one address in emails to send an email copy instead. Leaving firsTransmit on and supplying emails does both.
Checking the recipient tells you which applies before you call.
After a successful transmit, transmissionStatus moves from not_sent to transmitted and status becomes sent. Both are safe to re-enter, so resending does not break the invoice.
If the recipient's TIN is not connected to NRS, the call still returns 200, but with the message Recipient not on NRS network and transmissionStatus left at not_sent. Try again later, or send an email copy instead.
Retrying a transmit
A transmit through NRS accepts an optional x-idempotency-key header, in the same format as on submit and sign: 8 to 128 characters of letters, digits, ., _, :, or -. Repeating the call with the same key replays the first call's outcome instead of transmitting to NRS again.
The key covers only the NRS delivery. Email copies are sent before it is checked, so a retry that includes emails sends the copy again.
How to react to a failed transmit depends on what comes back:
| Response | What it means | What to do |
|---|---|---|
502 with NRS transmission outcome is unknown; reconciliation is required | The call to NRS timed out or got an ambiguous answer, so the invoice may or may not have arrived | Do not transmit again, with the same key or a new one. Duplo confirms the outcome with NRS in the background and moves transmissionStatus to transmitted once NRS confirms it. Read the invoice back to check |
4xx carrying NRS's rejection reason | NRS definitively refused the invoice, and transmissionStatus becomes rejected | Correct the cause, then retry with a new key |
409 Invoice transmission is already in progress | Another transmit for this invoice is still running | Wait, then read the invoice back |
409 The previous NRS transmission outcome is unknown and requires reconciliation | An earlier attempt returned the 502 above and is still unresolved | Wait for reconciliation rather than retrying |
409 This idempotency key belongs to a failed transmission | The key was used on an attempt that NRS rejected | Correct the cause, then retry with a new key |
409 Transmission idempotency key was already used for a different request | The key was already used for a different invoice or request | Use a key unique to this invoice |
As with submit and sign, deriving the key from your own invoice identifier is what makes a retry after a timeout safe.
Confirming delivery
A transmissionStatus of transmitted means NRS accepted the transmit call, not that the recipient has the invoice. To find out whether it arrived, make a request to the confirm endpoint with the IRN. It asks NRS directly for what it holds on the invoice:
curl --request GET \
--url https://spend-api.tryduplo.com/api/v1/e-invoicing/invoices/DUP00000001-2A3A045D-20240123/confirm \
--header 'Authorization: Bearer <your-api-key>'On a successful request, you should receive a response similar to the one below:
{
"statusCode": 200,
"timestamp": "2024-01-23T10:20:31.775Z",
"path": "/api/v1/e-invoicing/invoices/DUP00000001-2A3A045D-20240123/confirm",
"message": "Invoice confirmed with NRS",
"data": {
"reference": "DUP00000001-2A3A045D-20240123",
"issueDate": "2024-01-23",
"dueDate": null,
"syncDate": "2024-01-23",
"paymentStatus": "PENDING",
"entryStatus": "NEW_ENTRY",
"transmitted": true,
"delivered": true
}
}delivered: true means the invoice reached the recipient. A transmitted: true with delivered: false puts the problem on the recipient's side of NRS, not yours. The other fields are NRS's own record of the invoice, in its own upper-case vocabulary, and Checking state at NRS explains them.
The call goes to NRS live, so it is slower than reading the invoice from Duplo. Make it for an invoice you have a delivery question about, not in a loop over every invoice you send.
How is this guide?
Last updated on