API Documentation

Website API Integration

Create an integration key and submit sales invoices and credit notes directly against your tenant subdomain.

Overview

Nepal E-Billing is multi-tenant. Every organization uses its own tenant subdomain, so API calls must be sent to https://{sub_domain}.{base_url}, not the public marketing domain.

The sales invoice and credit note endpoints are authenticated with an active X-API-Key. Generate the key from Dashboard > Settings > API Keys and send it directly on each request.

The generated raw_key is shown only once when the key is created, so store it in your secure server environment before leaving the settings page.

Sales invoice generation returns invoice_id and invoice_number after a successful request. Credit note generation returns credit_note_id and credit_note_number.

If your tenant is configured for PDF Ready Response, the success response can also include a generated invoice pdf_url.

Authentication

A Billing Admin can generate an integration key from Dashboard > Settings > API Keys. That settings entry is shown only when API integration is enabled for the tenant. The returned raw_key is shown only once after creation.

Send that key in the X-API-Key header on every request.

Each key carries its own permissions. Sales invoice generation unlocks the invoice endpoint and Credit note generation unlocks the credit note endpoint. Tick both when the key is generated, or add the missing one later from the key list. A key without the matching permission gets 403.

  1. Open Dashboard > Settings > API Keys as a Billing Admin.
  2. Generate the key, copy the returned raw_key, and store it securely.
  3. Tick the permissions the key needs: sales invoice generation, credit note generation, or both.
  4. Send X-API-Key with the payload to the endpoint you are calling.

Sales invoice endpoint

Method: POST

Path: /invoices/sales-invoice-generation/

Authentication header: X-API-Key: <integration_api_key>

Content type: application/json

If customer_name is Cash In Hand, then payment_mode must be CA. In that case, a receipt voucher is created automatically.

Credit note endpoint

Method: POST

Path: /invoices/sales-credit-note-generation/

Authentication header: X-API-Key: <integration_api_key> on a key holding Credit note generation.

Content type: application/json

The payload is the invoice payload plus a required reference_number, which is the invoice number of the sale being credited.

If a sales invoice with that number exists, every returned product must still be returnable on it: unknown products, and quantities beyond what is left after earlier credit notes, are rejected with 400. Returned rows are booked back against the batches they were sold from, so stock and costing stay correct.

If no sales invoice matches, reference_number is kept as free text and the products are resolved the same way the invoice endpoint resolves them. That covers crediting a sale that was never billed in Nepal E-Billing.

The credit note is created locked, reverses the VAT through the reverse VAT ledger, and is queued for IRD sync as a credit note.

Payload

The request body includes top-level customer and invoice fields plus a products array. At least one product row is required.

Top-level fields

customer_name

Required

Yes

Type

string

Notes

Customer or ledger display name. If it is exactly Cash In Hand, payment mode must be CA.

payment_mode

Required

Yes

Type

string

Notes

Supported in the current API: CA (Cash), CR (Credit), BA (Bank), QR (QR), KH (Khalti), ES (Esewa), PO (POS).

products

Required

Yes

Type

array

Notes

At least one product row is required.

phone_number

Required

No

Type

string

Notes

Recommended with customer_name to reduce duplicate client creation.

pan_number

Required

No

Type

string

Notes

Used to match or update the customer ledger if available.

alias_email

Required

No

Type

string

Notes

Current API field for customer email.

address

Required

No

Type

string

Notes

Stored against the customer ledger if provided.

notes

Required

No

Type

string

Notes

Saved on the created invoice.

reference_number

Required

No

Type

string

Notes

Optional external reference stored on the created invoice.

invoice_date

Required

No

Type

YYYY-MM-DD

Notes

If omitted, the server uses the current tenant time.

Product item fields

name

Required

Yes

Type

string

Notes

Product or service name. Missing products are auto-created as service items.

quantity

Required

Yes

Type

number

Notes

Must be greater than 0.

rate

Required

Yes

Type

number

Notes

Must be greater than or equal to 0.

taxable

Required

No

Type

boolean

Notes

If true, VAT is calculated for that line item.

discount_type

Required

No

Type

AMT | PER | NONE

Notes

Defaults to AMT when omitted.

discount

Required

No

Type

number

Notes

Non-negative. Percentage discounts must not exceed 100.

category

Required

No

Type

string

Notes

Created if it does not already exist.

unit

Required

No

Type

string

Notes

Created if it does not already exist.

Credit note fields

The credit note endpoint takes the same body as the invoice endpoint. Only these fields behave differently; every other top-level and product item field is unchanged.

reference_number

Required

Yes

Type

string

Notes

Invoice number of the sale being credited. When a sales invoice with that number exists, the returned products and quantities are validated against it; otherwise it is stored as free text.

customer_name

Required

Yes

Type

string

Notes

Same matching rules as the invoice endpoint. If it is exactly Cash In Hand, payment mode must be CA.

payment_mode

Required

Yes

Type

string

Notes

Same values as the invoice endpoint. Anything other than CR creates a payment voucher refunding the customer.

products

Required

Yes

Type

array

Notes

Rows being returned, using the same product item fields as the invoice endpoint. Each row must still be returnable on the reference invoice when that invoice is found.

invoice_date

Required

No

Type

YYYY-MM-DD

Notes

Credit note date. If omitted, the server uses the current tenant time.

Examples

JSON

Invoice payload

{
  "customer_name": "Acme Corporation",
  "payment_mode": "CA",
  "phone_number": "9845000000",
  "pan_number": "999999999",
  "address": "Kathmandu, Nepal",
  "alias_email": "billing@acme.com",
  "notes": "Invoice generated from external order #SO-1048",
  "reference_number": "SO-1048",
  "invoice_date": "2026-04-09",
  "products": [
    {
      "name": "Widget B",
      "quantity": 15,
      "rate": 9.99,
      "taxable": true,
      "discount_type": "AMT",
      "discount": 2.5,
      "category": "Gadgets",
      "unit": "piece"
    },
    {
      "name": "Service C",
      "quantity": 1,
      "rate": 150,
      "taxable": false
    }
  ]
}

cURL

Invoice request with cURL

curl --request POST \
  --url https://{sub_domain}.{base_url}/invoices/sales-invoice-generation/ \
  --header 'X-API-Key: <integration_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "customer_name": "Acme Corporation",
    "payment_mode": "CA",
    "phone_number": "9845000000",
    "pan_number": "999999999",
    "address": "Kathmandu, Nepal",
    "alias_email": "billing@acme.com",
    "notes": "Invoice generated from external order #SO-1048",
    "reference_number": "SO-1048",
    "invoice_date": "2026-04-09",
    "products": [
      {
        "name": "Widget B",
        "quantity": 15,
        "rate": 9.99,
        "taxable": true,
        "discount_type": "AMT",
        "discount": 2.5,
        "category": "Gadgets",
        "unit": "piece"
      },
      {
        "name": "Service C",
        "quantity": 1,
        "rate": 150,
        "taxable": false
      }
    ]
  }'

JavaScript

Invoice request with fetch

const invoiceResponse = await fetch(
  "https://{sub_domain}.{base_url}/invoices/sales-invoice-generation/",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": process.env.NEB_INTEGRATION_KEY ?? ""
    },
    body: JSON.stringify({
  "customer_name": "Acme Corporation",
  "payment_mode": "CA",
  "phone_number": "9845000000",
  "pan_number": "999999999",
  "address": "Kathmandu, Nepal",
  "alias_email": "billing@acme.com",
  "notes": "Invoice generated from external order #SO-1048",
  "reference_number": "SO-1048",
  "invoice_date": "2026-04-09",
  "products": [
    {
      "name": "Widget B",
      "quantity": 15,
      "rate": 9.99,
      "taxable": true,
      "discount_type": "AMT",
      "discount": 2.5,
      "category": "Gadgets",
      "unit": "piece"
    },
    {
      "name": "Service C",
      "quantity": 1,
      "rate": 150,
      "taxable": false
    }
  ]
})
  }
);

const result = await invoiceResponse.json();
console.log(result.invoice_id, result.invoice_number);

JSON

Success response

{
  "invoice_id": "6d38446f-0bb1-4acb-9f5b-4c6fa35b8861",
  "invoice_number": "SA-000123",
  "subtotal": "298.35"
}

JSON

Credit note payload

{
  "customer_name": "Acme Corporation",
  "payment_mode": "CA",
  "reference_number": "SA-000123",
  "phone_number": "9845000000",
  "pan_number": "999999999",
  "notes": "Two damaged widgets returned",
  "invoice_date": "2026-04-12",
  "products": [
    {
      "name": "Widget B",
      "quantity": 2,
      "rate": 9.99,
      "taxable": true
    }
  ]
}

cURL

Credit note request with cURL

curl --request POST \
  --url https://{sub_domain}.{base_url}/invoices/sales-credit-note-generation/ \
  --header 'X-API-Key: <integration_api_key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "customer_name": "Acme Corporation",
    "payment_mode": "CA",
    "reference_number": "SA-000123",
    "phone_number": "9845000000",
    "pan_number": "999999999",
    "notes": "Two damaged widgets returned",
    "invoice_date": "2026-04-12",
    "products": [
      {
        "name": "Widget B",
        "quantity": 2,
        "rate": 9.99,
        "taxable": true
      }
    ]
  }'

JavaScript

Credit note request with fetch

const creditNoteResponse = await fetch(
  "https://{sub_domain}.{base_url}/invoices/sales-credit-note-generation/",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": process.env.NEB_INTEGRATION_KEY ?? ""
    },
    body: JSON.stringify({
  "customer_name": "Acme Corporation",
  "payment_mode": "CA",
  "reference_number": "SA-000123",
  "phone_number": "9845000000",
  "pan_number": "999999999",
  "notes": "Two damaged widgets returned",
  "invoice_date": "2026-04-12",
  "products": [
    {
      "name": "Widget B",
      "quantity": 2,
      "rate": 9.99,
      "taxable": true
    }
  ]
})
  }
);

const result = await creditNoteResponse.json();
console.log(result.credit_note_id, result.credit_note_number);

JSON

Credit note success response

{
  "credit_note_id": "1f0c4b02-8d61-4f2c-9a77-2f4b0f9c5a13",
  "credit_note_number": "SR-000045",
  "reference_invoice_number": "SA-000123",
  "subtotal": "19.98"
}

Notes

  • Use alias_email for customer email in the invoice payload.
  • Match customers with customer_name plus at least one of phone_number, pan_number, or alias_email where possible.
  • Billing Admins can create and copy the key from Dashboard > Settings > API Keys.
  • A credit note always needs reference_number. Send the exact invoice_number returned when the sale was created so the return is matched to it.
  • The same sales invoice can be credited more than once, but only up to the quantity still outstanding on it.
  • If API integration is disabled for your tenant, the integration endpoints return403.
  • If the tenant subscription is expired, the integration endpoints also return403 until the subscription is renewed.
  • Some tenants are configured to include a generated pdf_url in the success response of both endpoints. Do not depend on that field unless your tenant is using PDF Ready Response.
  • Store the integration key in server-side environment variables and do not expose it in public browser bundles.
  • If the browser will call these APIs directly, your domain must be allowed by Nepal E-Billing CORS and web-app origin rules.
  • Keep tenant URL parts and credentials in environment variables, not hard-coded in the frontend bundle.