Skip to content

Approvals

Tracking a payment through approval

Last updated 14 September 2026

When a payment you created needs sign-off, it does not fail and it does not send. It waits. This guide is about seeing where it is.

When approval applies

Finance configures approval policies in the web app under Team, Approval Policies. Each policy has an amount range, a set of approvers and a scope, and the scope includes a setting for whether the policy covers API-created payments. If it does, your POST /payments creates an approval request rather than a payment in flight.

Agree the policies with finance before you integrate. A payout service that assumes instant sending will look broken the first time a policy catches a payment.

Finding the approval

Three endpoints:

  • GET /account/{xaid}/approvals: approvals for one account, paged, up to 50 per page. Use this.
  • GET /approvals: all approvals the credentials can see.
  • GET /approval/{ref}: one approval by its reference.

An approval record carries ref, xtid, parent_xaid, status, the transaction it relates to and a meta object. Match on xtid from the payment response.

find-approval.jsjavascript
async function findApproval(xaid, xtid, token) {
  const approvals = await listAll(`/account/${xaid}/approvals`, token, 50);
  return approvals.find(a => a.xtid === xtid) ?? null;
}

Polling

An approval can take minutes or days depending on who has to sign. Poll gently:

  1. Immediately after creating the payment, check once. If there is no approval record, the payment did not need one.
  2. Then check every few minutes for the first hour, every 15 minutes after that.
  3. Stop when the status is no longer pending, or when the xtid appears in GET /account/{xaid}/transactions, which means it was approved and sent.

Show the status to whoever is waiting. "Awaiting approval by finance" is a much better message than a spinner.

Declined and expired

If the approval is declined, or expires under the policy's expiry window, the payment is not sent. Your job should surface that to a person and must not resubmit automatically; a declined payment was declined for a reason.

Webhooks instead of polling

Subscribe to TransactionConfirmed on the account and you are told when the payment settles, without polling. Use the approval endpoints for the "waiting" state and the webhook for the "done" state. See Subscribing to webhooks.

Approving from the API

The Customer API exposes approvals for reading. Approving and declining happens in the web app or Xace Mobile, where the approver's identity and MFA are checked. See [How to approve transactions created by multi-users](https://support.xace.io/en/articles/8711903-how-to-approve-transactions-created-by-multiusers).

Was this page helpful?
Suggest edits