Mint the single-use pay link for the live balance of one of my bookings
const url = 'https://quikstik-core.fly.dev/account/obligations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/balance-links';const options = { method: 'POST', headers: {'Idempotency-Key': 'example', Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://quikstik-core.fly.dev/account/obligations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/balance-links \ --header 'Authorization: Bearer <token>' \ --header 'Idempotency-Key: example'Customer portal, guest-scoped (HANDOFF-account-self-serve-2026-10-18 WP3). local-person
session; the obligation must be one the caller’s reach rule returns (buyer, rider, or head
of a rider) — anything else is 404 obligation_not_found. This is the staff mint
(POST /obligations/{obligation_ref}/balance-links) scoped to the signed-in person: same
refusals (409 nothing_owed, obligation_not_open, idempotency_key_reused), same
one-open-link supersession, the link stores no amount, and the page it opens reads the live
balance. The portal redirects to url. A replay of the same Idempotency-Key is 200 with
url: null (the plaintext token is not recoverable), so a button press should send a fresh key.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Header Parameters
Section titled “Header Parameters”Idempotency key for the command envelope. A retry with the same key is a no-op.
Responses
Section titled “Responses”Replay of an earlier mint with the same key (no url)
object
The pay page; present only on the minting call
Present on a replay
Example generated
{ "link_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "obligation_ref": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "url": "example", "expires_at": "2026-04-15T12:00:00Z", "status": "example", "already_minted": true}Minted
object
The pay page; present only on the minting call
Present on a replay
Example generated
{ "link_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "obligation_ref": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "url": "example", "expires_at": "2026-04-15T12:00:00Z", "status": "example", "already_minted": true}Malformed body
object
Example generated
{ "reason": "example"}Missing or invalid session bearer token
object
Stable, machine-readable reason code (e.g. “sold_out”, “processor_not_configured”, “rail_refused”).
Example
{ "reason": "sold_out"}The session’s effect authority does not cover this operation
object
Stable, machine-readable reason code (e.g. “sold_out”, “processor_not_configured”, “rail_refused”).
Example
{ "reason": "sold_out"}Expired, consumed, unknown, or unresolvable — indistinguishable by design
object
Example generated
{ "reason": "example"}nothing_owed, obligation_not_open, or idempotency_key_reused
object
Stable machine reason
Finer machine code under reason
object
Minor units the card gets back
Hours-before-departure the applying tier requires; absent when no tier applies
Last instant this refund still applies; absent when no tier applies
Example generated
{ "reason": "example", "detail": "example", "current": { "booking_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "refund_minor": 1, "refund_bps": 1, "tier_hours": 1, "deadline_at": "2026-04-15T12:00:00Z", "currency": "example" }}The command is rejected by a domain lifecycle gate (illegal state transition)
object
Stable machine-readable error code
Human-readable explanation (never leaks SQL, URLs, or secrets)
Example generated
{ "code": "example", "message": "example"}No durable backend is wired for this operation (fail-closed)
object
Stable, machine-readable reason code (e.g. “sold_out”, “processor_not_configured”, “rail_refused”).
Example
{ "reason": "sold_out"}