Get started
Pagination & limits
How list endpoints page through results, how often you can call the API, and how to make a retry safe.
Pagination
List endpoints take page (starting at 1) and limit. The items are in data.data and the position in data.pagination. Keep following nextPage until it is null.
{
"success": true,
"message": "Invoices retrieved",
"data": {
"data": [{ "id": "…" }, { "id": "…" }],
"pagination": {
"total": 15,
"page": 1,
"limit": 2,
"totalPages": 8,
"nextPage": "https://api.vezmo.com/api/v1/merchant/invoice?page=2&limit=2",
"prevPage": null
}
},
"requestId": "…",
"timestamp": "…"
}async function listAll(path, accessToken) {
const items = [];
let url = `https://api.vezmo.com/api/v1/${path}?page=1&limit=100`;
while (url) {
const res = await fetch(url, { headers: { Authorization: `Bearer ${accessToken}` } });
const body = await res.json();
if (!body.success) throw new Error(body.message);
items.push(...body.data.data);
url = body.data.pagination.nextPage; // null on the last page
}
return items;
}
const invoices = await listAll("merchant/invoice", accessToken);The payments list (GET /merchant/payment) also returns nextCursor and hasMore. For long exports, pass the previous page's nextCursor as cursor instead of a page number: it stays correct while new payments arrive. Its limit is at most 100 (default 15), and total stops counting at 10,000; totalIsCapped is true when there are more.
Rate limits
Busy endpoints are rate-limited, counted per IP address and per endpoint. Every window must have room for a call to go through.
| Endpoint | Limit |
|---|---|
Create token POST /merchant/api-auth/login | 5 a minute |
Create a secure payment POST /merchant/secure-payments | 10 a second, 30 per 10 seconds, 60 a minute |
| Refund or cancel a payment | 5 a second, 20 per 10 seconds, 40 a minute |
| Other payments endpoints | 3 a second, 20 per 10 seconds, 60 a minute |
Subscriptions /merchant/subscription/… | 3 a second, 20 per 10 seconds, 60 a minute |
| Agreements: create, upload, send, remind, void, delete | 2 a second, 10 per 10 seconds, 30 a minute |
| Agreements: templates, list, get, audit, document | 3 a second, 20 per 10 seconds, 60 a minute |
| Mark accepted and Mark rejected proposal | 2 a second, 10 per 10 seconds, 30 a minute |
Public payer routes, reading: GET /paylinks/:code, GET /client-invoice/… | 10 a second, 40 per 10 seconds, 120 a minute |
Public payer routes, paying: /paylinks/:code/checkout, …/confirm, …/client; POST /invoice/:id/checkout, …/confirm | 5 a second, 15 per 10 seconds, 30 a minute |
Over a limit, the API answers 429 Too Many Requests. Wait a few seconds and retry with backoff.
{
"success": false,
"message": "ThrottlerException: Too Many Requests",
"errors": [{ "code": "http.429", "message": "ThrottlerException: Too Many Requests" }],
"data": null,
"requestId": "…",
"timestamp": "…"
}An access token lasts 30 minutes. Keep it and reuse it for every call until it expires; don't create a token per request, or you will hit the 5-a-minute limit on Create token.
Email limits
Emails we send to your clients and signers from Vezmo's own address are limited per business. Each business can send 500 of each kind in 24 hours. If you need more, contact support: we can raise the limit for your business. Over a limit the API answers 429, and the message says your limit.
Emails test mode skips (a test key's invoice or proposal to an address outside your team) don't count. A send that test mode skips entirely doesn't start the once-a-minute wait either.
| What | Limit |
|---|---|
| Send invoice and Send proposal | One email per invoice or proposal a minute. |
| Invoice and proposal emails | 500 in 24 hours per business, CC copies included, unless support has set a different number for your business. The email that Create or Update invoice sends on its own counts too, but never fails the save. So does the invoice that Mark accepted emails. |
| Agreement invitations and reminders | 500 per business in 24 hours, unless support has set a different number for your business. Dashboard sends count too. |
| Agreement reminders | Once a minute per agreement. |
Agreement limits
- Upload: a PDF of at most 10 MB and 100 pages, not password-protected or encrypted.
- Recipients: 1 to 20 per agreement.
- Fields: at most 200 per agreement.
- Signer email codes: 5 an hour per signer.
Idempotency
POST /merchant/secure-payments accepts an Idempotency-Key header (1–255 ASCII characters, for example your order number). A retry with the same key and body returns the same payment instead of a second one.
curl -X POST https://api.vezmo.com/api/v1/merchant/secure-payments \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1234" \
-d '{ "title": "Order #1234", "amount": 49.90, "currency": "USD" }'- Same key, same body: the same payment, with a fresh client token.
- Same key, different body:
422. Use a new key for a new order. - Same key after the payment was paid:
409. The order is paid; reconcile it instead of retrying.
Refunds (POST /merchant/payment/:id/refund) take an Idempotency-Key too: a retry with the same key and body returns the refund already made, so a timeout can't refund twice. The key is per payment.
Create a subscription (POST /merchant/subscription) takes an Idempotency-Key too: the same key with the same body returns the first call's response and never charges again; with a different body it returns 422. Keys are per business and per mode.
Other POST endpoints don't take a key. If one times out, read the object before you retry.