Get Started
Five-minute quickstart for the Magma API - buy inbound Lightning liquidity from your first API call to a confirmed channel.
You'll go from zero to a paid order in five minutes. By the end of this guide you'll have priced liquidity, opened a buy order, paid the HODL invoice, and watched the channel confirm.
The API lives at:
https://magma.amboss.tech/graphqlThe buy flow is public - no signup required for one-off purchases. If you want to track your orders later, save the session_key from the response (see step 3) or mint an API key.
Get a node connection string
Magma needs to know where to deliver the channel. The format is pubkey@host:port:
lncli getinfo | jq -r '.uris[0]'
# [email protected]:9735lightning-cli getinfo | jq -r '.id + "@" + (.address[0].address + ":" + (.address[0].port | tostring))'
# [email protected]:9735Tor sockets (*.onion:9735) work too.
Estimate cost
How many satoshis of liquidity will $1 buy right now?
query LiquidityPerUsd {
market {
liquidity {
liquidity_per_usd {
sats
usd
}
}
}
}curl -X POST https://magma.amboss.tech/graphql \
-H "Content-Type: application/json" \
-d '{"query":"query { market { liquidity { liquidity_per_usd { sats usd } } } }"}'import { GraphQLClient, gql } from "graphql-request";
const magma = new GraphQLClient("https://magma.amboss.tech/graphql");
const { market } = await magma.request(gql`
query LiquidityPerUsd {
market {
liquidity {
liquidity_per_usd { sats usd }
}
}
}
`);
console.log(`1 USD = ${market.liquidity.liquidity_per_usd.sats} sats inbound`);{
"data": {
"market": {
"liquidity": {
"liquidity_per_usd": {
"sats": "543260",
"usd": "501.09"
}
}
}
}
}sats is how many satoshis of inbound capacity you get for each USD spent. usd is the expected dollar-receiving capacity per USD spent - at this rate, $1 of fees can earn ~$500 of routed payments.
Place a buy order
Call liquidity.buy with your connection string and the amount in USD cents. Minimum is 500 cents ($5).
mutation BuyLiquidity($input: LiquidityOrderInput!) {
liquidity {
buy(input: $input) {
account { id session_key }
order { transaction_id usd_cents }
payment { lightning_invoice redirect_url }
}
}
}{
"input": {
"connection_uri": "[email protected]:9735",
"usd_cents": "5000"
}
}curl -X POST https://magma.amboss.tech/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation($input: LiquidityOrderInput!) { liquidity { buy(input: $input) { account { id session_key } order { transaction_id usd_cents } payment { lightning_invoice redirect_url } } } }",
"variables": {
"input": { "connection_uri": "[email protected]:9735", "usd_cents": "5000" }
}
}'const BUY = gql`
mutation BuyLiquidity($input: LiquidityOrderInput!) {
liquidity {
buy(input: $input) {
account { id session_key }
order { transaction_id usd_cents }
payment { lightning_invoice redirect_url }
}
}
}
`;
const { liquidity } = await magma.request(BUY, {
input: {
connection_uri: "[email protected]:9735",
usd_cents: "5000",
},
});
console.log("Pay this invoice:", liquidity.buy.payment.lightning_invoice);
console.log("Save this key :", liquidity.buy.account.session_key);The response includes:
payment.lightning_invoice- pay this and the order moves forwardpayment.redirect_url- a BTCPay checkout URL (same invoice, hosted UI)order.transaction_id- use this to track the orderaccount.session_key- your anonymous identity, save it if you want to poll later
session_key is returned once. Persist it the moment you receive it. There is no recovery.
Pay the invoice
Pay payment.lightning_invoice from your Lightning wallet. The order moves from WAITING_FOR_SELLER_APPROVAL → WAITING_FOR_BUYER_PAYMENT → WAITING_FOR_CHANNEL_OPEN automatically once the payment lands.
Track the order
Use your session_key as a Bearer token to poll the order's status. (Or skip this step and just wait for the channel to appear on your node.)
query GetOrder($orderId: String!) {
user {
market {
orders {
get_order(order_id: $orderId) {
id
status
payment_status
channel_id
confirmations { confirmations }
}
}
}
}
}const TERMINAL = new Set([
"VALID_CHANNEL_OPENING",
"CHANNEL_MONITORING_FINISHED",
"SELLER_REJECTED",
"SELLER_FAILED_TO_REACT",
"BUYER_REJECTED",
"BUYER_FAILED_TO_PAY",
"SELLER_FAILED_TO_OPEN_CHANNEL",
"SELLER_FAILED_TO_SEND_SWAP",
"INVALID_CHANNEL_OPENING",
"ADMIN_CLOSED",
]);
const authed = new GraphQLClient("https://magma.amboss.tech/graphql", {
headers: { Authorization: `Bearer ${sessionKey}` },
});
while (true) {
const { user } = await authed.request(GET_ORDER, { orderId });
const order = user.market.orders.get_order;
console.log(order.status, order.payment_status);
if (TERMINAL.has(order.status)) break;
await new Promise((r) => setTimeout(r, 10_000));
}When you hit VALID_CHANNEL_OPENING, the channel is live and routable.
What just happened
The seller's invoice is a HODL invoice - funds are held in escrow until the channel is confirmed on chain. If the seller fails to open the channel, the payment is refunded automatically. See Liquidity Marketplace for the details.