TriportRPC

Cancel an invoice

POSThttps://api.triport.io/v1/billing/invoices/inv_7c1f9a3e2b6d/cancel

Cancels one of your own pending invoices, transitioning it from `pending` to `cancelled`.

— (billing console; rail-agnostic)

POST /v1/billing/invoices/{id}/cancel cancels a payment invoice you no longer intend to pay. The invoice is moved from the pending status to cancelled, which retires its payment address and stops it from ever settling. On success the endpoint returns 204 No Content with an empty body.

Only pending invoices can be cancelled. If the invoice has already reached a terminal state — paid, expired, or cancelled — the transition is rejected. Cancellation is also scoped to the owning user: the invoice must belong to the account behind the session cookie. Requests for an invoice that does not exist, is not pending, or belongs to another user all collapse to the same 404 response, so the endpoint never reveals whether someone else's invoice id exists.

This is a console endpoint, authenticated by your logged-in dashboard session rather than by an API key. It is the counterpart to Create an invoice: create opens a pending invoice, cancel closes one that is still open.

Parameters

Path parameters

idstringrequired
The invoice id to cancel, as returned by Create an invoice or List invoices.

Response

On success the server responds 204 No Content with no body:

There are no response fields — the absence of a body is the success signal. To observe the resulting state, re-fetch the invoice with Get an invoice (its status will be cancelled) or listen for the invoice_cancelled event on the invoice event stream.

Errors

Billing errors use a flat envelope, {"error": "<message>"}:

{
  "error": "not found or not pending"
}
CodeMeaningWhen it happens
204CancelledSuccess — the invoice was pending and is now cancelled. No body.
401Not authenticatedThe nl_session cookie is missing, expired, or invalid.
404Not found or not pendingThe invoice does not exist, is not in the pending state (already paid, expired, or cancelled), or does not belong to the session user.

The single 404 deliberately conflates "no such invoice," "wrong owner," and "not pending" so that one account cannot probe for another's invoice ids. Branch your UI on the HTTP status, not on the message text.

See the shared Errors page for the standard error envelope used across the API.

Examples

JavaScript (fetch)

const id = "inv_7c1f9a3e2b6d";


const res = await fetch(
  `https://api.triport.io/v1/billing/invoices/${id}/cancel`,
  {
    method: "POST",
    credentials: "include", // send the nl_session cookie
  },
);


if (res.status === 204) {
  // success — invoice is now cancelled
} else {
  let msg = `HTTP ${res.status}`;
  try {
    const body = await res.json();
    if (body?.error) msg = body.error;
  } catch {
    /* no JSON body */
  }
  throw new Error(msg); // e.g. "not found or not pending"
}

TypeScript SDK (@triport/sdk)

import { TriportConsole } from "@triport/sdk";


const console = new TriportConsole(); // uses the browser session cookie


await console.billing.cancelInvoice("inv_7c1f9a3e2b6d");
// resolves on 204; throws if the invoice is not pending or not yours

Python (triport-sdk)

import os
from triport import ConsoleClient


console = ConsoleClient(session=os.environ["TRIPORT_SESSION"])


console.billing.cancel_invoice("inv_7c1f9a3e2b6d")
# returns None on success (204); raises on 401 / 404

Notes

  • Pending-only, one-way. Cancellation works only from pending; there is no endpoint to un-cancel. Terminal states (paid, expired, cancelled) are rejected with 404.
  • Don't cancel to pay differently. If you want to settle a pending invoice from your account balance instead of on-chain, use Pay from balance — you don't need to cancel first.
  • Watch the state change live. A cancelled invoice emits an invoice_cancelled event on the invoice event stream; subscribers can react without polling.
  • Related: Create an invoice · Get an invoice · List invoices · Errors