Skip to Content
DocumentationPayment Links

Payment Links

Payment links are reusable URLs that open a checkout page. Unlike one-time checkouts, a payment link can be shared and used by multiple customers.


POST /api/v1/links
curl -X POST https://api.inzilink.com/api/v1/links \ -H "Authorization: Bearer sk_live_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "title": "Pro Plan — Monthly", "amount": 29, "displayCurrency": "USD", "linkType": "subscription", "metadata": { "plan": "pro" } }'

Fields

FieldTypeDefaultNotes
titlestring—Required, up to 255 characters.
descriptionstring—Up to 2000 characters.
amountnumber | nullopen amountA number, not a string. null or no field — the customer enters the amount.
displayCurrencystringUSDUSD or EUR.
acceptedTokensstring[]["USDC", "USDT"]USDC and USDT settle USD; EURC settles EUR. A token that does not settle displayCurrency is refused.
acceptedChainsstring[]all supportedsolana, polygon, base, ton, tron, ethereum.
isReusablebooleantruetrue — the link accepts payments until you pause or archive it. false — one payment, then the link is paid.
linkTypestringcustomSee Link types.
expiresAtISO 8601—After this time the link no longer opens checkout.
redirectUrlURL—Where the customer goes after paying.
webhookUrlURL—HTTPS endpoint for this link’s payment events.
metadataobject—String values, up to 500 characters each.
payerIdUUID—Link addressed to a saved payer. No field — anyone can pay.

isReusable defaults to true through the API. A link created without the field accepts more than one payment. The dashboard creates one-time requests by default; the API default does not change, so integrations that do not send the field keep their behaviour. Send "isReusable": false for a one-time request.

Unknown fields are ignored, not rejected — check the field names above if a setting seems to have no effect.

TypeUse case
invoiceOne-time payment for a specific amount
donationFlexible amount (user chooses)
subscriptionRecurring billing (manual re-payment)
customGeneral purpose

GET /api/v1/links?limit=20&offset=0

GET /api/v1/links/{id}

Returns the same link object as one row of the list.


FieldTypeNotes
idstring (uuid)
shortCodestring
titlestring
descriptionstring | null
amountnumber | nullnull — the payer enters the amount. See the note below.
displayCurrencystringCurrency of amount and of every amount in request.
acceptedTokensstring[]
acceptedChainsstring[]
isReusablebooleanfalse with a non-null amount is a payment request.
statusstringactive, paused, archived, canceled.
isActivebooleanDerived from status.
linkTypestring | null
paymentUrlstring
payerIdstring | nullWho the link is issued to.
createdAtstring (ISO 8601)
totalReceivednumberDeprecated for payment requests — use request.
paymentCountnumberDeprecated for payment requests — use request.
requestobject | nullPayment state of a payment request. null for reusable links and links without a fixed amount.

totalReceived and paymentCount are deprecated for payment requests. They count the request only once it closes and never show a partial payment. Read request.received, request.remaining and request.state instead — they sum every attempt on the request.

Known inconsistency: amount is a number. Every other amount in the API is a decimal string (request.received, request.remaining, checkout amounts). amount will become a string in the next API version; parse it as a decimal, not as a float, until then.

request — payment request state

All amounts are decimal strings in displayCurrency, without trailing zeros.

FieldTypeNotes
statestringawaiting · detected · partially_paid · paid · overpaid
receivedstring | nullSum over every attempt on the request. null — nothing arrived.
remainingstring | nullLeft to pay. On a request accepted as paid — the amount written off.
surplusstring | nullOnly when overpaid.
acceptedAsPaidbooleanClosed with Accept as paid rather than paid in full.
acceptedAsPaidAtstring | nullISO 8601. When it was accepted as paid.
acceptedAsPaidBystring | nullTeam member who accepted it: name, or email if the member has no name.
topUpOpenUntilstring | nullISO 8601. Until when a top-up can still arrive on at least one attempt. null — no window left, or the request is closed.

While topUpOpenUntil is in the future, a transfer may still be on its way. Accepting the request as paid before then writes off money that may yet arrive.


Accept a partially paid request as paid

POST /api/v1/links/{id}/accept-as-paid

Closes a partially paid request with the amount actually received. The difference is written off, recorded in the audit log, and you receive checkout.completed with accepted_as_paid: true. Owner or admin only, from the dashboard session; API keys are refused.

ErrorStatusMeaning
NOT_FOUND404No such request for this merchant.
NOT_A_REQUEST409Reusable link or no fixed amount.
NOT_PARTIALLY_PAID409Nothing arrived yet, or it is already paid in full.
ALREADY_CLOSED409Already closed as paid.

Send a request by email

POST /api/v1/links/{id}/send-email
{ "to": "client@example.com" }

Emails the request to your customer: title, amount, what they pay one to one, and the payment link. Sending again sends the same request — no new link is created. The link and QR code work whether or not the email went out.

201 means our email provider accepted the email; it is not a delivery receipt. Every attempt is kept: GET /api/v1/links/{id}/emails lists them newest first. GET /api/v1/links/{id}/email-preview returns the subject and text that will be sent.

Only a person on your team with a confirmed email can send; API keys cannot.

ErrorStatusMeaning
NOT_FOUND404No such link for this merchant.
LINK_NOT_OPEN409The link is paused, archived or canceled.
REQUEST_EMAILS_NOT_AVAILABLE403The sender has no confirmed email, or it is an API key.
TOO_MANY_EMAILS4295 emails already went out for this request in the last hour; details.retryAfterSec.
REQUEST_EMAIL_LIMIT429Too many request emails from this account.
EMAIL_NOT_SENT502The email did not go out. The attempt is recorded as failed.

PATCH /api/v1/links/{id}/status
{ "status": "paused" }

Available statuses: active, paused, archived.

Payment links use the Checkout API under the hood. Each time someone pays via a payment link, a new checkout session is created. You receive the same checkout.completed webhook.

Last updated on