Integrate in Pass-Through Mode

Validate, bill and sign synchronously, then look up and transmit the signed IRN.

Pass-through mode is for integrations that keep their own durable invoice record and send the NRS wire document through Duplo. Validation and transmission are unbilled. The exact signing route is billable.

Request contract

Every request uses your approved hostname and three customer-controlled headers: x-api-key, the API key from Duplo Dashboard; x-sub-business-id, the gatewaySubBusinessId of the represented business; and content-type: application/json. A sign attempt also carries x-idempotency-key, x-attempt-number, and x-request-id. Each example below shows the full header set for its operation.

x-attempt-number must be a positive integer and defaults to 1 when omitted. Keep both the attempt number and idempotency key unchanged for network retries of the same logical attempt. Only after an outcome is conclusively failed or reversed—and a new attempt is authorized—increment the attempt number and create a new stable idempotency key. Never increment or retry an unconfirmed outcome.

An optional x-invoice-reference must exactly equal the body irn. Send only the documented Gateway headers; state, mode, payer wallet, and fee are server-controlled.

Processing flow

  1. Validate

    Gateway binds the child and relays the document to NRS without charging.

  2. Debit

    On sign, Duplo resolves the current fee and confirms the payer transfer before NRS.

  3. Sign

    Gateway calls NRS and accepts only the documented sign-success contract.

  4. Transmit

    Use the same child and signed IRN for unbilled lookup and delivery.

1. Validate the document

Build the Pass-through NRS document, then call:

curl --request POST \
  --url https://acme.invoice.tryduplo.com/api/v1/invoice/validate \
  --header 'content-type: application/json' \
  --header 'x-api-key: pk_test_replace_with_your_key' \
  --header 'x-sub-business-id: 44444444-4444-4444-8444-444444444444' \
  --data @invoice.json

Expected NRS success:

Validation success
{
  "code": 200,
  "data": {
    "ok": true
  }
}

Before forwarding, the Gateway requires the document's business_id and normalized accounting_supplier_party.tin to match the authorized represented business. Validation creates no signing charge and no Stored invoice row.

2. Sign the same document

Do not mutate a validated invoice before signing. Reuse its exact IRN and document bytes where practical.

curl --request POST \
  --url https://acme.invoice.tryduplo.com/api/v1/invoice/sign \
  --header 'content-type: application/json' \
  --header 'x-api-key: pk_test_replace_with_your_key' \
  --header 'x-sub-business-id: 44444444-4444-4444-8444-444444444444' \
  --header 'x-idempotency-key: sign-INV000001-2A3A045D-20260818-1' \
  --header 'x-attempt-number: 1' \
  --header 'x-request-id: req-018f0f56-f5f5-7c98-a21a-4a03c11a85b1' \
  --data @invoice.json

The Gateway performs these checks in order:

  1. Authorize the API key against the approved host and represented business.
  2. Verify the body IRN, NRS business ID, and supplier TIN.
  3. Resolve and debit the current-state signing fee from the business you manage in Duplo Dashboard.
  4. Persist recovery context before contacting NRS.
  5. Call NRS, classify the outcome, and return the applicable response.

An exact success has an HTTP 2xx status and this NRS body contract:

Sign success contract
{
  "code": 201,
  "data": {
    "ok": true
  }
}

NRS may add response fields under data. Treat the returned document as sensitive, store it durably, and do not log full invoice contents in general application logs.

Pass-through does not store the invoice

A successful Pass-through request creates billing and audit state but no customer-visible invoice row in Duplo Dashboard. Your system must keep the original request, NRS response, IRN, represented-business mapping, idempotency key, and request trace.

3. Check receiver availability

After exact sign success, the Gateway normally binds that IRN to the host, state, and represented business. This post-sign delivery binding is best-effort: if it is temporarily unavailable, sign can still succeed while later lookup or transmit returns 503. Preserve the successful sign response and contact support instead of signing again. Use the same child:

curl \
  --url https://acme.invoice.tryduplo.com/api/v1/invoice/transmit/lookup/INV000001-2A3A045D-20260818 \
  --header 'x-api-key: pk_test_replace_with_your_key' \
  --header 'x-sub-business-id: 44444444-4444-4444-8444-444444444444'

A common NRS response reports connection state for the invoice parties:

Party availability response
{
  "code": 200,
  "data": {
    "accounting_supplier_party": { "up": true },
    "accounting_customer_party": { "up": true },
    "bill_party": { "up": true },
    "ship_party": { "up": true }
  }
}

NRS owns this response schema and may evolve it. Preserve the original response and use the current NRS reference when interpreting party availability.

4. Transmit the signed IRN

curl --request POST \
  --url https://acme.invoice.tryduplo.com/api/v1/invoice/transmit/INV000001-2A3A045D-20260818 \
  --header 'content-type: application/json' \
  --header 'x-api-key: pk_test_replace_with_your_key' \
  --header 'x-sub-business-id: 44444444-4444-4444-8444-444444444444' \
  --data '{}'

Expected NRS success:

Transmit success
{
  "code": 200,
  "data": {
    "ok": true
  }
}

NRS can return code: 201 for this operation; success requires data.ok: true. Lookup and transmission are unbilled. A child/IRN mismatch or missing signed-IRN binding returns 403 before NRS.

Safe retry behavior

SituationWhat to do
Validation failed with a definite 4xxCorrect the document; validation was not billed
Sign was rejected definitivelyKeep the trace; Duplo starts the safe fee reversal
Sign returned an unconfirmed 502Do not sign again; retain traceId, check the IRN, and contact Duplo support
Your client lost a successful sign responseQuery the signed IRN first; replay with the same attempt identity is blocked with 409
Lookup/transmit returned 503 after sign successPreserve the sign response and contact support; do not re-sign to recreate delivery state

Read Billing and safe retries before implementing automatic retries.

How is this guide?

Last updated on

On this page