- Reference
Authentication
Use this page to authenticate each call that your app sends to the Wafeq ASP API.
This page uses these terms:
- Your organization: the account of your company in the Wafeq ASP portal. Your company builds the app that uses the Wafeq ASP API. Your API keys and your OAuth client belong to your organization.
- Your app: the software that your company builds.
- Mode: Live or Sandbox. Live is real e-invoicing. Sandbox is for tests. Each mode has its own credentials and data.
- API key: the secret that your server sends with each API call. It identifies your organization.
- OAuth client: the client ID and the client secret of your app. Your app uses them to connect businesses and to get tokens.
- Business: a company that uses your app.
- Grant: the permission that a business gives to your organization. A grant lets your app submit e-invoices in which that business is the seller. The API uses the grant ID (
tgr_…) to identify it. - Taxpayer: a business from which your organization has an active grant. The API uses the Taxpayer ID (
txpay_…) to identify it. - Scope: one permission in a grant, for example
invoices:write. The business approves the scopes when it approves your app. - Access token: a token (
wat_…) that your app can send instead of the API key. One access token applies to one grant. - Refresh token: a token (
wrt_…) that your app exchanges for a new access token.
Your credentials
Your organization has two credentials in each mode. You get both in the Wafeq ASP portal. Refer to Set up your organization.
| Credential | Where in the portal | Use |
|---|---|---|
| API key | Developer → API keys | Authenticates the API calls of your server. |
| OAuth client | Developer → Settings | Connects businesses and gets tokens. |
Live and Sandbox have different credentials:
- A Live API key starts with
pk_live_. - A Sandbox API key starts with
pk_test_.
Live and Sandbox use the same base URL, https://api.wafeq.com/ae/v1. The API key selects the mode.
Your organization can have more than one API key. For example, use a different key for each server. Then you can revoke one key, and the other keys continue to work.
The rule: an active grant with the correct scope
An API key alone gives no access to a business. Your app can call the API for a taxpayer only through an active grant of your organization. The call must also be in the scopes of that grant. Your organization gets a grant when a business approves your app. Refer to Connect a taxpayer.
Your app asks for scopes when it starts the connection. A grant has one or more of these scopes:
invoices:write: submit and check the documents of the taxpayer, and change them. For example, void an invoice or replace the metadata of a document. This scope also lets your app manage the entry of the taxpayer in the Peppol Directory, the public list of businesses on Peppol.invoices:read: list and read all the documents of the taxpayer. This includes the documents that other apps submitted. Your organization receives the document webhook events of the taxpayer only with this scope.inbound:read: read the documents that other businesses send to the taxpayer. For these documents, your app also needsinvoices:read. In Live, Wafeq ASP charges your organization for each document that the taxpayer receives while your grant has this scope.taxpayer:read: read the details of the taxpayer.
Before you start
- Your organization has an API key in the mode of the taxpayer. Refer to Set up your organization (stage 1).
- The business is connected. Your app stored its Taxpayer ID and its grant ID. Refer to Connect a taxpayer (stage 2).
Call the API for a taxpayer: the three steps
Most calls are for one taxpayer. For example, your app submits, checks, lists and reads the documents of a taxpayer. The recommended method uses your API key and two headers. The headers identify the taxpayer and the grant. With this method, your app does not store or refresh tokens.
| Step | Action |
|---|---|
| 1 | Select the API key of the mode of the taxpayer. |
| 2 | Find the Taxpayer ID and the grant ID. |
| 3 | Send the three headers with each call. |
Step 1: Select the API key of the mode of the taxpayer
A taxpayer exists in one mode only. Use the API key of that mode:
- For a Live taxpayer, use a
pk_live_key. - For a Sandbox taxpayer, use a
pk_test_key.
If the Taxpayer ID is not in the mode of the key, Wafeq ASP answers 404.
Step 2: Find the Taxpayer ID and the grant ID
Use the taxpayer_id and the grant_id that your app stored at the end of the connection.
If your app does not have them, send GET /grants with your API key. Each grant in the response has a grant_id and a taxpayer_id. Use external_id or label to find the grant of each account in your app.
Use the Taxpayer ID. Do not use the TIN of the business, its 10-digit tax number.
Step 3: Send the three headers with each call
Authorization: Api-Key pk_live_…
x-ae-taxpayer-id: txpay_…
x-ae-grant-id: tgr_…Authorizationcontains the API key of your organization.x-ae-taxpayer-ididentifies the taxpayer. Send it with each call for a taxpayer, also when your organization has only one taxpayer. Without it, Wafeq ASP refuses the call.x-ae-grant-idlimits the call to this grant and its scopes. If the grant is revoked, Wafeq ASP refuses the call immediately (403 grant_not_active).
Example:
curl https://api.wafeq.com/ae/v1/invoices \
-H "Authorization: Api-Key $API_KEY" \
-H "x-ae-taxpayer-id: $TAXPAYER_ID" \
-H "x-ae-grant-id: $GRANT_ID"Without x-ae-grant-id, the call uses all the active grants of your organization from this taxpayer, with all their scopes. If the business revokes one grant, and another grant stays active, the call continues to work. For this reason, send x-ae-grant-id each time that your app knows the grant.
Example: one taxpayer, two grants. A business connects two workspaces in your app. Your organization then has two grants from the same taxpayer:
- Grant A has the scope
invoices:read. - Grant B has the scopes
invoices:readandinvoices:write.
A call with the ID of grant A in x-ae-grant-id can read documents. It cannot submit documents. A call without x-ae-grant-id uses both grants. Thus it can read and submit documents. If the business revokes grant B, the calls that submit documents stop.
Other methods and rules
These sections are not steps. They describe access tokens, the calls for your whole organization, the refusals and the safety of your secrets.
Access tokens instead of the API key
At the end of the connection, the token exchange also gives an access token and a refresh token. Your app can send the access token instead of the API key:
Authorization: Bearer wat_live_…- One grant. An access token applies to one grant, with the scopes of that grant.
x-ae-taxpayer-idandx-ae-grant-idare optional. If you send them, they must identify the taxpayer and the grant of the token. Otherwise, Wafeq ASP refuses the call (403). - Lifetimes. An access token is valid for 1 hour. A refresh token is valid for 90 days.
- Refresh. To get a new access token, send
grant_type=refresh_tokenand the refresh token to the token endpoint. Authenticate with your client ID and client secret. The response contains a new access token and a new refresh token. The old refresh token stops working. - An old refresh token. If your app sends an old refresh token again, Wafeq ASP revokes all the tokens of the grant. The grant stays active. To get new tokens, start the connection again.
- Revocation.
POST /oauth/revokewith an access token revokes only that token. With a refresh token, it revokes the grant and all its tokens. After that, your app cannot use this grant.
For the token endpoint of each mode, refer to Connect a taxpayer.
Tokens give your app more work. Your app must store and refresh the tokens of each grant. If your server keeps an API key, the headers of step 3 are simpler.
Calls for your whole organization
Some calls are not for one taxpayer:
GET /taxpayers: the taxpayers from which your organization has an active grant, with these grants.GET /grants: the active grants of your organization. Addinclude_revoked=trueto also get the revoked grants.PATCH /grants/{grant_id}: change the label or the metadata of a grant.DELETE /grants/{grant_id}: revoke a grant. Its tokens stop working immediately.
These calls need only the Authorization header with your API key.
If your app uses OAuth only, get an organization token. Send grant_type=client_credentials to the token endpoint, with your client ID and client secret. This token is valid for 1 hour, and it has no refresh token. Use it only for the calls in this list. For a call for a taxpayer, Wafeq ASP refuses it (403 taxpayer_token_required).
When Wafeq ASP refuses a call
401: Wafeq ASP cannot identify your organization.
- The
Authorizationheader is missing. - Wafeq ASP does not know the API key, or your organization revoked it.
- The access token is expired or revoked.
403: your organization has no access for this call. For some causes, the response gives a code in detail.code:
detail.code | Cause |
|---|---|
grant_not_active | The grant in x-ae-grant-id is not an active grant of your organization from this taxpayer. |
insufficient_scope | No grant of the call has the scope that the call needs. detail.scope gives the scope. |
taxpayer_token_required | The call is for a taxpayer, but the token is an organization token. |
Other causes of 403 have no code:
- Your organization has no active grant from the taxpayer.
- The taxpayer is not active, for example because it deregistered. Your app cannot submit or change its documents. Your app can still read them.
x-ae-taxpayer-idorx-ae-grant-iddoes not agree with the access token.
404: Wafeq ASP does not know the taxpayer. For example, the Taxpayer ID is from the other mode.
Keep your secrets safe
- Keep the API keys, the client secret, the tokens and the webhook signing secret on your server.
- Do not put them in browser code, mobile apps, URLs or logs.
- The portal shows an API key and a client secret one time only. Store each one when you create it.
- If a secret leaks, revoke the API key in Developer → API keys. For the client secret, make a new secret in Developer → Settings. The old value stops working immediately.
Authentication in Sandbox
- Use your Sandbox API key (
pk_test_…) with the headers of step 3. Use the Taxpayer IDs and the grant IDs of Sandbox. - Use the same base URL as in Live. Do not add
/sandboxto API paths. - Use your Sandbox OAuth client to connect test taxpayers. Refer to Sandbox.
Updated about 14 hours ago