API documentation
A versioned REST API. The major version is in the path and is never content-negotiated;
Accept carries the media type and nothing else.
Authentication
A bearer API key created in your dashboard. The secret is shown once at creation and stored as a SHA-256 — we cannot recover it for you, and neither can anyone who reads our database.
Authorization: Bearer vp_live_…
Correlation
Every response — including a 200 — carries a request_id of the form
req_<ULID>. Quote it in a support ticket and it is one indexed lookup
instead of a day of logs.
X-Request-Id: req_01hzxw…
Idempotency
Send an Idempotency-Key on any credit-mutating call. A retry with the same key
returns the first result rather than charging twice.
Idempotency-Key: <your uuid>
Endpoints · v1
Generated from the route table of this deployment, so it describes what is actually running here.
Account
| Method | Path |
|---|---|
| GET | /api/v1/account/credits |
| GET | /api/v1/account/usage |
Billing
| Method | Path |
|---|---|
| POST | /api/v1/billing/checkout |
| GET | /api/v1/billing/invoices |
| GET | /api/v1/billing/orders/{id} |
| GET | /api/v1/billing/plans |
| GET | /api/v1/billing/wallet |
Bulk
| Method | Path |
|---|---|
| POST | /api/v1/bulk |
| POST | /api/v1/bulk/preview |
| GET | /api/v1/bulk/{id} |
| POST | /api/v1/bulk/{id}/cancel |
| GET | /api/v1/bulk/{id}/results |
Keys
| Method | Path |
|---|---|
| GET | /api/v1/keys |
| POST | /api/v1/keys |
| DELETE | /api/v1/keys/{id} |
Status
| Method | Path |
|---|---|
| GET | /api/v1/status |
Verify
| Method | Path |
|---|---|
| POST | /api/v1/verify |
| POST | /api/v1/verify/batch |
Webhook Deliveries
| Method | Path |
|---|---|
| POST | /api/v1/webhook-deliveries/{id}/replay |
Webhooks
| Method | Path |
|---|---|
| GET | /api/v1/webhooks |
| POST | /api/v1/webhooks |
| DELETE | /api/v1/webhooks/{id} |
| GET | /api/v1/webhooks/{id} |
| PUT, PATCH | /api/v1/webhooks/{id} |
| GET | /api/v1/webhooks/{id}/deliveries |
| POST | /api/v1/webhooks/{id}/replay |
| POST | /api/v1/webhooks/{id}/rotate |
| POST | /api/v1/webhooks/{id}/test |
Rate limits by plan
Baseline figures. Your live limits are the ones on your subscription and are returned on every response in the rate-limit headers.
| Plan | Requests / minute | Daily cap | Concurrent jobs |
|---|---|---|---|
| Starter | 60 | 25,000 | 2 |
| Growth | 300 | 100,000 | 5 |
| Reseller | 600 | 150,000 | 8 |
| Enterprise | 1,200 | 200,000 | 10 |
| Sandbox | 30 | 1,000 | 1 |
Before your first bulk call
Two refusals surprise integrators, so they are documented here rather than discovered.
-
403 attestation_required— your organisation must have a current lawful-basis attestation on file before addresses can be submitted. The response carries the acceptance URL. Reading results and downloading exports are never blocked. -
403 agreement_required— an outstanding re-acceptance of the Terms, DPA or Acceptable Use Policy blocks bulk submit, API bulk and connector sync, and nothing else. You can always retrieve your data and leave.