GitHub
PATH REQUEST

API reference

Payment requests

Issuing a request, reading one as any wallet, and closing it out.

Creation and closure need a member credential. Reading does not — that is what lets a wallet at another institution pay it.


POST /requests

{
  "amount": { "value": "5000", "asset_type": "fiat", "asset_code": "USD" },
  "accepts": [
    {
      "rail": "book",
      "asset_type": "fiat",
      "asset_code": "USD",
      "fees": [{ "kind": "operator", "amount": { "value": "25", "asset_type": "fiat", "asset_code": "USD" }, "paid_by": "payer" }]
    }
  ],
  "address_id": "addr_71bc",
  "order_reference": "ord_10482",
  "expires_at": "2026-09-10T10:00:00Z"
}
{
  "reference": "7fk2m9pq3vx8",
  "url": "https://api.example.com/path/7fk2m9pq3vx8",
  "status": "created",
  "expires_at": "2026-09-10T10:00:00Z"
}
FieldRequiredNotes
amountnoAn Amount. Omit to let the payer choose — a tip, a donation, an open invoice
acceptsyesOne capability per entry. Issued against an address, each entry must be in its standing intent
address_idnoBinds the request to that address's standing intent
order_referencenoYour own key. Returned to the payer
expires_atnoNo expiry means indefinite, which is rarely what you want

Idempotency: send Path-Idempotency-Key. A replay returns the original request rather than creating a second one — which matters most on the retry after a timeout, when you do not know whether the first call landed.

References are random. A sequential reference leaks volume: read two links a week apart and you know how many payments were requested in between.


GET /requests/{reference}

Public. No credential. This is the route a foreign wallet calls.

{
  "type": "path.request",
  "reference": "7fk2m9pq3vx8",
  "issuer": "example-member",
  "payee": { "member": "example-member", "address": "path:4a91c2f7e8d3" },
  "amount": { "value": "5000", "asset_type": "fiat", "asset_code": "USD" },
  "accepts": [
    {
      "rail": "book",
      "asset_type": "fiat",
      "asset_code": "USD",
      "fees": [{ "kind": "operator", "amount": { "value": "25", "asset_type": "fiat", "asset_code": "USD" }, "paid_by": "payer" }]
    }
  ],
  "intent_version": 3,
  "order_reference": "ord_10482",
  "status": "created",
  "settled_by": [],
  "expires_at": "2026-09-10T10:00:00Z",
  "grammar": 2,
  "protocol_version": "0.2.0",
  "signed_at": "2026-09-09T10:00:00Z",
  "kid": "op_example_2026_01",
  "signature": "…"
}

The same shape as a resolver answer with the terms already fixed. A wallet that reads one reads the other with no new code.

Verify before displaying

The domain says      WHERE TO FETCH
The signature says   WHO IS RESPONSIBLE

A link may be served from the issuer's domain, from its network under a managed arrangement, or from a custom domain. Fetch the issuer's keys from its discovery document, check the kid, then show the issuer's verified name — never the raw URL. A payer confronted with an unfamiliar hostname closes the app, and a card terminal shows a merchant name rather than an acquirer's for the same reason.

Errors

CodeStatusMeaning
path.request.expired410Past its expiry — ask for a new one
path.request.revoked410Revoked by the issuer
path.core.not_found404No such reference

Expired and revoked are distinguished from not-found on purpose: the payer needs to know whether they are too late or looking at the wrong thing.


POST /requests/{reference}/paid

{ "reference": "7fk2m9pq3vx8", "status": "paid" }

Separate from issuing a receipt, because payment and proof are two events that can be seconds or hours apart depending on the rail. Conflating them forces every integration to pretend every rail settles as fast as a signature.

Re-marking an already-paid request is not an error, and does not append a second transition — a duplicate webhook must not rewrite history.


POST /requests/{reference}/revoke

{ "reference": "7fk2m9pq3vx8", "status": "revoked" }

Only the issuer may revoke. A payer opening the link afterwards is told it was revoked rather than that it never existed.


Lifecycle

Fig. 01 — Lifecycle
created
paid
expired
revoked

created is the only state with anywhere to go. Every transition is recorded — a status overwritten without a trail cannot be contested, and disputes are the case that needs one.

On this page