Validate and submit documents

The endpoint chooses the document type. Wafeq calculates totals and VAT and
derives your account's party from its registered profile. Send only the other
party as document.counterparty.

DocumentStandard clearanceSimplified reporting
Invoice/invoices/simplified-invoices
Credit note/credit-notes/simplified-credit-notes
Debit note/debit-notes/simplified-debit-notes
Prepayment invoice/prepayment-invoices/prepayment-simplified-invoices

Use POST to submit. Standard documents receive NBR clearance; simplified
documents are signed locally and reported. Credit/debit notes require their
original-document reference and reason fields; see their API reference schemas.

Example invoice

Save this example as invoice.json, replacing the document number and buyer
details with your own values:

{
  "reference": "PO-4471",
  "metadata": {"channel": "pos"},
  "document": {
    "document_number": "INV-1",
    "tax_amount_type": "exclusive",
    "currency": "BHD",
    "counterparty": {
      "name": "Example Buyer",
      "identification": {"type": "IGA", "value": "1234567890"},
      "address": {
        "street": "Road 10",
        "block": "Block 300",
        "building_name": "Tower A",
        "flat": "12",
        "city": "Riffa",
        "country": "BH"
      }
    },
    "line_items": [
      {"item": "Consulting", "unit_price": "100.00", "quantity": "1", "tax": {"type": "S"}}
    ]
  }
}

Validate it first:

curl -X POST "$BASE/invoices/validate" \
  -H "Authorization: Api-Key $KEY" \
  -H "X-NBR-Connected-Account-Id: $ACCOUNT_ID" \
  -H 'X-NBR-Sub-CR: 136690-1' \
  -H 'Content-Type: application/json' \
  --data-binary @invoice.json

Validation assembles and signs the document and checks it locally. It requires
an active device, but does not send the document to NBR or store a submission.
Inspect valid, validation_status, errors and warnings. Every document
family supports the corresponding /{family}/validate endpoint.

When it passes, send the same request to POST /invoices. Inspect accepted
and the validation and clearance/reporting statuses; HTTP 200 alone does not
mean NBR accepted the document. Store the response's uuid to retrieve the
document later. The response includes the QR code as base64 TLV data.

Parties and VAT

For ordinary sales, the connected account supplies the seller and counterparty
is the buyer. For SELF_BILLING and IMPORT_SERVICES_RCM, the account supplies the
buyer/importer and counterparty is the external seller. Do not send
document.supplier or document.customer.

Standard domestic buyer addresses require street, block, building name, flat and
city. Standard exports require an explicit country-only address. Simplified
buyer addresses may be omitted or partial; buyer name and identification/VAT
requirements still apply.

Tax category S uses the configured standard rate when percent is omitted;
explicit supported rates are 5 and 10. Categories Z, E and O use zero
VAT and require a valid Bahrain exemption reason. Non-BHD documents require a
positive exchange_rate in BHD per document-currency unit.

For THIRD_PARTY accounts, Wafeq adds the agent and THIRD_PARTY indicator from
the account and organization. Do not supply inline third_party details or a
THIRD_PARTY document indicator. reference and metadata stay in Wafeq and are
not sent to NBR.

Bulk invoices

Standard and simplified invoices support up to 100 items through
/{family}/bulk and /{family}/bulk-validate. The body is
{"invoices":[{"document":{...}}]}. A batch targets one taxpayer and branch;
each item is processed independently. Check every result's index, accepted,
errors, warnings and processing error. Notes and prepayment invoices use
single-document submission.