# Verification

`GET /partner/v1/sandbox/verification` is the definition of done for the integration. It reports 16 checks — 12 required, 4 optional — each flipped to `pass` by a specific API interaction performed with your key. `readyForProduction` is `true` when ALL 12 required checks pass. Checks are **sticky**: once passed they stay passed until `POST /partner/v1/sandbox/reset` (which sets all 16 back to `pending`).

Do not report the integration complete until this endpoint returns `"readyForProduction": true`. Run the flows through your integration code, not hand-typed curls — the checks cannot tell the difference, but only the former proves your integration.

## The endpoint

```bash
curl -s https://sandbox.bilnex.io/partner/v1/sandbox/verification \
  -H "Authorization: Bearer <YOUR_API_KEY>"
```

Response (early in an integration — two checks passed):

```json
{
  "checks": [
    { "id": "AUTH_OK", "required": true, "status": "pass", "detail": "GET /partner/v1/me succeeded", "fixHint": null, "docsUrl": "https://sandbox.bilnex.io/docs/authentication.md" },
    { "id": "CAPABILITY_CHECKED_CAPABLE", "required": true, "status": "pass", "detail": "Capability checked for 95000003 (capable)", "fixHint": null, "docsUrl": "https://sandbox.bilnex.io/docs/sending-invoices.md" },
    { "id": "CAPABILITY_CHECKED_NOT_CAPABLE", "required": true, "status": "pending", "detail": "No capability check has returned eInvoiceCapable=false yet", "fixHint": "GET /partner/v1/customers/95999902/e-invoice-capability (Sandbox Paper OÜ is not capable)", "docsUrl": "https://sandbox.bilnex.io/docs/sending-invoices.md" },
    { "id": "INVOICE_CREATED", "required": true, "status": "pending", "detail": "No invoice created yet", "fixHint": "POST /partner/v1/invoices with a customer, dates, currency, language and at least one item", "docsUrl": "https://sandbox.bilnex.io/docs/sending-invoices.md" },
    { "id": "PDF_FETCHED", "required": true, "status": "pending", "detail": "No invoice PDF fetched yet", "fixHint": "GET /partner/v1/invoices/{id}/pdf for any created invoice", "docsUrl": "https://sandbox.bilnex.io/docs/sending-invoices.md" },
    { "id": "EINVOICE_SENT", "required": true, "status": "pending", "detail": "No E_INVOICE send yet", "fixHint": "POST /partner/v1/invoices/{id}/send with channel E_INVOICE to a capable customer (95000003 or 95999901)", "docsUrl": "https://sandbox.bilnex.io/docs/sending-invoices.md" },
    { "id": "EINVOICE_RECEIVED_AT_RECEIVER", "required": true, "status": "pending", "detail": "No e-invoice has arrived at Sinilille Kaubandus OÜ", "fixHint": "Send an E_INVOICE to regCode 95000003, then list purchase invoices with X-Company-Id set to the receiver", "docsUrl": "https://sandbox.bilnex.io/docs/receiving-invoices.md" },
    { "id": "PURCHASE_LISTED", "required": true, "status": "pending", "detail": "Purchase invoices never listed", "fixHint": "GET /partner/v1/purchase-invoices?since=... as the receiver company", "docsUrl": "https://sandbox.bilnex.io/docs/receiving-invoices.md" },
    { "id": "MARKED_EXPORTED", "required": true, "status": "pending", "detail": "No purchase invoice marked exported", "fixHint": "POST /partner/v1/purchase-invoices/{id}/mark-exported after importing", "docsUrl": "https://sandbox.bilnex.io/docs/receiving-invoices.md" },
    { "id": "EMAIL_SENT", "required": true, "status": "pending", "detail": "No EMAIL send yet", "fixHint": "POST /partner/v1/invoices/{id}/send with channel EMAIL", "docsUrl": "https://sandbox.bilnex.io/docs/email-invoices.md" },
    { "id": "EMAIL_FETCHED_FROM_INTERCEPT", "required": true, "status": "pending", "detail": "Intercepted email never fetched", "fixHint": "GET /partner/v1/sandbox/emails after an EMAIL send", "docsUrl": "https://sandbox.bilnex.io/docs/email-invoices.md" },
    { "id": "NOT_CAPABLE_FALLBACK", "required": true, "status": "pending", "detail": "No EMAIL send to a regCode previously checked not-capable", "fixHint": "Check 95999902 capability (false), then send an invoice for 95999902 via EMAIL", "docsUrl": "https://sandbox.bilnex.io/docs/sending-invoices.md" },
    { "id": "PEPPOL_SENT (not available in v1 — sending over Peppol returns 501)", "required": false, "status": "pending", "detail": "No PEPPOL send yet", "fixHint": "POST /partner/v1/invoices/{id}/send with channel PEPPOL to a peppolCapable customer", "docsUrl": "https://sandbox.bilnex.io/docs/peppol.md" },
    { "id": "PEPPOL_RECEIVED", "required": false, "status": "pending", "detail": "No PEPPOL purchase invoice listed yet", "fixHint": "Send via PEPPOL to the receiver company (or trigger inbound_peppol), then list its purchase invoices", "docsUrl": "https://sandbox.bilnex.io/docs/peppol.md" },
    { "id": "INVOICE_SEEN_HANDLED", "required": false, "status": "pending", "detail": "No SEEN invoice observed", "fixHint": "Trigger invoice_seen on an EMAIL-sent invoice, then GET that invoice and observe status SEEN", "docsUrl": "https://sandbox.bilnex.io/docs/email-invoices.md" }
  ],
  "readyForProduction": false,
  "nextSteps": [
    "10 required checks remain: CAPABILITY_CHECKED_NOT_CAPABLE, INVOICE_CREATED, PDF_FETCHED, EINVOICE_SENT, EINVOICE_RECEIVED_AT_RECEIVER, PURCHASE_LISTED, MARKED_EXPORTED, EMAIL_SENT, EMAIL_FETCHED_FROM_INTERCEPT, NOT_CAPABLE_FALLBACK.",
    "Follow https://sandbox.bilnex.io/docs/quickstart.md steps 4-11 in order."
  ]
}
```

Per check: `status` is `pass`, `fail`, or `pending` (`pending` = never attempted; `fail` = attempted and observed wrong, e.g. an E_INVOICE send attempted to a not-capable customer without a subsequent fallback). `detail` says what was observed, `fixHint` says exactly what to do, `docsUrl` is where to read more.

## All 16 checks

### Required (all 12 must pass for `readyForProduction`)

| # | id | What flips it to `pass` | fixHint |
|---|---|---|---|
| 1 | `AUTH_OK` | A successful `GET /partner/v1/me` with your key | Call GET /partner/v1/me with Authorization: Bearer your key |
| 2 | `CAPABILITY_CHECKED_CAPABLE` | `GET /partner/v1/customers/{regCode}/e-invoice-capability` returning `eInvoiceCapable: true` (e.g. `95000003` or `95999901`) | Check capability for 95000003 or 95999901 |
| 3 | `CAPABILITY_CHECKED_NOT_CAPABLE` | The same endpoint returning `eInvoiceCapable: false` (e.g. `95999902`) | Check capability for 95999902 (Sandbox Paper OÜ) |
| 4 | `INVOICE_CREATED` | A successful `POST /partner/v1/invoices` (201) | Create an invoice with customer, dates, currency, language, ≥1 item |
| 5 | `PDF_FETCHED` | A successful `GET /partner/v1/invoices/{id}/pdf` | Fetch the PDF of any created invoice |
| 6 | `EINVOICE_SENT` | A successful `POST /partner/v1/invoices/{id}/send` with `channel: "E_INVOICE"` | Send an invoice via E_INVOICE to a capable customer |
| 7 | `EINVOICE_RECEIVED_AT_RECEIVER` | An `E_INVOICE` you sent to regCode `95000003` appearing as a purchase invoice at the receiver company | Send E_INVOICE to 95000003, then list purchase invoices with X-Company-Id = receiver |
| 8 | `PURCHASE_LISTED` | A successful `GET /partner/v1/purchase-invoices` with a `since` parameter | List purchase invoices using since= |
| 9 | `MARKED_EXPORTED` | A successful `POST /partner/v1/purchase-invoices/{id}/mark-exported` | Mark any purchase invoice exported after importing it |
| 10 | `EMAIL_SENT` | A successful `send` with `channel: "EMAIL"` | Send an invoice via EMAIL |
| 11 | `EMAIL_FETCHED_FROM_INTERCEPT` | A `GET /partner/v1/sandbox/emails` performed after at least one EMAIL send | Fetch /partner/v1/sandbox/emails after sending via EMAIL |
| 12 | `NOT_CAPABLE_FALLBACK` | An EMAIL send of an invoice whose `customer.regCode` was previously capability-checked with `eInvoiceCapable: false` (i.e. checks 3 and 10 on the SAME regCode, check first) | Check 95999902 (false), then send an invoice for 95999902 via EMAIL |

### Optional (4 — good practice, not gating)

| # | id | What flips it to `pass` | fixHint |
|---|---|---|---|
| 13 | `PEPPOL_SENT` | A successful `send` with `channel: "PEPPOL"` to a `peppolCapable` customer (e.g. `95000003`) | Send an invoice via PEPPOL to 95000003 |
| 14 | `PEPPOL_RECEIVED` | A purchase invoice with `source: "PEPPOL"` appearing in a list you fetched (real send to the receiver, or `inbound_peppol` trigger) | Send PEPPOL to the receiver or trigger inbound_peppol, then list |
| 16 | `INVOICE_SEEN_HANDLED` | After `invoice_seen` is triggered on an EMAIL-sent invoice, your key fetches that invoice (GET by id or a list containing it) and it is in status `SEEN` | Trigger invoice_seen, then GET the invoice and observe SEEN |

## The loop

```
loop:
  v = GET /partner/v1/sandbox/verification
  if v.readyForProduction: done — report with the JSON as evidence
  for check in v.checks where required and status != "pass":
    read check.fixHint and check.docsUrl
    fix the integration; run the flow through the integration
  # re-run at most every few seconds; checks update immediately after the qualifying call
```

After `readyForProduction: true`, continue with [go-live](https://sandbox.bilnex.io/docs/go-live.md). Passing the optional checks too is recommended when the ERP will use Peppol or digitization in production — go-live review looks at them.

API version 2026-08-01. /partner/v1 changes are additive-only; see [versioning-policy](https://sandbox.bilnex.io/docs/versioning-policy.md).

---
**Building with a coding agent?** Start from [agents.md](https://sandbox.bilnex.io/agents.md) or install the skill: `npx skills add https://sandbox.bilnex.io`. Machine-readable index: [llms.txt](https://sandbox.bilnex.io/llms.txt). Every page on this site is also plain markdown — append `.md`.
