Documentation / Getting started
Test keys
A test key (ak_test_…) exercises the whole API — and MCP — against a scripted, offline stand-in for VIES instead of the real service. Create one from the dashboard (API keys → Créer une clé de test) or with akwito admin create-key --account ID --label L --test.
A test key:
- consumes no quota and never calls VIES;
- produces no proof: no RFC 3161 timestamp, no daily anchoring, no public page (
GET /v/{hash}answers404for a test check); - writes a PDF marked "TEST CHECK — no evidentiary value", without a QR code;
- carries
"test": trueon every check it produces, and on everycheck.completed/check.failedwebhook event.
Four VAT numbers drive four scripted scenarios (country DE, any format the API would otherwise accept):
| Number | Behaviour | valid / confidence | Company | checks[0].ref |
|---|---|---|---|---|
DE000000001 | Answers immediately | true / confirmed | Sandbox GmbH, Teststraße 1, 10115 Berlin | SANDBOX-DE000000001 |
DE000000002 | Answers immediately | false / invalid | none | SANDBOX-DE000000002 |
DE000000003 | First call: upstream unavailable (MS_UNAVAILABLE) | — | — | — |
DE000000004 | First call: upstream saturated (MS_MAX_CONCURRENT_REQ) | — | — | — |
curl -s -X POST https://api.akwito.eu/v1/checks -H "Authorization: Bearer ak_test_…" \
-d '{"vat_number":"DE000000001"}'
# 201 { "valid": true, "confidence": "confirmed", "test": true,
# "company": {"name": {"value": "Sandbox GmbH", ...}, ...}, ... }
curl -s -X POST https://api.akwito.eu/v1/checks -H "Authorization: Bearer ak_test_…" \
-d '{"vat_number":"DE000000002"}'
# 201 { "valid": false, "confidence": "invalid", "test": true, "company": null, ... }
curl -s -X POST https://api.akwito.eu/v1/checks -H "Authorization: Bearer ak_test_…" \
-d '{"vat_number":"DE000000003"}'
# 202 { "request_id": "req_…", "status": "pending", ... }
curl -s -X POST https://api.akwito.eu/v1/checks -H "Authorization: Bearer ak_test_…" \
-d '{"vat_number":"DE000000004"}'
# 202 { "request_id": "req_…", "status": "pending", ... }
For DE000000003 and DE000000004, the first call is accepted with 202 exactly like a real upstream outage (see Pending validation): the worker completes it about a minute later and delivers check.completed with "test": true; within 10 minutes the same number answers like DE000000001 for your account, letting you exercise both the pending path and the eventual success in one sitting. That memory of the scripted attempt count lives in the process, not the database: if the server restarts between the 202 and the retry, DE000000003/DE000000004 fail again as a fresh first call, and after the usual retry policy the request can end up check.failed instead of succeeding — in practice a server stays up far longer than the minute this takes, so it is rarely visible.
Any other well-formed number answers like DE000000002; a malformed one is recorded as FORMAT_INVALID, as in production. Check digits are not applied under a test key — the scenario numbers would fail them — so a test key never sees CHECKSUM_INVALID; use GET /v1/format/{number} to test that.
A test key gets 403 TEST_KEY_NOT_ALLOWED on batches, watches, the audit file export, and both /anchor//anchor.tsr and /timestamp//timestamp.tsr — routes the sandbox does not serve, reads included. Webhook setup, test sends and the delivery log, and GET /v1/usage, are account-level surfaces shared between live and test — everything else described in this section is partitioned between the two worlds.
Live and test data are fully partitioned: a test key only ever lists and reads its account's test checks and requests, a live key never sees them, GET /v1/checks/{id} and GET /v1/requests/{id} answer 404 for an id from the other world (never 403 — the other world simply does not exist for this key). The dashboard shows both, each test row carrying a test badge.
Test checks are not evidence: they are purged after 30 days, regardless of the account's retention plan, whenever RETENTION_PURGE is on.
Going live: switch the key, nothing else changes — same endpoints, same request and response shapes.