API keys and webhooks

Audience: Developer Time: 10 minutes

Use the envoice REST API to create and submit e-invoices from your own POS, website or back office, and webhooks to hear back when their LHDN status changes. API access needs the Pro or Enterprise plan.


1. Create an API key

Open Settings > API Keys.

API Keys tab

  1. Under Create a new key, give the key a name you will recognise (for example "Website checkout").
  2. Click Generate key.
  3. Copy the key straight away. It starts with env_ and is shown only once.

Treat keys like passwords: keep them on your server, never in a browser or mobile app. Each key belongs to one shop.

Key expiry (days) sets how long new keys last (365 days unless you change it). envoice emails the shop owner before a key expires. The table shows each key's prefix, when it was created and last used, and the days left. Click Revoke to stop a key immediately; integrations using it stop working.

2. Call the API

Send the key in the Authorization header:

Authorization: Bearer env_...

The base URL is https://envoice.my/api/v1. To create and submit an invoice, POST /invoices with JSON like this:

{
  "items": [
    { "description": "Monthly membership", "classification": "022", "quantity": "1", "unitPrice": "120.00" }
  ],
  "buyer": null,
  "paymentMode": "01",
  "idempotencyKey": "order-1001"
}
  • buyer: null files the sale as a general public sale. For a named buyer, send tin, name, idType (NRIC, PASSPORT, BRN or ARMY), idValue, phone, address, city, postcode and state.
  • idempotencyKey makes retries safe: sending the same key twice never files twice.
  • The response includes the document id, invoiceNumber, status, lhdnUuid and lhdnQrLink.

Other endpoints cover listing invoices, bulk and self-billed submission, credit, debit and refund notes, cancellation, refreshing the LHDN status, PDFs, consolidated invoices, the catalog and TIN lookup.

Settings > Usage shows requests from this shop's keys over the last 30 days, split into successful, client errors and server errors, with your top endpoints.

3. Add a webhook

Open Settings > Webhooks and click Add endpoint.

Add a webhook endpoint

  1. Enter the Endpoint URL. It must be a public HTTPS address.
  2. Under Events to subscribe, tick the events you want:
    • invoice.submitted: sent to LHDN
    • invoice.validated: LHDN accepted
    • invoice.rejected: LHDN rejected
    • invoice.cancelled: invoice cancelled
  3. Click Create endpoint.
  4. Copy the Signing secret. It is shown once.

envoice sends a POST with a JSON body of the form { "event": "...", "data": { ... }, "timestamp": "..." } and two headers: X-Envoice-Event and X-Envoice-Signature.

Verify every request. Compute an HMAC SHA-256 of the raw request body with your signing secret, hex-encode it, and compare it with the header value after sha256=. Reject the request if they differ.

Each endpoint has Pause, Enable and History (every delivery with its status) controls. Deleting an endpoint stops deliveries for good.