API key
How the bearer key works: one set of keys for each client, with scopes.
- In the sandbox
In plain words
The API key is how a calling system proves it may use the service. Each client has its own keys, and each key has scopes that say what it may do. We issue the first sandbox key on request.
Send the key as a bearer token on every call.
Authorization: Bearer <your-api-key>What the service does with it
The service hashes the key you send with SHA-256 and compares the hash with the one it holds. It stores no key value. Each use writes an audit row, and that row holds no value either. A sandbox key starts with eik_test_, and a production key with eik_live_.
A valid key
A call that needs a key, with a valid one. The care list is empty because nothing has been rejected.
curl "https://api-sandbox-eu.eurinvoice.com/care" \
-H "Authorization: Bearer <your-api-key>"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/care"))
.header("Authorization", "Bearer <your-api-key>")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/care', {
headers: {
Authorization: 'Bearer <your-api-key>',
},
});
console.log(response.status);
console.log(await response.text());{
"data": []
}A missing or wrong key
The answer is 401, before anything else is read.
curl "https://api-sandbox-eu.eurinvoice.com/invoices/inv_unknown"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/inv_unknown"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/inv_unknown', {
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/unauthorized",
"title": "Missing or unknown API key",
"status": 401
}Keys and scopes
A key belongs to one client and sees only that client's data. Another client's invoice answers 404.
| Scope | What the key may do |
|---|---|
submit | Send invoices (POST /invoices, POST /invoices/xml), run a dry run (POST /validate) and cancel an invoice. |
read | Read invoices, events and documents, the care list and the catalogue. |
admin | Manage the client's webhook, rail credentials and API keys. |
A call without the scope it needs answers 403. Each scope has its own rate limit.
Making and revoking keys
A key is shown once, in the answer that makes it. We keep only its SHA-256, so a lost key cannot be shown again: revoke it and make a new one.
- A key with the
adminscope makes keys for its own client, with any of the scopes it holds itself, and revokes them. Revoking a key also revokes every key it made. - One client may hold up to 20 live keys. Each call is counted for the client, not for the key, so more keys do not buy more requests.
- A revoked key stops working at once.
The first key for a client comes from us. Later keys are made through POST /keys.
Warning
Keep real keys out of examples, tickets and email.