{
    "info": {
        "_postman_id": "40334186-be3e-476a-a99a-68265f31c710",
        "name": "TourismRevenue Integrator API v1",
        "description": "Issue fiscal invoices and account for the Tourism Development Contribution straight from the software a business already runs.\n\nAuthentication: Authorization: Bearer sk_live_… (or sk_test_… for the sandbox). An integrator key must also name the business it is acting for in X-Operator-Code, and hold that business's active grant.\n\nMoney is kobo integers, in and out. Never send a float.\n\nEvery POST needs an Idempotency-Key: the same key with the same body replays the first answer, and the same key with a different body is refused. A retry on a bad network must never become a second sale.\n\nLimits: 120 calls a minute per key, 600 per address; answers stay replayable for 7 days.",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
    },
    "auth": {
        "type": "bearer",
        "bearer": [
            {
                "key": "token",
                "value": "{{secret_key}}",
                "type": "string"
            }
        ]
    },
    "variable": [
        {
            "key": "base_url",
            "value": "https://tourismrevenue.co",
            "type": "string"
        },
        {
            "key": "secret_key",
            "value": "sk_test_replace_me",
            "type": "string"
        },
        {
            "key": "operator_code",
            "value": "REPLACE-ME",
            "type": "string"
        }
    ],
    "item": [
        {
            "name": "Diagnostics",
            "description": "Prove a key works before anything is built on it.",
            "item": [
                {
                    "name": "Check a key works",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/ping",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "ping"
                            ]
                        },
                        "description": "Answers 200 for any key that is valid, unrevoked and unexpired. It needs no scope and no X-Operator-Code, so it is the first call to make on the day a key is issued — before any business has authorised you. The answer says which environment the key resolves to; if that says sandbox when you expected live, stop and fix it here rather than three endpoints later.\n\nScope: none — any valid key."
                    },
                    "response": []
                },
                {
                    "name": "Describe the calling key",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/whoami",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "whoami"
                            ]
                        },
                        "description": "The key's owner, environment and scopes — and, when X-Operator-Code is present, the business it is acting for and the scopes that business has actually granted, which may be narrower. Read this before debugging a 403; quote it in a support ticket. The key itself is never echoed, only its public prefix.\n\nScope: none — any valid key."
                    },
                    "response": []
                }
            ]
        },
        {
            "name": "Invoices",
            "description": "Issue, read and correct fiscal invoices. This is where the levy is charged.",
            "item": [
                {
                    "name": "Issue an invoice",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices"
                            ]
                        },
                        "description": "Prices the lines against the tariff in force at the tax point, builds the canonical fiscal document and puts it through the tax service inline, so a till gets the IRN and the QR back in the same round trip it made the sale in. Send \"async\": true to have the lodgement queued instead and poll the document — either way the DOCUMENT exists before this returns. This is the call that charges the levy, so it is idempotent by construction: the same Idempotency-Key with the same body returns the first answer and issues nothing further.\n\nScope: invoices:write.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"kind\": \"B2C\",\n    \"document_type\": \"customer_invoice\",\n    \"external_ref\": \"folio-10482\",\n    \"customer\": {\n        \"name\": \"Adaeze Okafor\",\n        \"phone\": \"08030000000\",\n        \"email\": \"guest@example.ng\"\n    },\n    \"lines\": [\n        {\n            \"category\": \"ROOM_NIGHT\",\n            \"description\": \"Deluxe room · 2 nights\",\n            \"quantity\": 2,\n            \"unit_price\": 4500000\n        },\n        {\n            \"category\": \"SERVICE_CHARGE\",\n            \"description\": \"Service charge\",\n            \"quantity\": 1,\n            \"unit_price\": 450000\n        }\n    ],\n    \"payment_status\": \"paid\",\n    \"payment_means_code\": \"42\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Price a sale without issuing it",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/preview",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                "preview"
                            ]
                        },
                        "description": "Runs exactly the pricing the issue call would run — the same tariff version, the same exemptions, the same rounding — and returns the totals and the priced lines. No document, no IRN, no levy. Show the guest this total; issue the same body afterwards and the figures will match. It still takes an Idempotency-Key: one POST helper on your side, one rule to remember.\n\nScope: invoices:write.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"kind\": \"B2C\",\n    \"lines\": [\n        {\n            \"category\": \"ROOM_NIGHT\",\n            \"description\": \"Standard room · 1 night\",\n            \"quantity\": 1,\n            \"unit_price\": 3500000\n        }\n    ]\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Issue a batch of invoices",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/bulk",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                "bulk"
                            ]
                        },
                        "description": "For a till that has been offline: send the sales it took while it could not reach us, oldest first. Every row is priced and validated BEFORE any document is issued, the per-row outcome is durable (poll the batch long after this request has gone), and a batch whose content has been sent before is refused rather than issued twice. The documents are created in this request; the tax service half is queued, so watch the batch or subscribe to invoice.signed.\n\nScope: invoices:write.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"rows\": [\n        {\n            \"external_ref\": \"till-3-2026-09-04-0001\",\n            \"issued_at\": \"2026-09-04 19:41:00\",\n            \"kind\": \"B2C\",\n            \"lines\": [\n                {\n                    \"category\": \"FOOD_BEVERAGE\",\n                    \"description\": \"Dinner\",\n                    \"quantity\": 1,\n                    \"unit_price\": 1250000\n                }\n            ]\n        }\n    ]\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "List invoices",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices"
                            ],
                            "query": [
                                {
                                    "key": "status",
                                    "value": "",
                                    "description": "One document status, e.g. confirmed.",
                                    "disabled": true
                                },
                                {
                                    "key": "kind",
                                    "value": "",
                                    "description": "B2C, B2B or B2G.",
                                    "disabled": true
                                },
                                {
                                    "key": "type",
                                    "value": "",
                                    "description": "A document type, e.g. customer_invoice.",
                                    "disabled": true
                                },
                                {
                                    "key": "from",
                                    "value": "",
                                    "description": "Issue date on or after this date (YYYY-MM-DD).",
                                    "disabled": true
                                },
                                {
                                    "key": "to",
                                    "value": "",
                                    "description": "Issue date on or before this date (YYYY-MM-DD).",
                                    "disabled": true
                                },
                                {
                                    "key": "search",
                                    "value": "",
                                    "description": "Free text over number, reference and customer.",
                                    "disabled": true
                                },
                                {
                                    "key": "page",
                                    "value": "",
                                    "description": "Page number, from 1.",
                                    "disabled": true
                                },
                                {
                                    "key": "per_page",
                                    "value": "",
                                    "description": "Rows per page (maximum 100).",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "The documents this business has issued, newest first. A sandbox key sees sandbox documents and a live key sees live ones: the two money worlds never appear in one list, and the count is deliberately per-page rather than a total, because a total across both worlds would tell a test key how many real documents exist.\n\nScope: invoices:read."
                    },
                    "response": []
                },
                {
                    "name": "Retrieve one invoice",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/{uid}",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                ":uid"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The document uid returned when it was issued (26 characters)."
                                }
                            ]
                        },
                        "description": "One document in full: its lines, its taxes, its parties, its levy and where it has got to with the tax service. Poll this after an async issue if you would rather not wait for the invoice.confirmed webhook.\n\nScope: invoices:read."
                    },
                    "response": []
                },
                {
                    "name": "Download the fiscal PDF",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/{uid}/pdf",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                ":uid",
                                "pdf"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The document uid."
                                }
                            ]
                        },
                        "description": "The customer's copy, with the QR code and the verification address on it. The only endpoint here that does not answer JSON — a PDF base64'd into an envelope is a third larger and has to be decoded before it can reach a printer. Every REFUSAL on this route is still the usual envelope, so your error handling is unchanged.\n\nScope: invoices:read."
                    },
                    "response": []
                },
                {
                    "name": "Get the fiscal QR",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/{uid}/qr",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                ":uid",
                                "qr"
                            ],
                            "query": [
                                {
                                    "key": "format",
                                    "value": "",
                                    "description": "png for the image bytes; omit for JSON.",
                                    "disabled": true
                                }
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The document uid."
                                }
                            ]
                        },
                        "description": "JSON by default: a data URI a till can drop straight into its receipt template, plus the verification URL the QR encodes. Add ?format=png for the image bytes if you would rather not decode base64.\n\nScope: invoices:read."
                    },
                    "response": []
                },
                {
                    "name": "The signed e-invoice, as sent",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/{uid}/einvoice",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                ":uid",
                                "einvoice"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The document uid."
                                }
                            ]
                        },
                        "description": "The canonical document as it was signed, with the tax service's answer. This is the endpoint an accounting package archives. The document arrives as a STRING, not a nested object, and deliberately so: the signature covers THOSE bytes, and re-serialising them through our encoder would reorder keys and reformat decimals until the archive you kept was no longer the thing that was signed.\n\nScope: invoices:read."
                    },
                    "response": []
                },
                {
                    "name": "Credit an invoice",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/{uid}/credit-note",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                ":uid",
                                "credit-note"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The uid of the invoice being corrected."
                                }
                            ]
                        },
                        "description": "The only way to reverse or reduce a document that has already been lodged. It is a fiscal document in its own right (type 381), it references the original, and the levy it reverses is credited back on the ledger. Omit the lines to credit the invoice in full.\n\nScope: invoices:write.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"reason\": \"Room rate corrected after the guest complained at checkout.\",\n    \"lines\": [\n        {\n            \"category\": \"ROOM_NIGHT\",\n            \"description\": \"Rate correction\",\n            \"quantity\": 1,\n            \"unit_price\": 500000\n        }\n    ]\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Charge more against an invoice",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/{uid}/debit-note",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                ":uid",
                                "debit-note"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The uid of the original invoice."
                                }
                            ]
                        },
                        "description": "A further charge on a document that has already been lodged (type 383) — a minibar bill found after checkout, a late cancellation fee. It carries its own levy and it references the original.\n\nScope: invoices:write.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"reason\": \"Minibar consumption found after departure.\",\n    \"lines\": [\n        {\n            \"category\": \"FOOD_BEVERAGE\",\n            \"description\": \"Minibar\",\n            \"quantity\": 1,\n            \"unit_price\": 320000\n        }\n    ]\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Reissue a corrected invoice",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/invoices/{uid}/correction",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "invoices",
                                ":uid",
                                "correction"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The uid of the document being corrected."
                                }
                            ]
                        },
                        "description": "Replaces a document's content with corrected content (type 384), referencing what it corrects. Use it when the figures were right but the document was wrong — a mistyped TIN, the wrong buyer. Where the money changes, credit and reissue instead.\n\nScope: invoices:write.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"reason\": \"Buyer TIN was mistyped at the desk.\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "How a bulk request turned out",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/batches/{id}",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "batches",
                                ":id"
                            ],
                            "variable": [
                                {
                                    "key": "id",
                                    "value": "",
                                    "description": "The batch id returned by the bulk call."
                                }
                            ]
                        },
                        "description": "The outcome of a bulk submission, row by row: what was issued, what was refused and why. It stays answerable long after the request that created it, which is what makes an offline catch-up auditable rather than hopeful.\n\nScope: invoices:read."
                    },
                    "response": []
                }
            ]
        },
        {
            "name": "Documents",
            "description": "Fiscal documents received from suppliers, and the buyer's answer to them.",
            "item": [
                {
                    "name": "The inbox",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/documents/received",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "documents",
                                "received"
                            ],
                            "query": [
                                {
                                    "key": "response",
                                    "value": "",
                                    "description": "pending, accepted or rejected.",
                                    "disabled": true
                                },
                                {
                                    "key": "from",
                                    "value": "",
                                    "description": "Received on or after (YYYY-MM-DD).",
                                    "disabled": true
                                },
                                {
                                    "key": "to",
                                    "value": "",
                                    "description": "Received on or before (YYYY-MM-DD).",
                                    "disabled": true
                                },
                                {
                                    "key": "page",
                                    "value": "",
                                    "description": "Page number, from 1.",
                                    "disabled": true
                                },
                                {
                                    "key": "per_page",
                                    "value": "",
                                    "description": "Rows per page (maximum 100).",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "Fiscal documents OTHER businesses have issued to this one — what a bookkeeping integration reconciles payables against. ?response=pending returns exactly the ones still owed an answer, which is the query worth running on a timer, and each row carries the seconds left on its 72-hour deadline so you can escalate without doing date arithmetic against our clock.\n\nScope: documents:read."
                    },
                    "response": []
                },
                {
                    "name": "Accept a document",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/documents/{uid}/accept",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "documents",
                                ":uid",
                                "accept"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The received document's uid."
                                }
                            ]
                        },
                        "description": "The buyer agrees the document is correct. The answer goes on to the tax service and stops the deadline clock.\n\nScope: documents:write.\n\nNOTE: the door computes a scope for this endpoint that no key can currently hold, so it answers 403 insufficient_scope until its resource is mapped in ApiKeyAuth::RESOURCE_SCOPES.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"note\": \"Matched to purchase order PO-8841.\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Reject a document",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/documents/{uid}/reject",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "documents",
                                ":uid",
                                "reject"
                            ],
                            "variable": [
                                {
                                    "key": "uid",
                                    "value": "",
                                    "description": "The received document's uid."
                                }
                            ]
                        },
                        "description": "The buyer disputes it. A reason is required and is sent on: rejection obliges the supplier to credit and reissue, and \"rejected\" with no explanation turns a two-day correction into a fortnight of telephone calls.\n\nScope: documents:write.\n\nNOTE: the door computes a scope for this endpoint that no key can currently hold, so it answers 403 insufficient_scope until its resource is mapped in ApiKeyAuth::RESOURCE_SCOPES.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"reason\": \"Quantity billed does not match the delivery note.\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                }
            ]
        },
        {
            "name": "Operators",
            "description": "The business this key acts for, whether it can issue, and asking a new one for consent.",
            "item": [
                {
                    "name": "The business this key acts for",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/operators/me",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "operators",
                                "me"
                            ]
                        },
                        "description": "The register's record of the operator named in X-Operator-Code (or the one an operator-owned key is bound to): its code, its legal name, its trade, its premises. Codes and names, never our primary keys — an id you stored would be a number that means nothing outside our database and that we have never promised to keep.\n\nScope: operators:read."
                    },
                    "response": []
                },
                {
                    "name": "Can this business issue right now?",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/operators/me/einvoicing",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "operators",
                                "me",
                                "einvoicing"
                            ]
                        },
                        "description": "\"ready\" is the whole answer a till needs before it offers to issue: true only when a credential actually resolves for this business in THIS environment. When it is false the reason is given as text, because the fix is always somebody's action — enter your tax-service keys, finish onboarding — and a machine code would not tell them which. Call it at start-up.\n\nScope: operators:read."
                    },
                    "response": []
                },
                {
                    "name": "Ask a business for consent",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/operators/link",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "operators",
                                "link"
                            ]
                        },
                        "description": "Raises a link request against a business by its operator code. It grants nothing: the business accepts it in its own portal, and until it does, every call naming that business is refused operator_not_linked. THE INVITE CODE IS NOT RETURNED — an answer to a POST is stored for idempotent replay, and a code stored anywhere is a code somebody else could redeem. \"No such business\" and \"that business is not open to linking\" answer identically, so a vendor cannot walk the operator register from a refusal message.\n\nScope: operators:write.\n\nNOTE: the door computes a scope for this endpoint that no key can currently hold, so it answers 403 insufficient_scope until its resource is mapped in ApiKeyAuth::RESOURCE_SCOPES.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"operator_code\": \"LAG-HTL-0042\",\n    \"scopes\": [\n        \"invoices:read\",\n        \"invoices:write\"\n    ],\n    \"note\": \"Front-desk till integration\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                }
            ]
        },
        {
            "name": "Reference",
            "description": "The tariff, the charge categories, the code lists and the currency rule — read these, never hard-code them.",
            "item": [
                {
                    "name": "The levy schedule in force",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/tariff",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "tariff"
                            ]
                        },
                        "description": "The Tourism Development Contribution schedule that governs today, already narrowed to the pilot and the state of the business you are acting for. Cells are published by CODE, never by our primary keys, and \"*\" in a dimension means every value of it. Never hard-code a rate: it is set by an approved tariff version and it can change between one booking and the next.\n\nScope: operators:read."
                    },
                    "response": []
                },
                {
                    "name": "What this business may bill for",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/charge-categories",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "charge-categories"
                            ]
                        },
                        "description": "The charge lines this business may put on an invoice, with the ones its trade uses first, and whether each attracts the levy. A till renders its buttons from this rather than from a list someone typed into its configuration two versions ago.\n\nScope: operators:read."
                    },
                    "response": []
                },
                {
                    "name": "A tax-service code list",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/resources/{kind}",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "resources",
                                ":kind"
                            ],
                            "variable": [
                                {
                                    "key": "kind",
                                    "value": "",
                                    "description": "The list to fetch, e.g. currencies, invoice-types, payment-means, tax-categories."
                                }
                            ]
                        },
                        "description": "The code lists a document is VALIDATED against before it can be signed — currencies, invoice types, payment means, tax categories. Build your dropdowns from these and you cannot send us a code we will reject. They are served for the KEY'S environment: the sandbox catalogue and the live one are different lists, and a sandbox key must never be shown the live one and believe it has been checked.\n\nScope: operators:read."
                    },
                    "response": []
                },
                {
                    "name": "The currency rule",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/fx",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "fx"
                            ]
                        },
                        "description": "What currency the levy is computed in, and the rule for a document that is not in it. The platform does not invent an exchange rate: a document in another currency carries the rate the SELLER used, and it is rejected without one. Where no reference rate has been published, this says so plainly rather than handing your till a number we made up — a levy computed against an invented rate is a reconciliation ticket with a date on it.\n\nScope: operators:read."
                    },
                    "response": []
                }
            ]
        },
        {
            "name": "Remittances",
            "description": "What the business owes, what it has paid, and how to pay it.",
            "item": [
                {
                    "name": "The periods and the position",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/remittances",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "remittances"
                            ],
                            "query": [
                                {
                                    "key": "status",
                                    "value": "",
                                    "description": "open, issued, part_paid, paid, overdue.",
                                    "disabled": true
                                },
                                {
                                    "key": "year",
                                    "value": "",
                                    "description": "Calendar year, e.g. 2026.",
                                    "disabled": true
                                },
                                {
                                    "key": "page",
                                    "value": "",
                                    "description": "Page number, from 1.",
                                    "disabled": true
                                },
                                {
                                    "key": "length",
                                    "value": "",
                                    "description": "Rows per page.",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "What this business owes, what it has paid and when the next payment falls due — the figures behind the \"TDC due\" line an accounting integration shows its user, reconciled to the levy ledger.\n\nScope: levy:read."
                    },
                    "response": []
                },
                {
                    "name": "Enrol a direct debit",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/remittances/mandate",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "remittances",
                                "mandate"
                            ]
                        },
                        "description": "Standing permission to collect the levy from the business's own account. AN INTEGRATOR KEY IS REFUSED HERE whatever it is linked for: the consent a business gives a vendor is permission to handle its fiscal documents, and taking money out of its bank account is not a side effect of that. A business that wants its vendor to set this up mints an operator-owned key, which is a decision it takes deliberately and can revoke on its own screen. Consent must be evidenced, and only the masked account is ever stored.\n\nScope: levy:write.\n\nNOTE: the door computes a scope for this endpoint that no key can currently hold, so it answers 403 insufficient_scope until its resource is mapped in ApiKeyAuth::RESOURCE_SCOPES.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"bank_code\": \"070\",\n    \"account_number\": \"0123456789\",\n    \"account_name\": \"Lagoon Hotels Limited\",\n    \"consent_evidence\": \"Signed direct-debit instruction, 4 September 2026\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "One period in full",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/remittances/{ref}",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "remittances",
                                ":ref"
                            ],
                            "variable": [
                                {
                                    "key": "ref",
                                    "value": "",
                                    "description": "The remittance reference, as it appears on the statement."
                                }
                            ]
                        },
                        "description": "What the period bills, what has landed against it, and the account it is being collected on — with the evidence that reconciles the two.\n\nScope: levy:read."
                    },
                    "response": []
                },
                {
                    "name": "Get the payment instruction",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/remittances/{ref}/pay",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "remittances",
                                ":ref",
                                "pay"
                            ],
                            "variable": [
                                {
                                    "key": "ref",
                                    "value": "",
                                    "description": "The remittance reference."
                                }
                            ]
                        },
                        "description": "Hands back how to pay a period: the account, the reference and the amount. A second call with the same Idempotency-Key replays the first answer, and a call with a NEW key still does not open a second account — the business may already have typed that account number into its banking app, and changing it underneath them is how a payment goes to a dead reference.\n\nScope: levy:write.\n\nNOTE: the door computes a scope for this endpoint that no key can currently hold, so it answers 403 insufficient_scope until its resource is mapped in ApiKeyAuth::RESOURCE_SCOPES.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"channel\": \"transfer\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                }
            ]
        },
        {
            "name": "Tickets",
            "description": "High-volume gate admissions and the day-sheets they close into.",
            "item": [
                {
                    "name": "Post a batch of gate taps",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/tickets/bulk",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "tickets",
                                "bulk"
                            ]
                        },
                        "description": "For attractions: admissions in bulk, up to a whole session at a time. The WHOLE batch is validated before any of it is recorded — a row with a malformed price must not leave half a morning's admissions in the ledger and half rejected, because nobody can tell from the day-sheet which half is missing. Once recording starts, a row the domain refuses is reported against its group and the rest still land.\n\nScope: invoices:write.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"rows\": [\n        {\n            \"premises_id\": 12,\n            \"ticket_type\": \"Adult\",\n            \"qty\": 2,\n            \"unit_price\": 150000,\n            \"device_code\": \"GATE1\"\n        },\n        {\n            \"premises_id\": 12,\n            \"ticket_type\": \"Child\",\n            \"qty\": 1,\n            \"unit_price\": 75000,\n            \"device_code\": \"GATE1\"\n        }\n    ]\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Day-sheets and running totals",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/tickets/daysheets",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "tickets",
                                "daysheets"
                            ],
                            "query": [
                                {
                                    "key": "premises_id",
                                    "value": "",
                                    "description": "One gate, with its live running total.",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "The recent premises-days and where each one stands: still open, or closed with the day-sheet document it produced. ?premises_id adds the live running total for that gate, which is the screen a gate app renders behind its +1 buttons.\n\nScope: invoices:read."
                    },
                    "response": []
                }
            ]
        },
        {
            "name": "Webhooks",
            "description": "Endpoints we deliver events to, and the signed deliveries themselves.",
            "item": [
                {
                    "name": "Endpoints, events and the signature scheme",
                    "request": {
                        "method": "GET",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/webhooks",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "webhooks"
                            ],
                            "query": [
                                {
                                    "key": "mode",
                                    "value": "",
                                    "description": "live or test.",
                                    "disabled": true
                                }
                            ]
                        },
                        "description": "This key's registered endpoints, plus everything needed to build a receiver without opening the documentation: the event catalogue, the signature scheme, the retry ladder and the limits. The scheme is published beside the endpoints because a receiver that verifies signatures wrongly fails in the one way nobody notices until an event matters. Signing secrets are never in this list.\n\nScope: webhooks:manage."
                    },
                    "response": []
                },
                {
                    "name": "Register a receiver",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/webhooks",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "webhooks"
                            ]
                        },
                        "description": "Registers an HTTPS URL and mints its signing secret. THE SECRET IS RETURNED ONCE, in this response, and can never be read again — store it before you close the connection. The URL is vetted before anything is stored and again before every delivery: https only, a public address, no userinfo, no private or link-local host. A webhook is an outbound request WE make on your say-so, so an unvetted URL would be a request forgery with our network behind it.\n\nScope: webhooks:manage.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"url\": \"https://api.yourcompany.com/hooks/tourismrevenue\",\n    \"events\": [\n        \"invoice.confirmed\",\n        \"invoice.failed\",\n        \"remittance.due\"\n    ],\n    \"mode\": \"test\",\n    \"description\": \"Production till fleet\"\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Send a signed test event",
                    "request": {
                        "method": "POST",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            },
                            {
                                "key": "Idempotency-Key",
                                "value": "{{$guid}}"
                            },
                            {
                                "key": "Content-Type",
                                "value": "application/json"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/webhooks/test",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "webhooks",
                                "test"
                            ]
                        },
                        "description": "Delivers a signed webhook.ping to one of your endpoints so you can prove your signature check before a real invoice depends on it. It is a normal delivery — same signing, same retry ladder, same log — because a test that took a different path would prove nothing about the path that matters. The ping is not subscribable and is never fanned out to anybody else.\n\nScope: webhooks:manage.",
                        "body": {
                            "mode": "raw",
                            "raw": "{\n    \"endpoint_id\": 1\n}",
                            "options": {
                                "raw": {
                                    "language": "json"
                                }
                            }
                        }
                    },
                    "response": []
                },
                {
                    "name": "Stop sending to a receiver",
                    "request": {
                        "method": "DELETE",
                        "header": [
                            {
                                "key": "Accept",
                                "value": "application/json"
                            },
                            {
                                "key": "X-Operator-Code",
                                "value": "{{operator_code}}"
                            }
                        ],
                        "url": {
                            "raw": "{{base_url}}/api/v1/webhooks/{id}",
                            "host": [
                                "{{base_url}}"
                            ],
                            "path": [
                                "api",
                                "v1",
                                "webhooks",
                                ":id"
                            ],
                            "variable": [
                                {
                                    "key": "id",
                                    "value": "",
                                    "description": "The endpoint id."
                                }
                            ]
                        },
                        "description": "The endpoint goes; its deliveries do not. What we sent is evidence and is append-only, including for an endpoint somebody has since removed. Deleting twice is not an error, so this needs no Idempotency-Key.\n\nScope: webhooks:manage."
                    },
                    "response": []
                }
            ]
        }
    ]
}