Overview
The Vaki API lets a partner run fundraising on Vaki’s rails: create a cause, mint hosted checkout links, and reconcile the money that comes in against your own records.
Base URL
Section titled “Base URL”https://api.vaki.co/v1
Every path on this site is relative to that. The major version lives in the URL and never changes meaning — see Versioning.
There is a second base URL — the sandbox, the same /v1
code on our staging deployment, with its own keys and its own data:
https://public-api-staging.vaki.co/v1
The Examples switcher in the header (and in the menu on a narrow screen) rewrites the base URL in every code block on this site, including what the copy button puts on your clipboard, so you can read the whole site in whichever environment you are working against. This page is the one that always names both.
What you can call today
Section titled “What you can call today”| Endpoint | What it does | Permission |
|---|---|---|
POST /v1/checkout_links | Mint a hosted checkout URL for a vaki | checkout_links:write |
GET /v1/checkout_links/{id} | Read a link’s status — open, completed, expired, cancelled | checkout_links:read |
POST /v1/vakis | Create a cause in draft | vakis:write |
GET /v1/vakis/{key} | Read a cause | vaki:read |
Eight further endpoints — webhooks, updates, finances, verification, bank accounts, provider and creator onboarding, withdrawals — have published contracts under Coming soon. They are not routed and not callable. We publish the contract so you can design against it, not so you can call it.
What a donor can pay with
Section titled “What a donor can pay with”Local rails where the donor is, cards everywhere else. You never choose the method, build that UI, or see a payment credential: you mint a checkout link and the hosted page offers what is available for that cause.
| Where the donor is | What they can pay with today |
|---|---|
| Colombia | PSE bank transfer, and credit or debit cards |
| Mexico | PayPal |
| United States and everywhere else | Credit and debit cards, wherever they were issued |
Cards are processed by Stripe, so a donor with a card almost anywhere in the world can give to a cause that collects in Colombia. PSE is Colombia’s bank-transfer network and is the method most Colombian donors reach for; it is served through Cobre.
US-based giving through the Vaki USA Foundation — an IRS-approved 501(c)(3) with its own Stripe account — is a separate route with its own entity, selected by the API key you hold rather than by anything in the request. It is being built and is not issuable yet. Read US giving via the Vaki USA Foundation before you plan a campaign aimed at US donors: what it gives you is real, and what it does not give you yet is a tax outcome you can promise.
Conventions
Section titled “Conventions”These hold everywhere, and most integration bugs come from one of them.
Amounts are integers, in the currency’s smallest billable unit
Section titled “Amounts are integers, in the currency’s smallest billable unit”Vaki’s domain treats COP as having no minor unit and USD as having one.
| Currency | You send | The donor pays |
|---|---|---|
COP | 50000 | COP 50.000 |
USD | 5000 | USD 50.00 |
Never send a decimal. Never send a formatted string. A float amount is a 400,
not a rounding surprise.
A cause collects in exactly one currency
Section titled “A cause collects in exactly one currency”Every vaki has a currency, fixed when the cause is created — COP, USD or
MXN in practice — and it is also the currency the cause settles in.
POST /v1/checkout_links rejects any other currency with a 422 and
currency_not_supported. It does not convert
for you, and that is deliberate: accepting a currency the cause does not collect
in would make the amount you asked for depend on an exchange rate nobody quoted.
So do not hardcode COP. Read the cause’s currency and send that value:
curl https://api.vaki.cohttps://public-api-staging.vaki.co/v1/vakis/clinicalaliga \ -H "Authorization: Bearer $VAKI_API_KEY"{ "key": "clinicalaliga", "object": "vaki", "finance_data": { "currency": "COP", "fee_percent": 5 }, "goal": { "amount": 50000000, "currency": "COP" }}One currency per cause is about settlement and your bookkeeping — it does not limit who can give. A donor abroad pays by card, and the charge is in the cause’s currency.
Timestamps are ISO 8601 with an offset
Section titled “Timestamps are ISO 8601 with an offset”2026-08-17T14:00:00Z. Always. Never an epoch integer, never a naive local
datetime. If you are writing a signature check or a comparison, parse it as a
date — do not do arithmetic on the string.
Identifiers are opaque and prefixed
Section titled “Identifiers are opaque and prefixed”chl_01J9Z4M2K7QF3B (checkout link), whe_… (webhook endpoint), ba_… (bank
account), wd_… (withdrawal). Store them as strings of arbitrary length. Do not
parse them, do not assume a length, and do not assume the part after the
underscore is a ULID forever.
A vaki key is different: it is the human-readable slug in the cause’s public
URL (vaki.co/clinicalaliga → clinicalaliga), and it is what you pass as
vaki when minting a checkout link.
external_reference is yours, and it authorizes nothing
Section titled “external_reference is yours, and it authorizes nothing”Put your own donation or order id in external_reference. It comes back on the
checkout link and lands on the resulting payment, which is what makes
reconciliation a join on one column.
It is also visible and editable by the donor in some surfaces, and we treat
it accordingly: it never selects a fee, a callback destination, or a
beneficiary. Neither should your code. If a value must be trusted, look it up
server-side by the chl_… id we minted.
Errors are RFC 9457 problem documents
Section titled “Errors are RFC 9457 problem documents”application/problem+json, with a stable machine code. Branch on code,
never on title or on the HTTP status alone. See Errors.
Requests that create things take Idempotency-Key
Section titled “Requests that create things take Idempotency-Key”Send one on every POST. Retrying with the same key returns the original
response instead of creating a second resource. See
Idempotency.
What this API deliberately does not do
Section titled “What this API deliberately does not do”- It does not process payments. You never see a card number, a PSE session or a bank credential. You get a URL; Vaki and the gateway do the rest. That is what keeps your PCI scope at zero.
- It does not construct checkout URLs. You receive
urland redirect to it. The host and query shape are ours to change — and will change whencheckout.vaki.coships — without breaking you. - It does not move money out. Withdrawals are coming soon, and when they land the endpoint will request a payout with a human in the loop above a threshold. Money leaving the platform is not an unattended API call.
Getting a key
Section titled “Getting a key”API keys are issued per client by Vaki, scoped to the permissions you need. Write to soporte@vaki.co with the integration you are building and the named technical contact who should hold the key. Then read Authentication.