New France e-invoicing mandate goes live September 2026 — our implementation is ready. See all mandates →
Sandbox & Testing

Integration tests

Run a recommended suite of tests against your integration in the sandbox, with the expected outcome of each, and track which ones pass. You can start a run from the dashboard or from your build pipeline, and add tests of your own. There is no separate test environment: a run uses your sandbox key and your sandbox data.

ℹ
These results show how your integration handled simulated scenarios in the Clearvo sandbox on <date>. Nothing was sent to any tax authority, network or supplier. This is not a certification, accreditation or approval by any authority, by OpenPeppol or by any e-invoicing platform, and it does not assess the tax treatment of your documents. Every response carries this statement in its disclaimer field, with the date filled in.

All of these endpoints need a sandbox key (csk_test_*); a live key gets 403 SANDBOX_ONLY. With an organisation key, send x-entity-id to name the entity.

Sandbox & Testing

Run the tests from your build pipeline

Two calls: start a run, then read it until it is no longer queued or running. Fail the build when status is failed.

Shell — start a run and wait for it
# 1. Start the run (returns at once)
RUN=$(curl -s -X POST https://api.clearvo.io/v1/test-runs \
  -H "x-api-key: $CLEARVO_SANDBOX_KEY" -H "Content-Type: application/json" \
  -H "x-idempotency-key: $CI_BUILD_ID" \
  -d '{"name":"CI build '$CI_BUILD_ID'"}' | jq -r .runId)

# 2. Read it until it is no longer queued or running
while true; do
  STATUS=$(curl -s https://api.clearvo.io/v1/test-runs/$RUN \
    -H "x-api-key: $CLEARVO_SANDBOX_KEY" | jq -r .status)
  [ "$STATUS" != "queued" ] && [ "$STATUS" != "running" ] && break
  sleep 5
done
[ "$STATUS" = "failed" ] && exit 1

The command line tool does the same: clearvo tests run --wait starts a run, polls it, prints the summary and exits with code 1 when the run failed. clearvo tests status <runId> reads a run later. In an AI assistant (MCP) the tools are start_test_run and get_test_run; the SDK methods are startTestRun and getTestRun.

  • Only one run can be in progress at a time (409 RUN_IN_PROGRESS).
  • Retry the start call with the same x-idempotency-key and you get the same run back (200, idempotent: true).
  • By default a run covers the tests the platform can check on its own (tag automatic). A test that needs a step by hand is reported as not run; use tags or caseIds to choose.
  • status is waiting while a test is waiting for your integration to act; the run has a deadline (deadlineMinutes, default 10, up to 1440).
Sandbox & Testing

Reading a run

GET /v1/test-runs/{id} returns the run, its counts and each test's outcome. GET /v1/test-runs lists your last 50 runs, newest first.

FieldMeaning
statusqueued, running, waiting, passed, failed or cancelled. passed only when every required test passed with the platform's own check; a test marked done by hand never counts.
summarypassed, failed, waiting, notRun, notApplicable, autoVerified, selfAttested, required, requiredPassed.
cases[]One entry per test: caseId, caseVersion, title, group, required, scope (standard, added_for_you or your_organisation), outcome, verification (auto or self_attested), reasonCode, reason, firedAt, resolvedAt, windowEndsAt, evidence.
evidenceIds and metadata only (webhook, delivery and invoice ids, HTTP status, timings). Never a request or response body.
notApplicable[]Tests that do not apply to your setup, each with the reason.
disclaimerThe statement above, with the date.

The tests themselves, with their steps and expected outcome, are listed by GET /v1/test-cases (MCP list_test_cases, CLI clearvo tests cases list).

Sandbox & Testing

Add tests of your own

Add the cases that matter to your integration. A test has a title, steps and the expected outcome. With a check the platform verifies it in every run; without one you mark it done by hand in the dashboard. Ask GET /v1/test-cases/catalogue for the checks you can pick, their settings, who a test can apply to (appliesWhen) and your limits.

JSON — POST /v1/test-cases
{
  "title": "A rejected invoice reaches my webhook",
  "steps": ["Send an invoice that is rejected", "Check your endpoint receives invoice.rejected"],
  "expected": "invoice.rejected is delivered within an hour.",
  "check": { "kind": "webhook_event_delivered", "params": { "event": "invoice.rejected", "withinSeconds": 3600 } },
  "appliesWhen": { "direction": "sale", "countries": ["FR"] }
}
  • PATCH /v1/test-cases/{id} changes one of your tests and creates a new version; past runs keep the version they ran against.
  • DELETE /v1/test-cases/{id} removes it from new runs; past runs keep showing it.
  • Standard tests cannot be changed or removed (403 CASE_NOT_EDITABLE). There is a limit on how many tests you can add (409 CASE_LIMIT_REACHED); the catalogue shows it.

Command line: clearvo tests cases create|archive. MCP: create_test_case, archive_test_case, get_test_case_catalogue. SDK: createTestCase, updateTestCase, archiveTestCase, getTestCaseCatalogue.

Sandbox & Testing

Simulators your tests can use

  • POST /v1/webhooks/test sends one signed test event to a webhook you registered and reports what your endpoint answered. Nothing is stored and it is not retried. CLI: clearvo webhooks test; MCP: test_webhook; SDK: testWebhook.
  • POST /v1/receive/simulate creates sample received invoices or credit notes (Germany or France) from a fictional supplier, so you can test the purchase side. They are received through the same pipeline as real ones and fire invoice.received. CLI: clearvo receive simulate; MCP: simulate_received_invoices; SDK: simulateReceivedInvoices.