Payment links
Scopes: links:write to create, links:read to read. Live only.
POST /v1/payment_links
A price with a URL on it. No money moves when you create one; every payment against it is an ordinary charge created later, by the payer, on the hosted page.
Headers: Idempotency-Key optional. A link takes no money, so a duplicate is a second link you can see and close — but if your client sends one, a retry returns the link it made rather than a second URL, and the same key with a different price is IDEMPOTENT_MISMATCH.
Body
| Field | ||
|---|---|---|
amount_minor | required | Fixed price, whole shillings. |
title | required | 2–80 chars. What the payer is paying for. |
kind | optional | reusable (default) or single_use. |
max_uses | optional | Reusable only. Integer ≥ 1. |
expires_at | optional | ISO-8601, in the future. |
description | optional | ≤ 500 chars. |
reference | optional | ≤ 200 chars. |
success_url | optional | Where to send the payer afterwards. Must be https and on the website registered for your business at KYB. |
Response 201
json
{
"id": "pl_01HZX…",
"object": "payment_link",
"kind": "reusable",
"url": "https://pay.pamopay.co/l/9mQx…",
"amount_minor": 2500000,
"currency": "TZS",
"title": "Term 3 trip deposit",
"description": "",
"reference": "TRIP-T3",
"max_uses": null,
"used": 0,
"active": true,
"expires_at": null,
"success_url": null,
"created": "2026-09-16T09:14:02.118Z"
}Send url to the payer. The price is fixed: a payer cannot decide what to pay on a link. For a balance somebody pays down over time, issue a bill.
Refusals: BAD_AMOUNT, BAD_REQUEST (title, max_uses, expiry), NO_REGISTERED_WEBSITE, BAD_RETURN_URL.
GET /v1/payment_links/{id} · GET /v1/payment_links
Read them back. The list takes limit only, newest first. Closing a link is done from the dashboard.