Payment Destinations

Save Lightning Addresses as reusable payment destinations, optionally tagged with the currency the recipient converts to.

A payment destination is a saved Lightning Address you can send to again and again without re-entering it. Destinations are scoped to a single environment, like wallets and webhooks, and can be passed directly to create_send by id.

payment.destination.create(input: CreatePaymentDestinationInput) → PaymentDestination

Reads require a service API key with PAYMENTS: READ; create, update, and delete require PAYMENTS: WRITE. See API Keys.

Currency tags

A destination can carry an optional currency tag: EUR, USD, or MXN. The tag is informational — it records which currency the receiving service converts incoming sats to. Amboss does not convert anything; every send is a normal Lightning payment in sats.

  • Untagged destination — a standard BTC Lightning Address.
  • Tagged destination — an address at a service that converts incoming payments to fiat (for example a EUR address at Bringin, or an MXN address at Aureo).

Create a destination

FieldTypeRequiredNotes
environment_idUUIDyesThe environment the destination belongs to
labelstring (1 – 64)yesDisplay name, e.g. "Alice savings"
lightning_addressstring (1 – 255)yes[email protected] format
currencyPaymentDestinationCurrencynoEUR, USD, or MXN. Omit for a standard BTC address.
mutation CreateDestination {
  payment {
    destination {
      create(input: {
        environment_id: "81b73615-ddf3-46e3-943a-467c3e442e04"
        label: "Alice savings"
        lightning_address: "[email protected]"
        currency: EUR
      }) {
        id
        label
        type
        value { lightning_address }
        currency
        created_at
      }
    }
  }
}
curl -X POST https://rails.amboss.tech/graphql \
  -H "Content-Type: application/json" \
  -H "x-api-key: $AMBOSS_API_KEY" \
  -d '{
    "query": "mutation($input: CreatePaymentDestinationInput!) { payment { destination { create(input: $input) { id label type value { lightning_address } currency created_at } } } }",
    "variables": {
      "input": {
        "environment_id": "81b73615-ddf3-46e3-943a-467c3e442e04",
        "label": "Alice savings",
        "lightning_address": "[email protected]",
        "currency": "EUR"
      }
    }
  }'
import { GraphQLClient, gql } from "graphql-request";

const client = new GraphQLClient("https://rails.amboss.tech/graphql", {
  headers: { "x-api-key": process.env.AMBOSS_API_KEY },
});

const CREATE_DESTINATION = gql`
  mutation CreateDestination($input: CreatePaymentDestinationInput!) {
    payment {
      destination {
        create(input: $input) {
          id
          label
          value { lightning_address }
          currency
        }
      }
    }
  }
`;

const { payment } = await client.request(CREATE_DESTINATION, {
  input: {
    environment_id: process.env.AMBOSS_ENV_ID,
    label: "Alice savings",
    lightning_address: "[email protected]",
    currency: "EUR",
  },
});
console.log(payment.destination.create.id);

Example response:

{
  "data": {
    "payment": {
      "destination": {
        "create": {
          "id": "c2f9d8e1-4b6a-4f3c-9d2e-0987654321fe",
          "label": "Alice savings",
          "type": "LIGHTNING_ADDRESS",
          "value": { "lightning_address": "[email protected]" },
          "currency": "EUR",
          "created_at": "2026-07-03T12:00:00.000Z"
        }
      }
    }
  }
}

Live environments validate reachability. On create, the address is resolved as an LNURL-pay endpoint; an address that does not resolve is rejected with Invalid or unreachable lightning address. Sandbox environments skip this check, so you can save any address string for testing.

List destinations

find_many.list takes the environment id and returns the environment's destinations, newest first:

query ListDestinations($environmentId: String!) {
  payment {
    destination {
      find_many {
        list(environment_id: $environmentId) {
          id
          label
          type
          value { lightning_address }
          currency
          created_at
        }
      }
    }
  }
}

Fetch a single destination by id with find_one:

query GetDestination($id: String!) {
  payment {
    destination {
      find_one(id: $id) {
        id
        label
        value { lightning_address }
        currency
      }
    }
  }
}

Update a destination

Only the label and currency can change:

mutation UpdateDestination {
  payment {
    destination {
      update(input: {
        id: "c2f9d8e1-4b6a-4f3c-9d2e-0987654321fe"
        label: "Alice cold storage"
        currency: EUR
      }) {
        id
        label
        currency
        updated_at
      }
    }
  }
}

The address itself is immutable. To point a destination at a different Lightning Address, delete it and create a new one — this keeps past transactions linked to the address they were actually paid to.

Delete a destination

mutation DeleteDestination {
  payment {
    destination {
      delete(id: "c2f9d8e1-4b6a-4f3c-9d2e-0987654321fe")
    }
  }
}

Returns true on success. Deletion is soft — past transactions keep their payment_destination_id reference.

Send to a saved destination

Pass the destination id to create_send instead of a raw address. The amount is a positive integer string in the wallet asset's base unit:

mutation SendToDestination {
  payment {
    transaction {
      create_send(input: {
        wallet_id: "5e4b1e2a-9f3c-4a5b-8c7d-1234567890ab"
        destination: {
          payment_destination_id: "c2f9d8e1-4b6a-4f3c-9d2e-0987654321fe"
          amount: "50000"
        }
        idempotency_key: "payout-2026-07-03-alice"
      }) {
        id
        status
      }
    }
  }
}

The resulting transaction records the payment_destination_id, so payout history stays linked to the saved destination. See Send Payments for lifecycle, idempotency, and sandbox behavior.

Next steps