Stored invoices

Create an Invoice Customer

STORED invoice flow: create or resolve the customer before submitting its customerId through POST /api/v1/invoice/sign. PASSTHROUGH does not require this step. Customer routes themselves are not restricted by invoice-handling mode. Create an invoice customer using your approved Gateway domain and x-api-key. Ownership, test/live state and the invoice module are derived by the service; do not supply business ownership fields. Customers are scoped to the parent business and state and may be reused across represented businesses and approved domains with the same parent/state. No x-sub-business-id is required. Duplicate email/TIN conflicts return 409 GW_CUSTOMER_ALREADY_EXISTS; use GET /customers?email=... to resolve an uncertain creation before retrying. New customer creation returns 409 GW_DOMAIN_DRAINING during a domain transition.

POST
/customers
x-api-key<token>

The API key generated for your business in Duplo Dashboard. The credential's ipWhitelisted setting is enforced end to end on the customer-facing custom-domain Gateway routes in this public contract. A trusted edge overwrites the configured client-IP header and Gateway carries that verified address over its authenticated internal hop; caller-supplied X-Forwarded-For values are never trusted. An empty IP allowlist permits any source. When an allowlist is configured, a missing, malformed, or nonmatching verified client address is rejected with HTTP 403.

In: header

Header Parameters

X-Request-ID?string

Optional caller correlation metadata. Gateway creates a new authoritative request ID, returns it in the response X-Request-ID header and Problem Details requestId, and propagates that generated value to its dependencies.

Match^[A-Za-z0-9][A-Za-z0-9._:-]*$
Length1 <= length <= 128

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

curl -X POST "https://example.com/customers" \  -H "X-Request-ID: erp-run-20260916-0042" \  -H "Content-Type: application/json" \  -d '{    "firstName": "string",    "lastName": "string",    "email": "user@example.com",    "phone": "string",    "country": "st",    "address": "string",    "postcode": "string"  }'
{
  "data": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "firstName": "string",
    "lastName": "string",
    "email": "user@example.com",
    "phone": "string",
    "tin": "string",
    "country": "st",
    "state": "string",
    "city": "string",
    "address": "string",
    "postcode": "string",
    "module": "invoice",
    "reference": "string",
    "modules": [
      "string"
    ],
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  },
  "statusCode": 0,
  "message": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}
{
  "type": "http://example.com",
  "title": "string",
  "status": 400,
  "detail": "string",
  "instance": "http://example.com",
  "code": "GW_REQUEST_INVALID_JSON",
  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",
  "timestamp": "2019-08-24T14:15:22Z",
  "action": {
    "code": "string",
    "description": "string",
    "documentation": "http://example.com"
  },
  "retry": {
    "strategy": "DO_NOT_RETRY",
    "sameIdempotencyKey": true,
    "afterSeconds": 0
  },
  "errors": [
    {
      "location": "header",
      "field": "string",
      "pointer": "string",
      "code": "REQUIRED",
      "detail": "string"
    }
  ],
  "operationId": "string",
  "message": "string",
  "statusCode": 0,
  "path": "string"
}

How is this guide?

Last updated on