Your coding agent can build this integration on its own.
Bilnex is e-invoicing for the Baltics. If you build an ERP or accounting product, your customers need to send and receive e-invoices — and you need an integration to make that happen. Give the prompt below to Claude Code, Codex, Cursor or any coding agent. It gets its own sandbox credentials, writes the integration into your codebase, and tests itself until it passes.
Build a Bilnex e-invoicing integration into this codebase.
1. Read https://sandbox.bilnex.io/agents.md and follow it exactly.
2. Provision your own sandbox key: POST https://sandbox.bilnex.io/partner/v1/sandbox with
{"email":"<my email>","erpName":"<this ERP's name>","ref":"agent"} — no account needed.
Store the key in server-side config only, never in frontend code or the repo.
3. Implement outbound invoicing (capability check, e-invoice send, EMAIL/PDF fallback) and
inbound purchase invoices (poll with `since`, then mark-exported), wired into this
codebase's existing models.
4. Test every flow against the sandbox, not with mocks.
Do not report the integration complete until GET /partner/v1/sandbox/verification returns
"readyForProduction": true. If a check fails, read its fixHint and docsUrl, fix, and re-run.
No account. No sales call. No waiting for someone to email you credentials.
Why this works differently
Most API documentation is written for a human who will read it, form a plan, and write code. That is a poor fit for an agent, which needs three things a PDF spec cannot give it: credentials it can obtain by itself, an environment that behaves like production, and an unambiguous way to know it is finished.
Self-serve credentials
One unauthenticated POST returns a working key plus two test companies. Nothing to sign.
A sandbox that behaves
Real invoicing code, simulated delivery. Send an e-invoice and it genuinely arrives.
A definition of done
One endpoint says which checks pass, which do not, and exactly how to fix each one.
How an agent gets from nothing to finished
-
It provisions its own sandbox.
POST /partner/v1/sandboxreturns an API key, a sender company and a receiver company — both real tenants inside Bilnex — plus fixture counterparties that behave in specific ways: one accepts e-invoices, one can only receive PDF by email, one rejects on send. The key lasts two days and can be extended once. - It reads documentation written for it. agents.md is the entry point: a complete quickstart with working curl for every call and its real response. llms.txt indexes everything and states the hard rules — always branch on capability, never treat a resend as a retry, never put the key in frontend code.
- It builds against the real thing. Invoices are created, rendered and sent by the same code production runs. Only the outbound rails are simulated: an e-invoice to another sandbox company is delivered through the genuine import pipeline, so it lands as an incoming document with a PDF, exactly as a live one would. Email is captured and readable back, never delivered to a real inbox.
-
It checks its own work — and this is the part that matters.
GET /partner/v1/sandbox/verificationreturns twelve required checks, observed server-side from what the integration actually did. Each failing check carries afixHintand adocsUrl. The agent loops untilreadyForProductionis true. It cannot mistakenly believe it is done.
Going live is a base URL and a key. Nothing else in the integration changes — not a field, not an endpoint, not a status value. Sandbox keys are refused by production and production keys by the sandbox, with an explicit error, because mixing them up is the most common mistake there is.
What the checklist covers
These are observed, not self-reported. We record what your integration did; you cannot tick a box by claiming it.
| Area | What has to happen |
|---|---|
| Authentication | A call succeeds with your key |
| Capability | You check a recipient that can receive e-invoices, and one that cannot |
| Sending | Create an invoice, fetch its PDF, send it as an e-invoice |
| Delivery | It arrives at the receiving company |
| Receiving | List incoming documents and mark one as imported into your ERP |
| Fallback | Email an invoice to a recipient that cannot receive e-invoices, and read it back |
That fallback check is deliberately required. Branching on capability is the single most common way a real Estonian integration breaks in production, so the sandbox will not let you skip it.
Prefer to read it yourself?
Everything the agent uses is plain text, and you are welcome to it.
| Resource | What it is |
|---|---|
| /agents.md | Entry point and full quickstart |
| /llms.txt | Index of everything, plus the hard rules |
| /docs/quickstart.md | The happy path, step by step |
| /docs/sending-invoices.md | Capability, channels, sending |
| /docs/receiving-invoices.md | Polling, cursors, mark-exported |
| /docs/errors.md | Every error code and what to do |
| /docs/verification.md | The checklist, explained |
| /docs/go-live.md | Moving to production |
| /partner/v1/openapi.json | OpenAPI specification |
| Agent Skill | Installable via npx skills add https://sandbox.bilnex.io |
Try it in one command
This works right now, from anywhere, with no credentials:
curl -X POST https://sandbox.bilnex.io/partner/v1/sandbox \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","erpName":"Your ERP","ref":"manual"}'
You get back a key and two companies, and you are ready to make your first call. Nothing you do in the sandbox reaches a real recipient.
When you are ready for production
Send us the passing verification response and we will issue a production key. Read go-live.md first — it covers the differences that are real (channel activation is verified against the business registry, e-invoices reach actual recipients) and the ones that are not (the API itself).