Docs / API reference

Authentication and scopes

Create Invoa API keys, send them as a bearer token or x-api-key header, choose the least scopes an integration needs, and keep keys safe.

The Invoa API authenticates every request with an API key. Each key belongs to one company and carries a set of scopes that decide which endpoints it can call.

Create an API key

You need the owner or admin role.

  1. Open Settings → API keys.
  2. Under Create key, enter a Name that says where the key is used, for example "Lembah Bayu booking system".
  3. Choose the Mode: Live (inv_live_…) or Test (inv_test_…).
  4. Under Permissions, tick the scopes the integration needs. Only documents:read is ticked by default.
  5. Click Create key and copy the key.

Important: The full key is shown once. Invoa stores only a hash of it. If you lose it, create a new key and revoke the old one.

The Existing keys table shows each key's name, its prefix (for example inv_live_ab12cd34…), scopes, when it was last used, and whether it is active or revoked.

Live and test keys

PrefixMode
inv_live_Live key.
inv_test_Test key.

Test keys behave exactly like live keys and act on the same company's real data. There is no separate sandbox. The prefix only helps your systems tell keys apart. To experiment safely, use a separate company in Invoa.

Send the key

Send the key as a bearer token:

bash
curl https://app.invoa.io/api/v1/documents \
  -H "Authorization: Bearer inv_live_xxxxxxxxxxxxxxxx"

The x-api-key header is also accepted:

bash
curl https://app.invoa.io/api/v1/documents \
  -H "x-api-key: inv_live_xxxxxxxxxxxxxxxx"

A missing key returns 401 unauthenticated. An unknown or revoked key returns 401 invalid_api_key. See Errors, limits and pagination.

Scopes

ScopeGrants
documents:readEvery GET endpoint: contacts, items, documents, PDFs, payments, billing schedules, e-invoice status, webhook endpoints.
contacts:writePOST /contacts, PATCH /contacts/{id}.
documents:draftPOST /documents (drafts), POST /items, POST /schedules, POST /schedules/items/{id}/trigger (plus documents:issue and documents:send for schedules that issue automatically), and creating, updating and deleting webhook endpoints.
documents:issuePOST /documents/{id}/issue, POST /documents/{id}/void.
documents:sendPOST /documents/{id}/send.
payments:writePOST /payments.
einvoice:submitPOST /einvoice/{documentId}/submit.

A key without the required scope gets 403 insufficient_scope:

json
{
  "error": {
    "code": "insufficient_scope",
    "message": "This API key lacks the \"documents:issue\" scope.",
    "details": { "required_scope": "documents:issue", "granted": ["documents:read", "documents:draft"] }
  }
}

Note: API keys skip the human approval step that applies to Claude. A key with documents:issue issues and voids immediately, and a key with einvoice:submit submits to LHDN immediately. Triggering a milestone on a billing schedule set to issue automatically issues and emails the invoice, so the key also needs documents:issue and documents:send. Give each key only what it needs.

Revoke a key

In Settings → API keys, click Revoke next to the key (owner or admin). Requests with that key fail with 401 invalid_api_key from then on. Revoked keys stay in the list, marked Revoked.

Keep keys safe

  • Keep keys on your server, in environment variables or a secret manager. Never put a key in a browser, mobile app or public repository.
  • Use one key per integration, so you can revoke one without breaking the others.
  • Revoke keys you no longer use. Last used in the keys table helps you spot them.
  • If a key may have leaked, create a replacement, deploy it, then revoke the old key.
  • Invoa never asks for your API keys by email or phone.

Something unclear or out of date? Tell us at hello@invoa.io and we'll fix the page.