Reference

Errors

Muny uses conventional HTTP status codes and returns a consistent JSON error body you can branch on.

Error body#

422 Unprocessable Entity
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_address",
    "message": "recipient: Must be a valid Solana address",
    "request_id": "req_8f2c1a9b4d7e",
    "details": [{ "path": ["recipient"], "message": "Must be a valid Solana address" }]
  }
}

Branch on type and code; message is for humans and may change. Always log request_id — it is also returned in the x-request-id header.

Error types#

TypeStatusMeaning
invalid_request_error400 / 422The request is malformed or failed validation.
authentication_error401Missing, invalid, expired or revoked credentials.
permission_error403Authenticated, but the role or key scope doesn't allow this.
not_found_error404The resource doesn't exist or belongs to another organization.
idempotency_error409The idempotency key was reused with a different body, or is still in progress.
conflict_error409The resource is in a state that doesn't allow this action.
rate_limit_error429Too many requests. Back off and retry.
risk_error422Blocked by limits or risk checks.
api_error500Something went wrong on our side. Safe to retry with the same idempotency key.

Common codes#

CodeTypeWhat to do
invalid_addressinvalid_request_errorCheck the recipient is a base58 Solana address.
insufficient_fundsinvalid_request_errorFund the wallet, or wait for queued payouts to settle.
amount_exceeds_limitrisk_errorThe amount is above your per-payout limit.
daily_limit_exceededrisk_errorYour organization's daily payout limit would be exceeded.
idempotency_key_reusedidempotency_errorUse a new key for a different payout.
idempotency_key_in_progressidempotency_errorRetry after a short delay.
invalid_transitionconflict_errorE.g. cancelling a payout that is already processing.
wallet_cannot_signinvalid_request_errorThe funding wallet is an external, watch-only wallet.

Handling errors with the SDK#

ts
import { MunyError } from "@muny/sdk";

try {
  await muny.payouts.create({ recipient, amount: "500" });
} catch (err) {
  if (err instanceof MunyError && err.code === "insufficient_funds") {
    await alertFinanceTeam(err.requestId);
  } else {
    throw err;
  }
}