{"auth":{"apikey":[{"key":"in","type":"string","value":"header"},{"key":"key","type":"string","value":"X-API-Key"},{"key":"value","type":"string","value":"{{apiKey}}"}],"type":"apikey"},"event":[{"listen":"prerequest","script":{"exec":["pm.variables.set('idempotencyKey', (crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(16).slice(2)}`));"],"type":"text/javascript"}}],"info":{"_postman_id":"trustbill-partner-v1-generated","description":"Public API for ERP integrators pushing invoices, managing customers, and receiving webhooks under a connected SME. Every mutation is Idempotency-Key protected; every list is cursor-paginated; every webhook is HMAC-signed and retried with backoff.\n\n**Generated from the OpenAPI spec** — regenerate on catalog change via `pnpm --filter @businex360/api build:partner-openapi`.","name":"TrustBill Partner API","schema":"https://schema.getpostman.com/json/collection/v2.1.0/collection.json"},"item":[{"item":[{"name":"RFC 8414 authorization-server metadata (deprecated — see /oauth/token for status)","request":{"auth":{"type":"noauth"},"description":"Discovery document for OAuth-aware SDK generators. OAuth is not enabled on the current prod environment — this metadata is served for completeness but any token request will 503. See `POST /v1/partner/oauth/token` for the current status.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[],"method":"GET","url":{"host":["{{baseUrl}}"],"path":[".well-known","oauth-authorization-server"],"raw":"{{baseUrl}}/.well-known/oauth-authorization-server"}}},{"name":"OAuth 2.0 client-credentials grant (deprecated — not enabled on this environment)","request":{"auth":{"type":"noauth"},"body":{"mode":"raw","options":{"raw":{"language":"json"}},"raw":"{}"},"description":"**Status (2026-10-31):** this endpoint returns `503 oauth_not_configured` on the current prod environment — the OAuth shim is not enabled. **Use the three-header auth (`X-API-Key` + `X-API-Secret` + `x-erp-partner-secret`) instead.** When OAuth is enabled on a future environment this endpoint will exchange your API-Key credentials for a 24h JWT bearer that encodes `(partnerId, consultancyTenantId, mode)`. The `bearerAuth` + `oauth2ClientCredentials` security schemes were stripped from the spec in the same release to prevent SDK generators from emitting unusable OAuth client code — until the shim is enabled, don't code against this flow. If you have a hard OAuth-only constraint, contact support.\n\n**Required fields:** `grant_type`, `client_id`, `client_secret`.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"Content-Type","value":"application/json"}],"method":"POST","url":{"host":["{{baseUrl}}"],"path":["v1","partner","oauth","token"],"raw":"{{baseUrl}}/v1/partner/oauth/token"}}}],"name":"auth"},{"item":[{"name":"Catalog version history (append-only)","request":{"description":"Returns changelog entries for the FTA field catalog, oldest first. Each entry describes added / removed / deprecated / renamed catalog keys and any doc-only corrections. Partners pin against `?since=<version>` to receive strictly-after entries; an unknown `since` returns the full history.\n\n**Tenant-neutral** — authenticates with API-Key + API-Secret only; no `x-erp-partner-secret` required.\n\n**Caching**: `Cache-Control: public, max-age=300`. The `X-Catalog-Version` response header lets SDKs invalidate their cache precisely on a catalog bump — key your cache off that header rather than the generated timestamp.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","catalog","changelog"],"query":[{"description":"Return entries strictly AFTER this catalog version. Omit to receive the full history. Unknown values fall through to the full history.","key":"since","value":""},{"description":"Reserved for a future per-locale translation layer. The payload is currently English-only; the parameter is validated for forward compatibility.","key":"locale","value":""}],"raw":"{{baseUrl}}/v1/partner/catalog/changelog"}}},{"name":"Catalog-version polling fallback for the webhook","request":{"description":"Returns the current `FIELD_SPEC_VERSION` + server timestamp. Partners who don't receive the `catalog.updated` webhook (behind a firewall, during an outage) can poll here cheaply.\n\n**Tenant-neutral** — authenticates with API-Key + API-Secret only; no `x-erp-partner-secret` required.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","catalog","version"],"raw":"{{baseUrl}}/v1/partner/catalog/version"}}},{"name":"List partner-reachable error codes","request":{"description":"Every `DomainError.code` a partner can receive on any endpoint, with HTTP status + title + user-facing detail + retriable flag + docUrl.\n\n**Tenant-neutral** — authenticates with API-Key + API-Secret only; no `x-erp-partner-secret` required.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","error-codes"],"query":[{"description":"Reserved for a future per-locale translation layer. The payload is currently English-only; the parameter is validated for forward compatibility.","key":"locale","value":""}],"raw":"{{baseUrl}}/v1/partner/error-codes"}}},{"name":"List the full FTA invoice field catalog","request":{"description":"Returns every FTA invoice field with class (M/CM/O), effective source for the active partner_kind, rules, example value, Partner-API addressability, and per-partner adapter binding. The authoritative read of the catalog partners build against.\n\n**Tenant-neutral** — authenticates with API-Key + API-Secret only; no `x-erp-partner-secret` required.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","field-schema"],"query":[{"description":"Partner ERP kind. Defaults to `custom` when absent. Determines `source.effective` on each row.","key":"partner","value":""},{"description":"Reserved for a future per-locale translation layer. The payload is currently English-only; the parameter is validated for forward compatibility.","key":"locale","value":""}],"raw":"{{baseUrl}}/v1/partner/field-schema"}}},{"name":"Fetch a single field entry by catalog key","request":{"description":"Deep-link lookup for one catalog field. The response body is the same `FieldSchemaRow` shape as the list endpoint, wrapped in a single-row envelope.\n\n**Tenant-neutral** — authenticates with API-Key + API-Secret only; no `x-erp-partner-secret` required.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","field-schema",":fieldKey"],"query":[{"key":"partner","value":""}],"raw":"{{baseUrl}}/v1/partner/field-schema/:fieldKey"}}},{"name":"List invoice status codes partners can see","request":{"description":"Dictionary of every `InvoiceStatus` value a partner can receive — pipeline states, terminal states, ingestion states, and webhook event names — with human labels + reachable `nextStates` hints.\n\n**Tenant-neutral** — authenticates with API-Key + API-Secret only; no `x-erp-partner-secret` required.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","status-codes"],"query":[{"description":"Reserved for a future per-locale translation layer. The payload is currently English-only; the parameter is validated for forward compatibility.","key":"locale","value":""}],"raw":"{{baseUrl}}/v1/partner/status-codes"}}}],"name":"catalog"},{"item":[{"name":"Upsert a customer under the connected SME","request":{"body":{"mode":"raw","options":{"raw":{"language":"json"}},"raw":"{}"},"description":"Idempotent on (tenant_id, externalRef). Requires Idempotency-Key.\n\n**Required fields:** `externalRef`, `name`.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"},{"key":"Idempotency-Key","value":"{{idempotencyKey}}"},{"key":"Content-Type","value":"application/json"}],"method":"POST","url":{"host":["{{baseUrl}}"],"path":["v1","partner","customers"],"raw":"{{baseUrl}}/v1/partner/customers"}}},{"name":"Read a customer by externalRef","request":{"description":"Body is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","customers",":externalRef"],"raw":"{{baseUrl}}/v1/partner/customers/:externalRef"}}}],"name":"customers"},{"item":[{"name":"List invoices you have submitted for the connected SME","request":{"description":"Body is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices"],"query":[{"key":"status","value":""},{"key":"from","value":""},{"key":"to","value":""},{"key":"number","value":""},{"key":"limit","value":""},{"key":"cursor","value":""}],"raw":"{{baseUrl}}/v1/partner/invoices"}}},{"name":"Submit one invoice and auto-queue it for FTA delivery","request":{"body":{"mode":"raw","options":{"raw":{"language":"json"}},"raw":"{\n  \"actualDeliveryDate\": \"2026-10-30\",\n  \"buyer\": {\n    \"address\": {\n      \"city\": \"Abu Dhabi\",\n      \"country\": \"AE\",\n      \"countrySubdivision\": \"Abu Dhabi\",\n      \"emirate\": \"Abu Dhabi\",\n      \"line1\": \"Al Reem Island, Marina Square\",\n      \"line2\": \"Tower B\",\n      \"postalCode\": \"00000\",\n      \"state\": \"AUH\"\n    },\n    \"authorityName\": \"FTA\",\n    \"country\": \"AE\",\n    \"electronicAddress\": \"ap@buyer.ae\",\n    \"electronicAddressSchemeId\": \"EM\",\n    \"email\": \"ap@buyer.ae\",\n    \"kind\": \"buyer\",\n    \"legalRegistrationType\": \"TL\",\n    \"name\": \"Buyer Company LLC\",\n    \"phone\": \"+971-2-7654321\",\n    \"tin\": \"100000160500003\",\n    \"tradeLicenseNumber\": \"DED-654321\",\n    \"tradingName\": \"Buyer Co\",\n    \"trn\": \"100000160500003\"\n  },\n  \"contractReference\": \"CTR-2026-0421\",\n  \"contractValue\": 500000,\n  \"creditNoteReasonCode\": \"01\",\n  \"currency\": \"AED\",\n  \"customsReferenceNumber\": \"CDN-2026-0001\",\n  \"deliveryAddressLine1\": \"Plot 12, Sheikh Zayed Road\",\n  \"deliveryAddressLine2\": \"Zone 3\",\n  \"deliveryAddressLine3\": \"Building 42\",\n  \"deliveryCity\": \"Dubai\",\n  \"deliveryCountryCode\": \"AE\",\n  \"deliveryCountrySubdivision\": \"Dubai\",\n  \"deliveryLocationIdentifier\": \"LOC-5500\",\n  \"deliveryLocationSchemeIdentifier\": \"0088\",\n  \"deliveryPartyName\": \"Al Noor Warehouse\",\n  \"deliveryPostalCode\": \"00000\",\n  \"deliveryStateCode\": \"DXB\",\n  \"docAllowancesAmount\": 50,\n  \"docAllowancesReason\": \"Volume discount\",\n  \"docAllowancesVatCategory\": \"S\",\n  \"docAllowancesVatRate\": 0.05,\n  \"docChargesAmount\": 25,\n  \"docChargesReason\": \"Freight surcharge\",\n  \"docChargesVatCategory\": \"S\",\n  \"docChargesVatRate\": 0.05,\n  \"documentType\": \"tax_invoice\",\n  \"dueDate\": \"2026-11-29\",\n  \"frequencyOfBilling\": \"monthly\",\n  \"incoterms\": \"DAP Dubai\",\n  \"invoiceNote\": \"Payment due within 30 days from issue date.\",\n  \"invoiceType\": \"sale\",\n  \"invoicingPeriodEndDate\": \"2026-10-31\",\n  \"invoicingPeriodStartDate\": \"2026-10-01\",\n  \"issueDate\": \"2026-10-29\",\n  \"lines\": [\n    {\n      \"allowanceAmount\": 10,\n      \"allowanceReason\": \"Loyalty rebate\",\n      \"attributeName\": \"Period\",\n      \"attributeValue\": \"October 2026\",\n      \"chargeAmount\": 5,\n      \"chargeReason\": \"Handling\",\n      \"countryOfOrigin\": \"AE\",\n      \"description\": \"Consulting services — October 2026\",\n      \"itemType\": \"services\",\n      \"name\": \"Consulting — Oct 2026\",\n      \"priceBaseQuantity\": 1,\n      \"priceDiscount\": 0,\n      \"quantity\": 10,\n      \"serviceAccountingCode\": \"998311\",\n      \"standardIdentifier\": \"SKU-CONS-OCT\",\n      \"taxCategory\": \"standard_5\",\n      \"unitOfMeasureCode\": \"HUR\",\n      \"unitPrice\": 500,\n      \"vatRate\": 0.05\n    }\n  ],\n  \"number\": \"INV-2026-0001\",\n  \"paymentAccountIdentifier\": \"AE070331234567890123456\",\n  \"paymentAccountName\": \"Al Noor Trading LLC\",\n  \"paymentAccountScheme\": \"IBAN\",\n  \"paymentMeansCode\": \"30\",\n  \"paymentServiceProviderIdentifier\": \"EBILAEAD\",\n  \"precedingInvoiceIssueDate\": \"2025-10-01\",\n  \"precedingInvoiceNumber\": \"INV-2025-999\",\n  \"precedingInvoiceReference\": \"INV-2025-999\",\n  \"principleId\": \"principal-ref-01\",\n  \"projectReference\": \"PRJ-2026-99\",\n  \"purchaseOrderReference\": \"PO-2026-5500\",\n  \"receivingAdviceReference\": \"RAD-2026-0100\",\n  \"salesOrderReference\": \"SO-2026-5500\",\n  \"seller\": {\n    \"address\": {\n      \"city\": \"Dubai\",\n      \"country\": \"AE\",\n      \"countrySubdivision\": \"Dubai\",\n      \"emirate\": \"Dubai\",\n      \"line1\": \"Office 2201, Boulevard Plaza Tower 1\",\n      \"line2\": \"Sheikh Mohammed Bin Rashid Boulevard\",\n      \"postalCode\": \"00000\",\n      \"state\": \"DXB\"\n    },\n    \"authorityName\": \"FTA\",\n    \"country\": \"AE\",\n    \"electronicAddress\": \"ops@alnoor.ae\",\n    \"electronicAddressSchemeId\": \"EM\",\n    \"email\": \"ops@alnoor.ae\",\n    \"kind\": \"seller\",\n    \"legalRegistrationType\": \"TL\",\n    \"name\": \"Al Noor Trading LLC\",\n    \"passportIssuingCountry\": \"AE\",\n    \"phone\": \"+971-4-1234567\",\n    \"tin\": \"100000000000003\",\n    \"tradeLicenseNumber\": \"DED-123456\",\n    \"tradingName\": \"Al Noor\",\n    \"trn\": \"100000000000003\"\n  },\n  \"tenderOrLotReference\": \"TND-2026-0005\",\n  \"transactionTypeCode\": \"0100000A\",\n  \"trn\": \"100000000000003\",\n  \"vatPointDate\": \"2026-10-29\"\n}"},"description":"Server-side POST → transform → validate → deliver runs automatically; you get status via webhook or by polling GET :id.\n\n**Response `status` (create-only vocabulary):**\n- `queued` — invoice entered the delivery pipeline.\n- `held` — pre-submit validation refused it. `heldReason` + `heldErrors[]` tell you which fields to fix. To retry: DELETE the held invoice and POST the corrected body.\n- `draft` — auto-submit crashed. Recover via `POST /v1/partner/invoices/{id}/retry`.\n\n**Reserved test TRNs (test / sandbox modes only):**\n- `seller.trn = \"100000000000000\"` → **always accepts** end-to-end. Skips validation + delivery + status-poll, lands the invoice at the TERMINAL success state `acknowledged` synchronously (visible under the SME's \"Approved\" tab, not \"Awaiting FTA\"), and fires the HMAC `invoice.status_changed` webhook within ~5s. Full audit trail (`submitted → delivered → acknowledged`) is emitted so your logs look identical to a real pipeline run. `POST /v1/partner/invoices/validate` honours the same short-circuit so a CI loop around this TRN won't flag errors the live POST will ignore.\n- `seller.trn = \"100000000000666\"` → **always rejects** with `403 test_trn_reject`. Use to exercise your rejection code path.\nLive mode ignores both — TRN cross-check applies as normal.\n\n**Test-mode (`erp_test_*` key) behaviour on a real seller TRN:** every row created via a test key is stamped `is_demo=true` and routed through the sandbox submission pool. Demo rows **cannot progress beyond `draft` on a real TRN** — the submit pipeline holds them with `heldReason=\"invoice_asp_not_ready\"` (even when the SME has Microvista fully linked), because test-mode is intentionally isolated from any live FTA registration. The two paths that let a test-mode invoice reach the terminal success state are (a) using the reserved success TRN above (fast-path to `acknowledged`), or (b) rotating the integration to a `erp_live_*` key once your account has been approved for live mode (full pipeline to `acknowledged` via real FTA ack). If you need the full queue → ack → webhook round-trip against your real TRN, request live-mode approval; `erp_test_*` keys are capped at the smoke-test fast-path by design.\n\n**Required fields:** `number`, `issueDate`, `buyer`, `seller`, `lines`, `trn`.\n\nBody is a catalog-complete example — every addressable field is populated so you can edit down to what your invoice actually carries. Call `POST /v1/partner/invoices/validate` to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"},{"key":"Idempotency-Key","value":"{{idempotencyKey}}"},{"key":"Content-Type","value":"application/json"}],"method":"POST","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices"],"raw":"{{baseUrl}}/v1/partner/invoices"}}},{"name":"Submit up to 100 invoices in one call","request":{"body":{"mode":"raw","options":{"raw":{"language":"json"}},"raw":"{\n  \"invoices\": [\n    {\n      \"actualDeliveryDate\": \"2026-10-30\",\n      \"buyer\": {\n        \"address\": {\n          \"city\": \"Abu Dhabi\",\n          \"country\": \"AE\",\n          \"countrySubdivision\": \"Abu Dhabi\",\n          \"emirate\": \"Abu Dhabi\",\n          \"line1\": \"Al Reem Island, Marina Square\",\n          \"line2\": \"Tower B\",\n          \"postalCode\": \"00000\",\n          \"state\": \"AUH\"\n        },\n        \"authorityName\": \"FTA\",\n        \"country\": \"AE\",\n        \"electronicAddress\": \"ap@buyer.ae\",\n        \"electronicAddressSchemeId\": \"EM\",\n        \"email\": \"ap@buyer.ae\",\n        \"kind\": \"buyer\",\n        \"legalRegistrationType\": \"TL\",\n        \"name\": \"Buyer Company LLC\",\n        \"phone\": \"+971-2-7654321\",\n        \"tin\": \"100000160500003\",\n        \"tradeLicenseNumber\": \"DED-654321\",\n        \"tradingName\": \"Buyer Co\",\n        \"trn\": \"100000160500003\"\n      },\n      \"contractReference\": \"CTR-2026-0421\",\n      \"contractValue\": 500000,\n      \"creditNoteReasonCode\": \"01\",\n      \"currency\": \"AED\",\n      \"customsReferenceNumber\": \"CDN-2026-0001\",\n      \"deliveryAddressLine1\": \"Plot 12, Sheikh Zayed Road\",\n      \"deliveryAddressLine2\": \"Zone 3\",\n      \"deliveryAddressLine3\": \"Building 42\",\n      \"deliveryCity\": \"Dubai\",\n      \"deliveryCountryCode\": \"AE\",\n      \"deliveryCountrySubdivision\": \"Dubai\",\n      \"deliveryLocationIdentifier\": \"LOC-5500\",\n      \"deliveryLocationSchemeIdentifier\": \"0088\",\n      \"deliveryPartyName\": \"Al Noor Warehouse\",\n      \"deliveryPostalCode\": \"00000\",\n      \"deliveryStateCode\": \"DXB\",\n      \"docAllowancesAmount\": 50,\n      \"docAllowancesReason\": \"Volume discount\",\n      \"docAllowancesVatCategory\": \"S\",\n      \"docAllowancesVatRate\": 0.05,\n      \"docChargesAmount\": 25,\n      \"docChargesReason\": \"Freight surcharge\",\n      \"docChargesVatCategory\": \"S\",\n      \"docChargesVatRate\": 0.05,\n      \"dueDate\": \"2026-11-29\",\n      \"externalRef\": \"acme-batch-item-1\",\n      \"frequencyOfBilling\": \"monthly\",\n      \"incoterms\": \"DAP Dubai\",\n      \"invoiceNote\": \"Payment due within 30 days from issue date.\",\n      \"invoiceType\": \"sale\",\n      \"invoicingPeriodEndDate\": \"2026-10-31\",\n      \"invoicingPeriodStartDate\": \"2026-10-01\",\n      \"issueDate\": \"2026-10-29\",\n      \"lines\": [\n        {\n          \"allowanceAmount\": 10,\n          \"allowanceReason\": \"Loyalty rebate\",\n          \"attributeName\": \"Period\",\n          \"attributeValue\": \"October 2026\",\n          \"chargeAmount\": 5,\n          \"chargeReason\": \"Handling\",\n          \"countryOfOrigin\": \"AE\",\n          \"description\": \"Consulting services — October 2026\",\n          \"itemType\": \"services\",\n          \"name\": \"Consulting — Oct 2026\",\n          \"priceBaseQuantity\": 1,\n          \"priceDiscount\": 0,\n          \"quantity\": 10,\n          \"serviceAccountingCode\": \"998311\",\n          \"standardIdentifier\": \"SKU-CONS-OCT\",\n          \"taxCategory\": \"standard_5\",\n          \"unitOfMeasureCode\": \"HUR\",\n          \"unitPrice\": 500,\n          \"vatRate\": 0.05\n        }\n      ],\n      \"number\": \"INV-2026-0001\",\n      \"paymentAccountIdentifier\": \"AE070331234567890123456\",\n      \"paymentAccountName\": \"Al Noor Trading LLC\",\n      \"paymentAccountScheme\": \"IBAN\",\n      \"paymentMeansCode\": \"30\",\n      \"paymentServiceProviderIdentifier\": \"EBILAEAD\",\n      \"precedingInvoiceIssueDate\": \"2025-10-01\",\n      \"precedingInvoiceNumber\": \"INV-2025-999\",\n      \"principleId\": \"principal-ref-01\",\n      \"projectReference\": \"PRJ-2026-99\",\n      \"purchaseOrderReference\": \"PO-2026-5500\",\n      \"receivingAdviceReference\": \"RAD-2026-0100\",\n      \"salesOrderReference\": \"SO-2026-5500\",\n      \"seller\": {\n        \"address\": {\n          \"city\": \"Dubai\",\n          \"country\": \"AE\",\n          \"countrySubdivision\": \"Dubai\",\n          \"emirate\": \"Dubai\",\n          \"line1\": \"Office 2201, Boulevard Plaza Tower 1\",\n          \"line2\": \"Sheikh Mohammed Bin Rashid Boulevard\",\n          \"postalCode\": \"00000\",\n          \"state\": \"DXB\"\n        },\n        \"authorityName\": \"FTA\",\n        \"country\": \"AE\",\n        \"electronicAddress\": \"ops@alnoor.ae\",\n        \"electronicAddressSchemeId\": \"EM\",\n        \"email\": \"ops@alnoor.ae\",\n        \"kind\": \"seller\",\n        \"legalRegistrationType\": \"TL\",\n        \"name\": \"Al Noor Trading LLC\",\n        \"passportIssuingCountry\": \"AE\",\n        \"phone\": \"+971-4-1234567\",\n        \"tin\": \"100000000000003\",\n        \"tradeLicenseNumber\": \"DED-123456\",\n        \"tradingName\": \"Al Noor\",\n        \"trn\": \"100000000000003\"\n      },\n      \"tenderOrLotReference\": \"TND-2026-0005\",\n      \"transactionTypeCode\": \"0100000A\",\n      \"trn\": \"100000000000003\",\n      \"vatPointDate\": \"2026-10-29\"\n    }\n  ]\n}"},"description":"Per-item idempotency keys are derived from the batch's Idempotency-Key as `${batchKey}:${index}`. To recover from a partial failure, RESEND THE ORIGINAL BODY (same items, same order, same batch key) — the API will replay each item's stored result deterministically. Do NOT retry a subset with a fresh index range: the derived per-item keys would collide with completed items and hash-mismatch to 409.\n\n**Required fields:** `invoices`.\n\nBody is a catalog-complete example — every addressable field is populated so you can edit down to what your invoice actually carries. Call `POST /v1/partner/invoices/validate` to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"},{"key":"Idempotency-Key","value":"{{idempotencyKey}}"},{"key":"Content-Type","value":"application/json"}],"method":"POST","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices","bulk"],"raw":"{{baseUrl}}/v1/partner/invoices/bulk"}}},{"name":"List Peppol invoices delivered to the connected SME","request":{"description":"Read-only view of the SME's Peppol inbox — same data that powers the SME's /sme/inbox portal page. Scoped to the SME behind the `x-erp-partner-secret` header. Partners mirror this list into their ERP's incoming-bills workspace.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices","received"],"query":[{"key":"limit","value":""},{"key":"offset","value":""}],"raw":"{{baseUrl}}/v1/partner/invoices/received"}}},{"name":"Fetch one received invoice + its full UBL / PINT-AE detail","request":{"description":"Body is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices","received",":id"],"raw":"{{baseUrl}}/v1/partner/invoices/received/:id"}}},{"name":"Fetch one invoice's current status","request":{"description":"Body is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices",":id"],"raw":"{{baseUrl}}/v1/partner/invoices/:id"}}},{"name":"Cancel a pre-delivery invoice","request":{"description":"Deletes draft / queued / blocked_no_credit / rejected. Post-delivery invoices must be reversed with a credit note.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"}],"method":"DELETE","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices",":id"],"raw":"{{baseUrl}}/v1/partner/invoices/:id"}}},{"name":"Retry a rejected or blocked-no-credit invoice","request":{"description":"Same rate-limit the SME UI uses (3/hour/invoice).\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"},{"key":"Idempotency-Key","value":"{{idempotencyKey}}"}],"method":"POST","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices",":id","retry"],"raw":"{{baseUrl}}/v1/partner/invoices/:id/retry"}}}],"name":"invoices"},{"item":[{"name":"Round-trip health check","request":{"description":"Confirms API key + secret work. Does NOT require x-erp-partner-secret.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","ping"],"raw":"{{baseUrl}}/v1/partner/ping"}}},{"name":"Introspect the API key (and optionally the connection)","request":{"description":"Returns which ERP partner + which mode (test/live) the current API credentials belong to. When the caller ALSO passes `x-erp-partner-secret`, the response adds a `sme` block with the resolved SME's TRN, name, and submission mode — call this with your connection secret attached to discover which TRN to send on `POST /v1/partner/invoices`. The header is optional; bare `whoami` returns the partner-level shape only.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","whoami"],"raw":"{{baseUrl}}/v1/partner/whoami"}}}],"name":"meta"},{"item":[{"name":"Dry-run an invoice body against the catalog","request":{"body":{"mode":"raw","options":{"raw":{"language":"json"}},"raw":"{\n  \"actualDeliveryDate\": \"2026-10-30\",\n  \"buyer\": {\n    \"address\": {\n      \"city\": \"Abu Dhabi\",\n      \"country\": \"AE\",\n      \"countrySubdivision\": \"Abu Dhabi\",\n      \"emirate\": \"Abu Dhabi\",\n      \"line1\": \"Al Reem Island, Marina Square\",\n      \"line2\": \"Tower B\",\n      \"postalCode\": \"00000\",\n      \"state\": \"AUH\"\n    },\n    \"authorityName\": \"FTA\",\n    \"country\": \"AE\",\n    \"electronicAddress\": \"ap@buyer.ae\",\n    \"electronicAddressSchemeId\": \"EM\",\n    \"email\": \"ap@buyer.ae\",\n    \"kind\": \"buyer\",\n    \"legalRegistrationType\": \"TL\",\n    \"name\": \"Buyer Company LLC\",\n    \"phone\": \"+971-2-7654321\",\n    \"tin\": \"100000160500003\",\n    \"tradeLicenseNumber\": \"DED-654321\",\n    \"tradingName\": \"Buyer Co\",\n    \"trn\": \"100000160500003\"\n  },\n  \"contractReference\": \"CTR-2026-0421\",\n  \"contractValue\": 500000,\n  \"creditNoteReasonCode\": \"01\",\n  \"currency\": \"AED\",\n  \"customsReferenceNumber\": \"CDN-2026-0001\",\n  \"deliveryAddressLine1\": \"Plot 12, Sheikh Zayed Road\",\n  \"deliveryAddressLine2\": \"Zone 3\",\n  \"deliveryAddressLine3\": \"Building 42\",\n  \"deliveryCity\": \"Dubai\",\n  \"deliveryCountryCode\": \"AE\",\n  \"deliveryCountrySubdivision\": \"Dubai\",\n  \"deliveryLocationIdentifier\": \"LOC-5500\",\n  \"deliveryLocationSchemeIdentifier\": \"0088\",\n  \"deliveryPartyName\": \"Al Noor Warehouse\",\n  \"deliveryPostalCode\": \"00000\",\n  \"deliveryStateCode\": \"DXB\",\n  \"docAllowancesAmount\": 50,\n  \"docAllowancesReason\": \"Volume discount\",\n  \"docAllowancesVatCategory\": \"S\",\n  \"docAllowancesVatRate\": 0.05,\n  \"docChargesAmount\": 25,\n  \"docChargesReason\": \"Freight surcharge\",\n  \"docChargesVatCategory\": \"S\",\n  \"docChargesVatRate\": 0.05,\n  \"documentType\": \"tax_invoice\",\n  \"dueDate\": \"2026-11-29\",\n  \"frequencyOfBilling\": \"monthly\",\n  \"incoterms\": \"DAP Dubai\",\n  \"invoiceNote\": \"Payment due within 30 days from issue date.\",\n  \"invoiceType\": \"sale\",\n  \"invoicingPeriodEndDate\": \"2026-10-31\",\n  \"invoicingPeriodStartDate\": \"2026-10-01\",\n  \"issueDate\": \"2026-10-29\",\n  \"lines\": [\n    {\n      \"allowanceAmount\": 10,\n      \"allowanceReason\": \"Loyalty rebate\",\n      \"attributeName\": \"Period\",\n      \"attributeValue\": \"October 2026\",\n      \"chargeAmount\": 5,\n      \"chargeReason\": \"Handling\",\n      \"countryOfOrigin\": \"AE\",\n      \"description\": \"Consulting services — October 2026\",\n      \"itemType\": \"services\",\n      \"name\": \"Consulting — Oct 2026\",\n      \"priceBaseQuantity\": 1,\n      \"priceDiscount\": 0,\n      \"quantity\": 10,\n      \"serviceAccountingCode\": \"998311\",\n      \"standardIdentifier\": \"SKU-CONS-OCT\",\n      \"taxCategory\": \"standard_5\",\n      \"unitOfMeasureCode\": \"HUR\",\n      \"unitPrice\": 500,\n      \"vatRate\": 0.05\n    }\n  ],\n  \"number\": \"INV-2026-0001\",\n  \"paymentAccountIdentifier\": \"AE070331234567890123456\",\n  \"paymentAccountName\": \"Al Noor Trading LLC\",\n  \"paymentAccountScheme\": \"IBAN\",\n  \"paymentMeansCode\": \"30\",\n  \"paymentServiceProviderIdentifier\": \"EBILAEAD\",\n  \"precedingInvoiceIssueDate\": \"2025-10-01\",\n  \"precedingInvoiceNumber\": \"INV-2025-999\",\n  \"precedingInvoiceReference\": \"INV-2025-999\",\n  \"principleId\": \"principal-ref-01\",\n  \"projectReference\": \"PRJ-2026-99\",\n  \"purchaseOrderReference\": \"PO-2026-5500\",\n  \"receivingAdviceReference\": \"RAD-2026-0100\",\n  \"salesOrderReference\": \"SO-2026-5500\",\n  \"seller\": {\n    \"address\": {\n      \"city\": \"Dubai\",\n      \"country\": \"AE\",\n      \"countrySubdivision\": \"Dubai\",\n      \"emirate\": \"Dubai\",\n      \"line1\": \"Office 2201, Boulevard Plaza Tower 1\",\n      \"line2\": \"Sheikh Mohammed Bin Rashid Boulevard\",\n      \"postalCode\": \"00000\",\n      \"state\": \"DXB\"\n    },\n    \"authorityName\": \"FTA\",\n    \"country\": \"AE\",\n    \"electronicAddress\": \"ops@alnoor.ae\",\n    \"electronicAddressSchemeId\": \"EM\",\n    \"email\": \"ops@alnoor.ae\",\n    \"kind\": \"seller\",\n    \"legalRegistrationType\": \"TL\",\n    \"name\": \"Al Noor Trading LLC\",\n    \"passportIssuingCountry\": \"AE\",\n    \"phone\": \"+971-4-1234567\",\n    \"tin\": \"100000000000003\",\n    \"tradeLicenseNumber\": \"DED-123456\",\n    \"tradingName\": \"Al Noor\",\n    \"trn\": \"100000000000003\"\n  },\n  \"tenderOrLotReference\": \"TND-2026-0005\",\n  \"transactionTypeCode\": \"0100000A\",\n  \"trn\": \"100000000000003\",\n  \"vatPointDate\": \"2026-10-29\"\n}"},"description":"Accepts the same body as `POST /v1/partner/invoices` and returns the pre-submit validator's verdict without writing anything. CI partners wire this to catch catalog-rule changes before shipping.\n\n**TRN cross-check (opt-in):** when you ALSO pass `x-erp-partner-secret`, validate runs the same TRN check that `POST /v1/partner/invoices` runs — the top-level `trn` must match the SME bound to your connection secret. Without the header, validate is a pure body check so stateless CI integrators (no connected SME) can still exercise fixtures. Returning `ok: true` with the connection secret attached means `POST /v1/partner/invoices` will accept the same body modulo rate limits + the submission-mode guard.\n\n**Required fields:** `number`, `issueDate`, `buyer`, `seller`, `lines`, `trn`.\n\nBody is a catalog-complete example — every addressable field is populated so you can edit down to what your invoice actually carries. Call `POST /v1/partner/invoices/validate` to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"},{"key":"Content-Type","value":"application/json"}],"method":"POST","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices","validate"],"raw":"{{baseUrl}}/v1/partner/invoices/validate"}}},{"name":"Pre-flight TRN validation against the FTA registry","request":{"description":"Verifies a 15-digit TRN against the FTA registry before you build the invoice payload. Results are cached for 24h. Not scoped to an SME — no x-erp-partner-secret required.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","validate-trn"],"query":[{"key":"trn","value":""}],"raw":"{{baseUrl}}/v1/partner/validate-trn"}}}],"name":"validation"},{"item":[{"name":"Force-resend the last webhook payload for an invoice","request":{"description":"Creates a fresh delivery row with a refreshed timestamp so the HMAC signature stays inside your anti-replay window. Original history is preserved.\n\nBody is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"},{"key":"Idempotency-Key","value":"{{idempotencyKey}}"}],"method":"POST","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices",":id","replay-webhook"],"raw":"{{baseUrl}}/v1/partner/invoices/:id/replay-webhook"}}},{"name":"Audit trail of outbound webhook attempts for one invoice","request":{"description":"Body is a stub (`{}`) — call `POST /v1/partner/invoices/validate` with your own payload to see which rules fire before you push.","header":[{"key":"X-API-Key","value":"{{apiKey}}"},{"key":"X-API-Secret","value":"{{apiSecret}}"},{"key":"x-erp-partner-secret","value":"{{connectionSecret}}"}],"method":"GET","url":{"host":["{{baseUrl}}"],"path":["v1","partner","invoices",":id","webhook-deliveries"],"raw":"{{baseUrl}}/v1/partner/invoices/:id/webhook-deliveries"}}}],"name":"webhooks"}],"variable":[{"key":"baseUrl","type":"string","value":"https://trustbill.ae/api"},{"key":"apiKey","type":"string","value":"erp_test_..."},{"key":"apiSecret","type":"string","value":"..."},{"key":"connectionSecret","type":"string","value":"tb_secret_..."},{"key":"idempotencyKey","type":"string","value":""}]}