API reference
The Vitix Pay API is a predictable REST API: resource-oriented URLs, JSON request and response bodies, standard HTTP status codes and bearer authentication. Base URL: https://api.vitix.net.
Authentication
Authenticate every request with your secret key in the Authorization header. Keys starting with vx_test_ act on test data; vx_live_ keys on live data. Never expose a key in client-side code, mobile apps or public repositories. Requests without a valid key return 401; requests from a suspended account return 403.
curl https://api.vitix.net/v1/account \ -H "Authorization: Bearer vx_test_••••••••"Versioning & request ids
Every response carries vitix-version (currently 2026-10-01) and a unique request-id (req_…). Include the request id when you contact support; it is also in the body of every error. Backwards-incompatible changes ship under a new version date; additive changes (new fields, new event types, new enum values) can appear at any time, so parse defensively.
Idempotency
Add an Idempotency-Key header (any string up to 255 characters, typically a UUID or your own order id) to POST requests. The first response for a key is stored for 24 hours and returned verbatim for identical retries, with the header idempotent-replayed: true. Reusing a key with a different path or payload fails with idempotency_error. Keys are scoped to your account and mode.
curl https://api.vitix.net/v1/checkouts \ -H "Authorization: Bearer vx_live_••••••••" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 9c1f7f8e-6b0c-4c87-9b4a-2b1d0a3e5f10" \ -d '{ "amount": 2000, "success_url": "https://app.example.com/ok" }'Pagination
List endpoints return a list object with newest items first. Pass limit (1–100, default 20) and starting_after (the id of the last item you received) to fetch the next page while has_more is true.
{ "object": "list", "data": [ { "id": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "object": "payment", "livemode": true, "status": "succeeded", "checkout": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "fee_usd": 132, "net_usd": 2176, "refunded_usd": 0, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "invoice_available": true, "created_at": "2026-10-14T06:35:02.410Z" } ], "has_more": false}Amounts & currencies
Amounts are integers in the smallest unit: 2000 is $20.00 when currency is usd; 600000 is 600.000 ₫ when it is vnd. Customers are always charged in USD; VND requests are converted at 26,000 ₫ per USD and the charged figure is returned as amount_usd, alongside fee_usd and net_usd on payments. Live checkouts must be at least $10.00; the maximum per checkout is set on your account (GET /v1/account).
| Currency | amount means | Example |
|---|---|---|
| usd | US cents | 2000 → $20.00 |
| vnd | Vietnamese đồng | 600000 → 600.000 ₫ ≈ $23.08 |
Rate limits
Each API key may make 100 requests per 10 seconds. Beyond that the API returns 429 with rate_limit_error; back off and retry with jitter. Webhooks are not subject to this limit.
Errors
Errors use conventional status codes and a single error object with a stable code you can branch on. The full list is on the Errors page.
{ "error": { "type": "invalid_request_error", "code": "amount_too_small", "message": "Amount is below the minimum of $10.00 (≈ 260,000 VND).", "param": "amount", "request_id": "req_dCjruuTgsXzq3EwlIAWS" }}Checkouts
A checkout is a one-time payment attempt: it fixes an amount and a customer, exposes a hosted page where the customer pays, and turns into a payment when the money arrives. Create one per top-up; never reuse a checkout across customers.
The checkout object
Attributes
- idstring
- Unique id, prefixed
cs_live_orcs_test_. - objectstring
- Always
checkout. - livemodeboolean
- Whether this is a live or test checkout.
- statusenum
openwhile payable,completeonce paid,expiredafterexpires_ator an explicit expire call.- payment_statusenum
unpaidorpaid.- amountinteger
- The amount you requested, in the minor unit of currency (cents for usd, đồng for vnd).
- currencyenum
usdorvnd.- amount_usdinteger
- What the customer is charged, in USD cents. Equal to amount for usd; converted at 26,000 ₫/USD for vnd.
- descriptionstring | null
- Shown on the hosted page.
- customerobject | null
- The customer you passed.
Child attributes
- idstring
- Your own identifier for the paying user (max 128 chars). Echoed on the payment and usable as a list filter.
- emailstring
- Pre-fills the email on the hosted checkout and goes on the invoice. Strongly recommended.
- namestring
- Display name (max 120 chars).
- referencestring | null
- Your own reference (order id, invoice number). Copied to the payment.
- metadataobject
- Up to 20 string key/value pairs you attached. Copied to the payment.
- success_urlstring
- Your own success page, stored for your records. Vitix does not redirect the customer there.
- cancel_urlstring | null
- Stored for your records; the hosted page shows no link to your site.
- urlstring
- The Vitix-hosted checkout page (vitix.net/pay?cs=…). Redirect the customer here or open it in a popup window.
- paymentstring | null
- Id of the payment once paid.
- expires_attimestamp
- ISO 8601. The page stops accepting payment after this.
- completed_attimestamp | null
- When the payment succeeded.
- created_attimestamp
- ISO 8601.
{ "id": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "object": "checkout", "livemode": true, "status": "open", "payment_status": "unpaid", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "success_url": "https://app.example.com/billing/success?cs={CHECKOUT_ID}", "cancel_url": "https://app.example.com/billing", "url": "https://vitix.net/pay?cs=cs_live_0aWdSNgZbvGU0BjvCISLh07o", "payment": null, "expires_at": "2026-10-14T07:32:45.000Z", "completed_at": null, "created_at": "2026-10-14T06:32:45.156Z"}Create a checkout
POST/v1/checkouts
Creates a checkout and the hosted page behind its url. Amount limits and the domain allow-list are validated before anything is created, so a 400 here has no side effects.
Parameters
- amountintegerrequired
- Positive integer in the minor unit of currency.
- currencyenum
usd(default) orvnd.- success_urlstringrequired
- Absolute https URL on one of your allowed domains (http://localhost is accepted in test mode). Stored on the checkout for your records; the customer is not redirected there.
- cancel_urlstring
- Absolute URL stored for your records; not shown on the hosted page.
- customerobject
- Who is paying.
Child attributes
- idstringrequired
- Your own identifier for the paying user (max 128 chars). Echoed on the payment and usable as a list filter.
- emailstring
- Pre-fills the email on the hosted checkout and goes on the invoice. Strongly recommended.
- namestring
- Display name (max 120 chars).
- descriptionstring
- Up to 200 characters, shown on the hosted page.
- referencestring
- Up to 128 characters. Your own id, copied to the payment and filterable on lists.
- metadataobject
- Up to 20 keys (40 chars) with string values (500 chars). Copied to the payment.
- expires_ininteger
- Seconds until the checkout expires, 300–86400. Default 3600.
Returns
The new checkout with status: "open". HTTP 201.
curl -X POST https://api.vitix.net/v1/checkouts \ -H "Authorization: Bearer vx_live_••••••••" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: topup_8f1c" \ -d '{ "amount": 600000, "currency": "vnd", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "description": "Acme credits", "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "success_url": "https://app.example.com/billing/success?cs={CHECKOUT_ID}", "cancel_url": "https://app.example.com/billing" }'{ "id": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "object": "checkout", "livemode": true, "status": "open", "payment_status": "unpaid", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "success_url": "https://app.example.com/billing/success?cs={CHECKOUT_ID}", "cancel_url": "https://app.example.com/billing", "url": "https://vitix.net/pay?cs=cs_live_0aWdSNgZbvGU0BjvCISLh07o", "payment": null, "expires_at": "2026-10-14T07:32:45.000Z", "completed_at": null, "created_at": "2026-10-14T06:32:45.156Z"}Retrieve a checkout
GET/v1/checkouts/:id
Typically called from your success page. Check payment_status; if it is still unpaid the webhook has not landed yet, so show a pending state rather than an error.
Returns
The checkout object, or 404 if the id does not exist in this account and mode.
curl https://api.vitix.net/v1/checkouts/cs_live_0aWdSNgZbvGU0BjvCISLh07o \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "object": "checkout", "livemode": true, "status": "complete", "payment_status": "paid", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "success_url": "https://app.example.com/billing/success?cs={CHECKOUT_ID}", "cancel_url": "https://app.example.com/billing", "url": "https://vitix.net/pay?cs=cs_live_0aWdSNgZbvGU0BjvCISLh07o", "payment": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "expires_at": "2026-10-14T07:32:45.000Z", "completed_at": "2026-10-14T06:35:02.410Z", "created_at": "2026-10-14T06:32:45.156Z"}List checkouts
GET/v1/checkouts
Query parameters
- statusenum
open,completeorexpired.- customerstring
- Only checkouts for this customer id.
- limitinteger
- 1–100, default 20.
- starting_afterstring
- Cursor: the last id of the previous page.
Returns
A list object of checkouts, newest first.
curl https://api.vitix.net/v1/checkouts?customer=user_42&limit=10 \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "list", "data": [ { "id": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "object": "checkout", "livemode": true, "status": "open", "payment_status": "unpaid", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "success_url": "https://app.example.com/billing/success?cs={CHECKOUT_ID}", "cancel_url": "https://app.example.com/billing", "url": "https://vitix.net/pay?cs=cs_live_0aWdSNgZbvGU0BjvCISLh07o", "payment": null, "expires_at": "2026-10-14T07:32:45.000Z", "completed_at": null, "created_at": "2026-10-14T06:32:45.156Z" } ], "has_more": false}Expire a checkout
POST/v1/checkouts/:id/expire
Closes an open checkout early, for example when the customer cancels the order in your product. Emits checkout.expired.
Returns
The checkout with status: "expired". Fails with checkout_not_open if it is already complete or expired.
curl -X POST https://api.vitix.net/v1/checkouts/cs_live_0aWdSNgZbvGU0BjvCISLh07o/expire \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "object": "checkout", "livemode": true, "status": "expired", "payment_status": "unpaid", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "success_url": "https://app.example.com/billing/success?cs={CHECKOUT_ID}", "cancel_url": "https://app.example.com/billing", "url": "https://vitix.net/pay?cs=cs_live_0aWdSNgZbvGU0BjvCISLh07o", "payment": null, "expires_at": "2026-10-14T07:32:45.000Z", "completed_at": null, "created_at": "2026-10-14T06:32:45.156Z"}Payments
A payment is money that actually arrived. Payments are created by Vitix when a checkout succeeds and announced by the payment.succeeded event. They are immutable except for their refund state.
The payment object
Attributes
- idstring
- Prefixed
py_live_orpy_test_. Use it as the idempotency key of your own ledger row. - objectstring
- Always
payment. - livemodeboolean
- Live or test.
- statusenum
succeeded,partially_refundedorrefunded.- checkoutstring | null
- The checkout that produced this payment.
- amountinteger
- Requested amount in the minor unit of currency.
- currencyenum
usdorvnd.- amount_usdinteger
- Gross amount charged, USD cents.
- fee_usdinteger
- Processing fee retained by the payment provider, USD cents. 0 in test mode.
- net_usdinteger
- amount_usd minus fee_usd.
- refunded_usdinteger
- Total refunded so far, USD cents.
- descriptionstring | null
- From the checkout.
- customerobject | null
- From the checkout. The email may be updated with the address the customer actually used on the hosted page.
- referencestring | null
- From the checkout.
- metadataobject
- From the checkout.
- invoice_availableboolean
- True for live payments; fetch the PDF with GET /v1/payments/:id/invoice.
- created_attimestamp
- ISO 8601.
{ "id": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "object": "payment", "livemode": true, "status": "succeeded", "checkout": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "fee_usd": 132, "net_usd": 2176, "refunded_usd": 0, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "invoice_available": true, "created_at": "2026-10-14T06:35:02.410Z"}curl https://api.vitix.net/v1/payments/py_live_4YMjlAzqiKxSYAIsAWEToqvL \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "object": "payment", "livemode": true, "status": "succeeded", "checkout": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "fee_usd": 132, "net_usd": 2176, "refunded_usd": 0, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "invoice_available": true, "created_at": "2026-10-14T06:35:02.410Z"}List payments
GET/v1/payments
Useful for reconciliation jobs: page through everything since your last run and compare against your ledger.
Query parameters
- customerstring
- Filter by customer id.
- referencestring
- Filter by your reference.
- checkoutstring
- Filter by checkout id.
- statusenum
succeeded,partially_refundedorrefunded.- limitinteger
- 1–100, default 20.
- starting_afterstring
- Cursor.
Returns
A list object of payments, newest first.
curl https://api.vitix.net/v1/payments?reference=topup_8f1c \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "list", "data": [ { "id": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "object": "payment", "livemode": true, "status": "succeeded", "checkout": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "fee_usd": 132, "net_usd": 2176, "refunded_usd": 0, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "invoice_available": true, "created_at": "2026-10-14T06:35:02.410Z" } ], "has_more": false}Get the invoice PDF
GET/v1/payments/:id/invoice
Invoices are issued by Vitix's merchant of record in the customer's name and show the USD amount charged.
Returns
An object with a short-lived url to the PDF (valid about an hour). Fetch a fresh one each time rather than storing it. Returns invoice_unavailable for test payments or while the PDF is still being generated (retry after a few seconds).
curl https://api.vitix.net/v1/payments/py_live_4YMjlAzqiKxSYAIsAWEToqvL/invoice \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "invoice", "payment": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "url": "https://…/invoice.pdf?X-Amz-Expires=3600&…", "expires_in": 3600}Refunds
Request a full or partial refund. No provider request is sent until Vitix staff approves. Live refunds are confirmed asynchronously by the payment provider: watch for refund.succeeded / refund.failed and payment.refunded. Processing fees are not returned.
The refund object
Attributes
- idstring
- Prefixed
re_live_orre_test_. - objectstring
- Always
refund. - livemodeboolean
- Live or test.
- paymentstring
- The payment being refunded.
- statusenum
requestedawaiting Vitix review;rejectedif declined;pendingafter approval, thensucceededorfailed. Test refunds also require approval.- amount_usdinteger
- Refunded amount in USD cents.
- reasonenum | null
duplicate,fraudulent,customer_requestorother.- created_attimestamp
- ISO 8601.
{ "id": "re_live_dwxgQnlN31ZGfcZECgvAFygc", "object": "refund", "livemode": true, "payment": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "status": "requested", "amount_usd": 500, "reason": "customer_request", "reviewed_at": null, "review_note": null, "submission_error": null, "created_at": "2026-10-15T09:12:00.000Z"}Request a refund
POST/v1/refunds
Always send an Idempotency-Key: a retried refund call without one could refund twice (up to the remaining balance).
Parameters
- paymentstringrequired
- Id of the payment to refund.
- amount_usdinteger
- USD cents to refund. Defaults to the unrefunded balance. Must not exceed it.
- reasonenum
duplicate,fraudulent,customer_request(default) orother.
Returns
The refund request with status: "requested". No money moves until Vitix approves. HTTP 201. Fails with refund_pending while another refund of the same payment is awaiting review or processing and amount_invalid if the amount exceeds the remaining balance.
curl -X POST https://api.vitix.net/v1/refunds \ -H "Authorization: Bearer vx_live_••••••••" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: refund_8f1c" \ -d '{ "payment": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "amount_usd": 500, "reason": "customer_request" }'{ "id": "re_live_dwxgQnlN31ZGfcZECgvAFygc", "object": "refund", "livemode": true, "payment": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "status": "requested", "amount_usd": 500, "reason": "customer_request", "reviewed_at": null, "review_note": null, "submission_error": null, "created_at": "2026-10-15T09:12:00.000Z"}curl https://api.vitix.net/v1/refunds/re_live_dwxgQnlN31ZGfcZECgvAFygc \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "re_live_dwxgQnlN31ZGfcZECgvAFygc", "object": "refund", "livemode": true, "payment": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "status": "succeeded", "amount_usd": 500, "reason": "customer_request", "reviewed_at": null, "review_note": null, "submission_error": null, "created_at": "2026-10-15T09:12:00.000Z"}List refunds
GET/v1/refunds
Query parameters
- paymentstring
- Only refunds of this payment.
- limitinteger
- 1–100, default 20.
- starting_afterstring
- Cursor.
Returns
A list object of refunds, newest first.
curl https://api.vitix.net/v1/refunds?payment=py_live_4YMjlAzqiKxSYAIsAWEToqvL \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "list", "data": [ { "id": "re_live_dwxgQnlN31ZGfcZECgvAFygc", "object": "refund", "livemode": true, "payment": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "status": "requested", "amount_usd": 500, "reason": "customer_request", "reviewed_at": null, "review_note": null, "submission_error": null, "created_at": "2026-10-15T09:12:00.000Z" } ], "has_more": false}Events
Every state change produces an event. Events are what webhooks deliver, and they stay queryable here so you can audit, backfill or replay them. The Webhooks page lists the event types and the delivery contract.
The event object
Attributes
- idstring
- Prefixed
evt_live_orevt_test_. Also sent as thewebhook-idheader; stable across redeliveries. - objectstring
- Always
event. - livemodeboolean
- Live or test.
- typestring
- One of the event types.
- created_attimestamp
- ISO 8601.
- data.objectobject
- The resource the event is about (a checkout, payment or refund), in the state it had when the event was created.
{ "id": "evt_live_dBbRDc4vUYcwjyp93GkDKtyF", "object": "event", "livemode": true, "type": "payment.succeeded", "created_at": "2026-10-14T06:35:02.455Z", "data": { "object": { "id": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "object": "payment", "livemode": true, "status": "succeeded", "checkout": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "fee_usd": 132, "net_usd": 2176, "refunded_usd": 0, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "invoice_available": true, "created_at": "2026-10-14T06:35:02.410Z" } }}List events
GET/v1/events
If your webhook endpoint was down for longer than the retry window, page through this list to catch up.
Query parameters
- typestring
- Only events of this type, e.g.
payment.succeeded. - limitinteger
- 1–100, default 20.
- starting_afterstring
- Cursor.
Returns
A list object of events, newest first.
curl https://api.vitix.net/v1/events?type=payment.succeeded&limit=50 \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "list", "data": [ { "id": "evt_live_dBbRDc4vUYcwjyp93GkDKtyF", "object": "event", "livemode": true, "type": "payment.succeeded", "created_at": "2026-10-14T06:35:02.455Z", "data": { "object": { "id": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "object": "payment", "livemode": true, "status": "succeeded", "checkout": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "fee_usd": 132, "net_usd": 2176, "refunded_usd": 0, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "invoice_available": true, "created_at": "2026-10-14T06:35:02.410Z" } } } ], "has_more": false}Retrieve an event
GET/v1/events/:id
A common hardening pattern: on receiving a webhook, fetch the event by id and act on the fetched copy rather than the posted body.
Returns
The event object.
curl https://api.vitix.net/v1/events/evt_live_dBbRDc4vUYcwjyp93GkDKtyF \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "evt_live_dBbRDc4vUYcwjyp93GkDKtyF", "object": "event", "livemode": true, "type": "payment.succeeded", "created_at": "2026-10-14T06:35:02.455Z", "data": { "object": { "id": "py_live_4YMjlAzqiKxSYAIsAWEToqvL", "object": "payment", "livemode": true, "status": "succeeded", "checkout": "cs_live_0aWdSNgZbvGU0BjvCISLh07o", "amount": 600000, "currency": "vnd", "amount_usd": 2308, "fee_usd": 132, "net_usd": 2176, "refunded_usd": 0, "description": "Acme credits", "customer": { "id": "user_42", "email": "[email protected]", "name": "Ana Nguyen" }, "reference": "topup_8f1c", "metadata": { "plan": "pro" }, "invoice_available": true, "created_at": "2026-10-14T06:35:02.410Z" } }}List deliveries of an event
GET/v1/events/:id/deliveries
Returns
A list object of webhook deliveries (all attempts, all endpoints), newest first.
curl https://api.vitix.net/v1/events/evt_live_dBbRDc4vUYcwjyp93GkDKtyF/deliveries \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "list", "data": [ { "id": "wd_UZVVfiXb1UChe8HUwzXN", "object": "webhook_delivery", "event": "evt_live_dBbRDc4vUYcwjyp93GkDKtyF", "endpoint": "we_y2uBTZdXLUmV9dRRQ3Rh", "attempt": 1, "status": "succeeded", "next_attempt_at": null, "response_status": 200, "response_body": "ok", "error": null, "duration_ms": 184, "delivered_at": "2026-10-14T06:35:02.700Z", "created_at": "2026-10-14T06:35:02.460Z" } ], "has_more": false}The webhook_delivery object
One row per attempt. Read-only.
Attributes
- idstring
- Prefixed
wd_. - eventstring
- The event delivered.
- endpointstring
- The endpoint it was sent to.
- attemptinteger
- 1 for the first try, then 2…6 for automatic retries. Manual redeliveries continue the count.
- statusenum
pending,sending,succeededorfailed.- next_attempt_attimestamp | null
- When a pending delivery will be sent.
- response_statusinteger | null
- HTTP status your endpoint returned.
- response_bodystring | null
- First 1,000 characters of your response, to help debugging.
- errorstring | null
- Transport error, e.g.
timeout after 10sorHTTP 500. - duration_msinteger | null
- Round-trip time.
- delivered_attimestamp | null
- When a 2xx was received.
- created_attimestamp
- ISO 8601.
{ "id": "wd_UZVVfiXb1UChe8HUwzXN", "object": "webhook_delivery", "event": "evt_live_dBbRDc4vUYcwjyp93GkDKtyF", "endpoint": "we_y2uBTZdXLUmV9dRRQ3Rh", "attempt": 1, "status": "succeeded", "next_attempt_at": null, "response_status": 200, "response_body": "ok", "error": null, "duration_ms": 184, "delivered_at": "2026-10-14T06:35:02.700Z", "created_at": "2026-10-14T06:35:02.460Z"}Redeliver an event
POST/v1/events/:id/redeliver
Queues a fresh delivery immediately. The event keeps its id, so a correctly idempotent handler will treat it as a duplicate.
Query parameters
- endpointstring
- Only resend to this endpoint id. Default: all enabled endpoints of the event's mode.
Returns
A list object of the newly queued deliveries. HTTP 201.
curl -X POST https://api.vitix.net/v1/events/evt_live_dBbRDc4vUYcwjyp93GkDKtyF/redeliver \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "list", "data": [ { "id": "wd_UZVVfiXb1UChe8HUwzXN", "object": "webhook_delivery", "event": "evt_live_dBbRDc4vUYcwjyp93GkDKtyF", "endpoint": "we_y2uBTZdXLUmV9dRRQ3Rh", "attempt": 2, "status": "pending", "next_attempt_at": null, "response_status": 200, "response_body": "ok", "error": null, "duration_ms": 184, "delivered_at": "2026-10-14T06:35:02.700Z", "created_at": "2026-10-14T06:35:02.460Z" } ], "has_more": false}Webhook endpoints
Register up to 10 URLs per mode to receive events. Each endpoint has its own signing secret. Endpoints created with a test key only receive test events, and vice versa.
The webhook_endpoint object
Attributes
- idstring
- Prefixed
we_. - objectstring
- Always
webhook_endpoint. - livemodeboolean
- Endpoints are mode-scoped: a live endpoint only receives live events. The mode is taken from the key used to create it.
- urlstring
- Where events are POSTed. Must be https in live mode.
- descriptionstring
- Free text.
- eventsstring[]
- Event types to deliver, or
["*"]for all. - statusenum
enabledordisabled. Disabled endpoints receive nothing and pending deliveries fail.- secretstring
- Signing secret (
whsec_…). Returned only on create and rotate. - created_attimestamp
- ISO 8601.
{ "id": "we_y2uBTZdXLUmV9dRRQ3Rh", "object": "webhook_endpoint", "livemode": true, "url": "https://app.example.com/api/vitix/webhook", "description": "Production", "events": ["payment.succeeded", "payment.refunded"], "status": "enabled", "secret": "whsec_9fQm3…", "created_at": "2026-10-14T06:32:46.000Z"}Create a webhook endpoint
POST/v1/webhook_endpoints
Parameters
- urlstringrequired
- Absolute URL. Must be https in live mode.
- descriptionstring
- Up to 200 characters.
- eventsstring[]
- Event types to subscribe to. Default
["*"].
Returns
The endpoint including its secret. Store the secret now; it is not returned by later reads. HTTP 201.
curl -X POST https://api.vitix.net/v1/webhook_endpoints \ -H "Authorization: Bearer vx_live_••••••••" \ -H "Content-Type: application/json" \ -d '{ "url": "https://app.example.com/api/vitix/webhook", "description": "Production", "events": ["payment.succeeded", "payment.refunded"] }'{ "id": "we_y2uBTZdXLUmV9dRRQ3Rh", "object": "webhook_endpoint", "livemode": true, "url": "https://app.example.com/api/vitix/webhook", "description": "Production", "events": ["payment.succeeded", "payment.refunded"], "status": "enabled", "secret": "whsec_9fQm3…", "created_at": "2026-10-14T06:32:46.000Z"}Retrieve a webhook endpoint
GET/v1/webhook_endpoints/:id
Returns
The endpoint object without its secret.
curl https://api.vitix.net/v1/webhook_endpoints/we_y2uBTZdXLUmV9dRRQ3Rh \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "we_y2uBTZdXLUmV9dRRQ3Rh", "object": "webhook_endpoint", "livemode": true, "url": "https://app.example.com/api/vitix/webhook", "description": "Production", "events": ["payment.succeeded", "payment.refunded"], "status": "enabled", "created_at": "2026-10-14T06:32:46.000Z"}List webhook endpoints
GET/v1/webhook_endpoints
Returns
A list object of the endpoints in the key's mode (secrets omitted).
curl https://api.vitix.net/v1/webhook_endpoints \ -H "Authorization: Bearer vx_live_••••••••"{ "object": "list", "data": [ { "id": "we_y2uBTZdXLUmV9dRRQ3Rh", "object": "webhook_endpoint", "livemode": true, "url": "https://app.example.com/api/vitix/webhook", "description": "Production", "events": ["payment.succeeded", "payment.refunded"], "status": "enabled", "created_at": "2026-10-14T06:32:46.000Z" } ], "has_more": false}Update a webhook endpoint
PATCH/v1/webhook_endpoints/:id
Parameters
- urlstring
- New URL (https in live mode).
- descriptionstring
- New description.
- eventsstring[]
- Replace the subscription list.
- statusenum
enabledordisabled.
Returns
The updated endpoint.
curl -X PATCH https://api.vitix.net/v1/webhook_endpoints/we_y2uBTZdXLUmV9dRRQ3Rh \ -H "Authorization: Bearer vx_live_••••••••" \ -H "Content-Type: application/json" \ -d '{ "status": "disabled" }'{ "id": "we_y2uBTZdXLUmV9dRRQ3Rh", "object": "webhook_endpoint", "livemode": true, "url": "https://app.example.com/api/vitix/webhook", "description": "Production", "events": ["payment.succeeded", "payment.refunded"], "status": "disabled", "created_at": "2026-10-14T06:32:46.000Z"}Delete a webhook endpoint
DELETE/v1/webhook_endpoints/:id
Returns
A confirmation object. Pending deliveries to the endpoint are dropped.
curl -X DELETE https://api.vitix.net/v1/webhook_endpoints/we_y2uBTZdXLUmV9dRRQ3Rh \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "we_y2uBTZdXLUmV9dRRQ3Rh", "object": "webhook_endpoint", "deleted": true}Rotate the signing secret
POST/v1/webhook_endpoints/:id/rotate_secret
Returns
The endpoint with its new secret. Deliveries queued after this call are signed with the new secret; update your server before rotating in production.
curl -X POST https://api.vitix.net/v1/webhook_endpoints/we_y2uBTZdXLUmV9dRRQ3Rh/rotate_secret \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "we_y2uBTZdXLUmV9dRRQ3Rh", "object": "webhook_endpoint", "livemode": true, "url": "https://app.example.com/api/vitix/webhook", "description": "Production", "events": ["payment.succeeded", "payment.refunded"], "status": "enabled", "secret": "whsec_Lk2p8…", "created_at": "2026-10-14T06:32:46.000Z"}Ping a webhook endpoint
POST/v1/webhook_endpoints/:id/ping
Sends a signed ping event to this endpoint only. Use it to verify your signature check end to end.
Returns
The ping event and the queued delivery. HTTP 201.
curl -X POST https://api.vitix.net/v1/webhook_endpoints/we_y2uBTZdXLUmV9dRRQ3Rh/ping \ -H "Authorization: Bearer vx_live_••••••••"{ "event": { "id": "evt_test_cdQrBfJ6mQ5DCbP5ccQAmnTf", "object": "event", "livemode": false, "type": "ping", "created_at": "2026-10-14T06:40:11.000Z", "data": { "object": { "object": "ping", "endpoint": "we_y2uBTZdXLUmV9dRRQ3Rh", "message": "Hello from Vitix Pay" } } }, "deliveries": [ { "id": "wd_UZVVfiXb1UChe8HUwzXN", "object": "webhook_delivery", "event": "evt_live_dBbRDc4vUYcwjyp93GkDKtyF", "endpoint": "we_y2uBTZdXLUmV9dRRQ3Rh", "attempt": 1, "status": "pending", "next_attempt_at": null, "response_status": 200, "response_body": "ok", "error": null, "duration_ms": 184, "delivered_at": "2026-10-14T06:35:02.700Z", "created_at": "2026-10-14T06:35:02.460Z" } ]}Retrieve your account
GET/v1/account
A cheap call to verify a key and read the limits you should validate against before creating checkouts.
Returns
Your partner account, its amount limits (USD cents) and allowed return domains. livemode reflects the key you used.
curl https://api.vitix.net/v1/account \ -H "Authorization: Bearer vx_live_••••••••"{ "id": "pt_IfF9npu7GIGDS6UJ", "object": "account", "livemode": true, "name": "Acme SaaS", "slug": "acme", "limits": { "min_usd": 2000, "max_usd": 500000 }, "allowed_domains": ["app.example.com"], "created_at": "2026-10-14T06:32:45.156Z"}