Tax Star E-Invoice OAuth API
Integrate your software with the Tax Star E-Invoice platform. One API to register applications, manage users and companies, and dispatch legally compliant invoices to the UAE Peppol network — all secured with OAuth 2.0 client credentials.
Not writing an integration? If you already invoice from QuickBooks, Xero, Zoho Books, Odoo, Wafeq or Naqood, connect that system instead and skip the API entirely — application documentation.
Reselling Tax Star E-Invoice? Resellers have their own endpoints, with either a reseller account or reseller access on the account you already have — both arranged with Tax Star by email. Bringing your own clients to Tax Star? Pre-register them with the Partner API, from any app on this page, and get a webhook when each one is onboarded. Partner overview · Reseller accounts · Account types and roles.
Base URL
Developmenthttps://dev-api.taxstar.app/einvAll endpoints are relative to this base. Every resource endpoint requires Authorization: Bearer <access_token>.
Quickstart
Four steps from zero to your first invoice on the Peppol network.
Register an application
Sign in as a developer and call POST /oauth/apps. You receive a client_id and a client_secret (shown once — store it securely). The app starts as PENDING; an admin approves it before tokens are issued.
Get an access token
Exchange your credentials at POST /oauth/token with grant_type=client_credentials. The response gives an access_token (short-lived) and a refresh_token. All resource endpoints need the Bearer access_token.
Get your entity
Complete FTA onboarding to create your company entity, then call GET /oauth/entities to find its entity_id. Use that seller identifier on every invoice.
Send an invoice
POST /oauth/invoices with the entity_id from GET /oauth/entities, buyer, and line items. Totals are computed automatically. The invoice is validated, converted to XML, and dispatched to the UAE Peppol network in the background. Not sure the data is right? Send the same body to POST /oauth/invoices/validate first — it validates without sending.
API overview
Every endpoint, grouped by resource. Click a card to go to the full reference.
Exchange client credentials for a short-lived access token and a refresh token. Use the refresh token to get a new access token without re-supplying credentials.
POST /oauth/token grant_type=client_credentialsPOST /oauth/token grant_type=refresh_token
Inspect the application behind the current access token. Useful for debugging and validating that the right credentials are in use.
GET /oauth/me — return app identity
Create end-users scoped to your application. Users own their own entities and invoices. A user can even create further users, letting you build a hierarchy within one app.
POST /oauth/users — create a userGET /oauth/users — list usersGET /oauth/users/{id} — get a user
List and manage companies (entities) provisioned through FTA onboarding. Each entity holds its TRN, address, and contact details and can be owned by any user of your app.
GET /oauth/entities — list entitiesPATCH /oauth/entities/{id} — update
Create, validate, and dispatch invoices to the UAE Peppol network, with supporting documents attached. Send one invoice or a batch of invoices in a single call, or dry-run the validation first. Also list and inspect sent and received invoices, and download them as PDF or their attachments.
POST /oauth/invoices — push a single invoicePOST /oauth/invoices/bulk — push multiple at oncePOST /oauth/invoices/validate — dry-run validationGET /oauth/invoices/sent — list sent invoicesGET /oauth/invoices/received — list received invoicesGET /oauth/invoices/{sent|received}/{id}/pdf — the invoice as PDFGET /oauth/invoices/{sent|received}/{id}/attachments/{index} — one attachment
Register HTTPS endpoints and subscribe to invoice lifecycle events. Tax Star signs every payload so you can verify it came from us. Rotate secrets at any time without downtime.
POST /oauth/webhooks — create an endpointPATCH /oauth/webhooks/{id} — update subscriptionPOST /oauth/webhooks/{id}/rotate-secretDELETE /oauth/webhooks/{id} — remove
Key features
Capabilities beyond simple CRUD — built for production invoice automation.
Validate before you send
POST /oauth/invoices/validate runs the exact PINT-AE rules the send pipeline runs, without storing or dispatching anything. Fix what it reports and the send will pass.
Bulk invoice sending
POST /oauth/invoices/bulk accepts an array of invoice objects. Each is processed independently — one failure never blocks the rest. Returns HTTP 207 with per-item status codes.
Signed webhook events
Subscribe to invoice.sent, invoice.delivered, invoice.failed, invoice.received, and invoice.status_changed. Every payload carries an HMAC signature so you can verify authenticity.
UAE Peppol network
Invoices are dispatched via the UAE national Peppol framework. The API handles XML generation, schema validation (EN 16931 + BTUAE), and network delivery.
OAuth 2.0 client credentials
Standard grant_type=client_credentials flow. Tokens are short-lived; refresh tokens rotate on every use. Secret rotation is non-disruptive — the old secret stops working immediately.
Multi-user hierarchy
One application can own many users. Each user owns their own entities and invoices. Pass created_by_user_id on POST /oauth/users to build a tree of sub-accounts under one app.
Validated up front, delivered async
POST /oauth/invoices validates the invoice before accepting it — a failure is a 422 with the rule errors and nothing is queued. A valid invoice returns 202 and moves through a Temporal workflow: re-validate → generate XML → deliver. Track progress with GET /oauth/invoices/{id}/status.
Ownership model
Every resource belongs to your application. Within it, users own entities, and entities own invoices. You can omit the user_id on most calls to attribute everything directly to the application owner — handy for simple single-tenant integrations.
Application
client_id + client_secret
owns all resources; must be approved
Users
optional sub-accounts
each user can own their own entities
Entities
companies / TRNs
the invoice sender; holds TRN & address
Invoices
sent & received
scoped to an entity; tracked per-app
Response codes
All errors return a JSON body with an error key. Validation errors return an array of field-level messages.
| Code | Status | Meaning |
|---|---|---|
| 200 | OK | Successful GET / PATCH / DELETE |
| 202 | Accepted | Invoice passed validation and is queued for async processing |
| 207 | Multi-Status | Bulk invoice results (per-item codes inside) |
| 400 | Bad Request | Request body does not match the schema — see error field |
| 401 | Unauthorized | Missing or expired access token |
| 404 | Not Found | Resource does not exist or does not belong to your app |
| 409 | Conflict | Duplicate invoice number for the same entity |
| 422 | Unprocessable Entity | Invoice failed PINT-AE validation and was not stored or queued — see errors |
| 429 | Too Many Requests | Rate limit exceeded — wait the seconds in the Retry-After header, then retry |
| 502 | Bad Gateway | Peppol network delivery failed |
Rate limits
Limits are per application: all of an application's users and entities share them. Every request counts as one, a bulk send included. Over a limit the API answers 429 with {"error": "rate_limit_exceeded", "retry_after": 12}. Reuse your access token until shortly before it expires rather than requesting one per call.
| Applies to | Limit |
|---|---|
| All resource endpoints | 20 requests per second and 600 per minute, per application |
| POST /oauth/token | 30 requests per minute, per client_id |
| Invoices with attachments | 30 per minute and 300 per hour, per application, on top of the limit above — Push invoice, Validate an invoice and Update & resend with files, and each invoice with files in a bulk send |
| Attachment downloads | 120 per minute, per application, on top of the limit above |
| Invoice PDFs | 30 per minute, per application, on top of the limit above |
| Response header | Meaning |
|---|---|
| X-RateLimit-Limit | Requests allowed in the current window |
| X-RateLimit-Remaining | Requests left in that window |
| X-RateLimit-Reset | When the window resets, in unix seconds |
| Retry-After | On a 429 only: seconds to wait before retrying |
Authentication
All resource endpoints (Users, Entities, Invoices, Webhooks) require an Authorization: Bearer <access_token> header. Application management endpoints (POST /oauth/apps and related) require a developer login token instead. The Token endpoint itself is public — no auth header needed to exchange credentials.