Get API key

Transactions

Create Lightning invoices and send payments to BOLT11 invoices or Lightning Addresses with the Amboss Payments SDK, including live progress and sandbox testing.

The transactions resource is where money moves. createReceive mints an invoice; send pays one. Both are fully typed and work against sandbox and live wallets.

Receiving

transactions.createReceive generates a Lightning invoice for a wallet. The backend mints the invoice on the node itself, so there is no team password or macaroon involved, and it behaves identically in sandbox and live.

const transaction = await payments.transactions.createReceive({
  wallet_id: walletId,
  amount: "1000", // base units (sats for BTC)
  description: "Order #1234", // optional
  expires_in_seconds: 3600, // optional
  idempotency_key: "order-1234-attempt-1", // optional
});

transaction.payment_request; // the BOLT11 invoice to share with the payer
transaction.payment_hash;

Render payment_request as a QR code or a lightning: link. Track settlement via webhooks. For the field reference and lifecycle diagram, see Receive Payments.

Sending

transactions.send mirrors the dashboard send flow. Every call requires a non-empty password. Live sends require the real team password; sandbox sends accept any non-empty value such as Password123 because it is not used. For a live wallet, the SDK derives the master key, decrypts the team symmetric key and node admin macaroon in-process, then executes the payment directly against the node's REST endpoint and resolves with the terminal result. The plaintext password never leaves your process.

A live send needs all of the following, or it fails at the node-permissions lookup:

  • The real team password (see Get Started → Try sending). Sandbox still requires the argument, but any non-empty value works there.
  • An API key with WALLETS: READ and WALLET_CREDENTIALS: READ, scoped to the wallet's wallet_id. The default create-key examples in API Keys don't grant this — mint a wallet-scoped credentials key instead.
  • Outbound HTTPS from your server to the node's REST endpoint.

Sandbox sends need no credential permission or node connectivity — see Sandbox sends below.

Base-asset wallets (BTC) pay over LND; Taproot Asset wallets pay over litd. The SDK picks the right endpoint automatically from the wallet's asset.

const { transaction, payment } = await payments.transactions.send({
  walletId,
  password, // team password, decrypts the node macaroon locally
  destination: { bolt11: "lnbc1..." },
  // zero-amount invoice: destination: { bolt11: "lnbc1...", amountSats: "1000" },
  onUpdate: ({ status }) => console.log(status), // 'IN_FLIGHT' | ...
});

payment.status; // 'SUCCEEDED' | 'FAILED'
payment.paymentHash;
payment.feeSat;

Set amountSats only for a zero-amount invoice. The API rejects it for an invoice that encodes an amount. amountSats is in sats for every wallet. A Taproot Asset wallet pays it in the asset at the current exchange rate.

const { transaction, payment } = await payments.transactions.send({
  walletId,
  password,
  destination: {
    lightningAddress: "[email protected]",
    amountSats: "1000",
  },
});

Send parameters

FieldTypeRequiredNotes
walletIdstringyesThe wallet the funds come from.
destinationSendDestinationyes{ bolt11, amountSats? } or { lightningAddress, amountSats }.
passwordstringyesReal team password for live sends. Any non-empty value works in sandbox because it is not used. Never sent to the API.
teamIdstringnoArgon2 salt for macaroon decryption. Resolved automatically from the wallet; pass it only to override the resolved value.
idempotencyKeystringnoReplays return the original transaction. Strongly recommended for sends.
metadataRecord<string, string>noArbitrary annotation. In sandbox, set amb_sandbox_behavior.
timeoutSecondsnumbernoDefaults to 60.
onUpdate(progress) => voidnoFires on each lifecycle transition (INITIATED, IN_FLIGHT, SUCCEEDED, FAILED).
signalAbortSignalnoAbort an in-flight payment.
allowSelfPaymentbooleannoSet to true to pay an invoice that one of your team's wallets issued, for example your Taproot Asset wallet's invoice from your BTC wallet. Defaults to false. See Paying your own invoice.

A wrong password throws DecryptionError; a node-side failure throws PaymentSendError. See Errors.

Sandbox sends

Sandbox wallets need no node or macaroon, but a non-empty password is still required so the same call shape works in production. Any value such as Password123 works because sandbox does not use it. The backend settles the transaction for you and payment comes back null; observe the outcome via webhooks or by polling the transaction status. Settlement follows the amb_sandbox_behavior metadata (complete, fail, or expire; default expire).

const { transaction, payment } = await payments.transactions.send({
  walletId, // a sandbox wallet
  password: "Password123", // any non-empty value works in sandbox
  destination: { bolt11: "lnbc1..." },
  metadata: { amb_sandbox_behavior: "complete" }, // force success in sandbox
});

payment; // null, settlement happens server-side

For network constraints, idempotency semantics, and how to inspect a failed send, see Send Payments.

Next steps