RGB Operations
Complete reference for RGB asset operations on the node. All paths carry the /api/v1 prefix. Asset quantities are raw asset units; BTC-related fields use _sats for satoshis.
RGB wallet and addresses
POST /api/v1/rgb/address/new
Generate a new RGB wallet receiving address (advances the RGB derivation index).
Response:
{
"address": "tb1q..."
}GET /api/v1/rgb/address/current
Return the most recently generated RGB address without advancing the derivation index. Returns 404 when the node has not initialized an RGB address yet.
Response: same as rgb/address/new.
GET /api/v1/rgb/descriptor
Get the RGB wallet descriptor.
Response:
{
"descriptor": "wpkh([fingerprint/84'/1'/0']xpub.../0/*)",
"derived_descriptors": [
{
"fingerprint": "a1b2c3d4",
"derivation_path": "m/84'/1'/0'",
"xpub": "xpub6...",
"descriptor": "wpkh([a1b2c3d4/84'/1'/0']xpub6.../0/*)"
}
]
}derived_descriptors is optional.
POST /api/v1/rgb/sign_message
Sign a message with the RGB wallet key.
Request:
{
"message": "hello",
"algorithm": "bitcoin_signed_message",
"encoding": "hex",
"compact": false
}algorithm is bitcoin_signed_message or ecdsa; encoding is hex or base64; all three are optional.
Response:
{
"message": "hello",
"algorithm": "bitcoin_signed_message",
"signature": "3045...",
"pubkey": "02def456...",
"derivation_path": "m/84'/1'/0'/0/0",
"digest_hex": "abc123...",
"encoding": "hex",
"compact": false
}POST /api/v1/rgb/sync
Synchronize RGB runtime state.
Response:
{ "ok": true }RGB UTXO queries
GET /api/v1/rgb/utxos
List the RGB wallet domain's colorable carrier UTXOs, including confirmation, lock state and RGB allocations.
Query parameter: refresh=true reconciles confirmation heights with the indexer first. Only an explicit refresh updates confirmation heights; /rgb/sync and /wallet/sync do not refresh this domain.
Response:
{
"utxos": [
{
"outpoint": "txid:1",
"value_sats": "10000",
"confirmation": { "status": "confirmed", "height": 250000 },
"lock": { "locked": false, "kind": "none", "operation_id": null },
"rgb": {
"allocations": [
{ "contract_id": "contract:...", "amount": "1000", "layer": "base" }
],
"has_mixed_asset_allocations": false,
"spend_roles": ["rgb-state"]
}
}
]
}Field notes:
value_sats: BTC amount of the carrier UTXO (sats)confirmation.status:confirmedormempoollock.kind:none,manual_reservationoroperationrgb.allocations[].layer: RGB state layer, e.g.base,active,pendingrgb.has_mixed_asset_allocations: whether the UTXO carries allocations from multiple contractsrgb.spend_roles: roles this UTXO can take, e.g.rgb-state,fee-support
GET /api/v1/rgb/utxos/summary
Return a summary of the RGB wallet domain's colorable carrier UTXOs with confirmation heights, for quickly totalling available and occupied capacity.
Query parameter: refresh=true runs a local reconcile first.
Response:
{
"utxos": [
{
"outpoint": "txid:1",
"value_sats": "10000",
"confirmed_height": 250000,
"reserved": false,
"reserved_until_unix_secs": "1704067200",
"assets": [
{ "contract_id": "contract:...", "amount": "1000" }
]
}
]
}Capacity operations
RGB on-chain transfers and RGB channels both need colorable carrier UTXOs. These endpoints prepare and reclaim carrier capacity with explicit inputs and outputs and no automatic coin selection.
POST /api/v1/rgb/utxos/fund
Create dedicated RGB wallet UTXOs from plain BTC wallet inputs.
Request:
{
"inputs": [
{ "outpoint": "txid:0" }
],
"outputs": [
{ "address": "tb1q...", "value_sats": "10000" }
],
"change_address": "tb1q...",
"fee_rate_sats_per_vb": 1.5
}Parameter notes:
inputs: plain BTC inputs fromGET /wallet/utxosoutputs: RGB wallet outputs to create; addresses fromPOST /rgb/address/newchange_address: change address fromPOST /wallet/address/new, must differ from all RGB output scriptsfee_rate_sats_per_vb: positive fee rate (sats/vB)
Response:
{
"txid": "abc123...",
"status": "broadcast",
"outputs": [
{ "address": "tb1q...", "value_sats": "10000", "vout": 1 }
],
"fee_sats": "500",
"change": { "address": "tb1q...", "value_sats": "89000", "vout": 2 }
}status reports the transaction's current state (signed and handed to the broadcaster). change is optional.
POST /api/v1/rgb/utxos/top_up
Expand an existing RGB UTXO without creating a new one (replacement transfer).
Request:
{
"rgb_input": { "outpoint": "txid:1" },
"l1_inputs": [
{ "outpoint": "txid:0" }
],
"rgb_output": { "address": "tb1q...", "target_value_sats": "20000" },
"change_address": "tb1q...",
"fee_rate_sats_per_vb": 1.5
}rgb_output.target_value_sats must exceed the old RGB UTXO's BTC value.
Response:
{
"txid": "abc123...",
"status": "broadcast",
"old_outpoint": "txid:1",
"new_rgb_output": { "address": "tb1q...", "value_sats": "20000", "vout": 1 },
"fee_sats": "600",
"consignment_key": "consign_abc123",
"change": { "address": "tb1q...", "value_sats": "78000", "vout": 2 }
}POST /api/v1/rgb/utxos/sweep
Reclaim empty RGB UTXOs with no RGB allocations and sweep the BTC back to the plain BTC wallet, reducing fragmentation and locked funds.
Request:
{
"input": { "outpoint": "txid:1" },
"destination_address": "tb1q...",
"fee_rate_sats_per_vb": 1.5
}Response:
{
"txid": "abc123...",
"status": "broadcast",
"input": { "outpoint": "txid:1" },
"destination": { "address": "tb1q...", "value_sats": "9400", "vout": 0 },
"fee_sats": "600"
}Releasing a UTXO reservation (POST /rgb/utxos/release) and single-outpoint status lookup are in UTXO management.
RGB contracts
GET /api/v1/rgb/contracts
List RGB contracts known to the node.
Response:
{
"contracts": [
{
"contract_id": "contract:...",
"name": "Example Asset",
"ticker": "EXA",
"precision": 8,
"issued_supply": "1000000",
"details": "optional note"
}
]
}name, ticker, precision, issued_supply and details are optional.
GET /api/v1/rgb/contract/{contract_id}/balance
Query one contract's balance. Returns 404 (ContractNotFound) when the contract is not imported locally.
Response:
{
"contract_id": "contract:...",
"balance": {
"mined": "1000",
"tentative": "0",
"offchain": "500",
"archived": "0",
"total": "1500"
}
}GET /api/v1/rgb/contract/{contract_id}/known
Check whether a contract is known locally.
Response:
{
"contract_id": "contract:...",
"known": true
}POST /api/v1/rgb/contracts/issue
Issue a new RGB asset.
Request:
{
"issuer_name": "example-issuer",
"contract_name": "Example Asset",
"ticker": "EXA",
"precision": 8,
"issued_supply": "1000000",
"utxo": "txid:0"
}ticker, precision and utxo are optional; utxo pins the issuance carrier outpoint.
Response:
{
"ok": true,
"contract_id": "contract:...",
"issued_supply": "1000000"
}POST /api/v1/rgb/contracts/export
Export a contract.
Request:
{
"contract_id": "contract:..."
}Response:
{
"ok": true,
"contract_id": "contract:...",
"consignment_key": "consign_abc123"
}POST /api/v1/rgb/contracts/import
Import a contract file. The body is a binary archive (Content-Type: application/octet-stream); contract and format come from query parameters.
Query parameters: contract_id=<contract id>, format=zip|raw (a ZIP archive starts with PK\x03\x04, otherwise raw).
Response:
{
"ok": true,
"contract_id": "contract:...",
"consignment_key": "consign_abc123"
}RGB issuers
GET /api/v1/rgb/issuers
List valid issuer names in the local issuer registry.
Response:
{
"issuers": ["example-issuer"],
"invalid_issuers": [
{ "name": "broken-issuer", "error": "failed to parse" }
]
}invalid_issuers is optional and lists issuer files that failed to load during a scan.
POST /api/v1/rgb/issuers/import
Import an issuer file. The body is raw binary (Content-Type: application/octet-stream).
Query parameters: name=<issuer name>, format=raw.
Response:
{
"ok": true,
"issuer_name": "example-issuer"
}RGB Lightning payments
POST /api/v1/rgb/ln/invoice/create
Create an RGB Lightning invoice.
Request:
{
"contract_id": "contract:...",
"asset_amount": "100",
"description": "RGB payment",
"expiry_secs": 3600,
"btc_carrier_amount_msat": "3000000"
}expiry_secs and btc_carrier_amount_msat are optional; when the carrier amount is omitted the node calculates and lifts it automatically.
Response:
{
"invoice": "lnbcrt1...",
"btc_carrier_amount_msat": "3000000"
}btc_carrier_amount_msat is the carrier amount actually embedded in the invoice and may be higher than requested.
POST /api/v1/rgb/ln/invoice/create_for_hash
Create an RGB Lightning invoice with a specified payment_hash.
Request:
{
"contract_id": "contract:...",
"asset_amount": "100",
"payment_hash": "abc123...",
"description": "RGB payment",
"expiry_secs": 3600
}Response: same as rgb/ln/invoice/create.
POST /api/v1/rgb/ln/invoice/decode
Decode an RGB Lightning invoice.
Request:
{
"invoice": "lnbcrt1..."
}Response:
{
"payment_hash": "abc123...",
"destination": "02def456...",
"carrier_amount_msat": "3000000",
"expiry_secs": "3600",
"contract_id": "contract:...",
"asset_amount": "100"
}carrier_amount_msat, contract_id and asset_amount are optional.
POST /api/v1/rgb/ln/invoice/estimate_carrier
Estimate the BTC carrier amount needed to create an RGB Lightning invoice. This is a non-binding snapshot estimate and does not change node state.
Request:
{
"contract_id": "contract:...",
"asset_amount": "100",
"description": "RGB payment",
"expiry_secs": 3600
}Response:
{
"receive_available": true,
"can_create_rgb_invoice": true,
"minimum_viable_carrier_amount_msat": "3000000",
"minimum_viable_reason": "...",
"default_create_carrier_amount_msat": "3000000",
"default_create_reason": "...",
"carrier_admission_threshold_msat": "...",
"minimum_allowed_carrier_amount_msat": "...",
"holder_reserve_threshold_msat": "...",
"channels": [
{
"channel_id": "abc123...",
"user_channel_id": "user_abc123",
"is_usable": true,
"inbound_capacity_msat": "500000000",
"inbound_htlc_minimum_msat": "1000",
"inbound_htlc_maximum_msat": "490000000",
"local_balance_output_sats": "200000",
"has_holder_reserve": true,
"receive_available": true,
"can_receive_rgb_invoice": true,
"blocking_reason": null,
"minimum_viable_carrier_amount_msat": "3000000",
"default_create_carrier_amount_msat": "3000000",
"required_carrier_msat": null,
"suggested_action": null
}
],
"estimate_only": true,
"warning": "",
"blocking_reason": null,
"required_carrier_msat": null,
"suggested_action": null
}channels is a snapshot of each channel's carrier receive capacity at that moment.
POST /api/v1/rgb/ln/pay
Pay an RGB Lightning invoice.
Request:
{
"invoice": "lnbcrt1...",
"contract_id": "contract:...",
"asset_amount": "100"
}contract_id and asset_amount are optional and usually derived from the invoice.
Response:
{
"payment_id": "pay_abc123"
}Whether the payment succeeds is determined by GET /payment/{paymentId} under payment status. An RGB payment consumes both the RGB asset and the BTC carrier on the same channel; before paying, confirm that contract channel's local asset balance and outbound capacity.
RGB on-chain transfers
POST /api/v1/rgb/onchain/invoice/create
Create an RGB on-chain invoice.
Request:
{
"contract_id": "contract:...",
"amount": "1000",
"expiry_secs": "86400",
"use_witness_utxo": true,
"nonce": "0",
"blinding_utxo": "txid:0"
}All fields except contract_id and amount are optional.
Response:
{
"invoice": "rgb:tb1q.../12345",
"blinding_utxo_used": "txid:0"
}blinding_utxo_used is optional.
POST /api/v1/rgb/onchain/invoice/decode
Decode an RGB on-chain invoice.
Request:
{
"invoice": "rgb:tb1q.../12345"
}Response:
{
"contract_id": "contract:...",
"amount": "1000",
"beneficiary": "tb1q...",
"use_witness_utxo": true,
"expiry_unix_secs": "1704067200"
}POST /api/v1/rgb/onchain/send
Send RGB assets on-chain per an invoice.
Request:
{
"invoice": "rgb:tb1q.../12345",
"sats_for_fee_and_outputs": "1000",
"fee_rate_sats_per_vb": 1.5
}sats_for_fee_and_outputs is optional and overrides the BTC amount for fees and outputs.
Response:
{
"txid": "abc123...",
"consignment_key": "consign_abc123"
}POST /api/v1/rgb/onchain/receive
Receive an RGB consignment.
Request:
{
"consignment_key": "consign_abc123",
"payment_id": "pay_abc123",
"invoice": "rgb:tb1q.../12345"
}You can also submit the archive as raw binary: POST /api/v1/rgb/onchain/receive?format=zip&payment_id=<id> with the archive bytes and Content-Type: application/octet-stream.
Response:
{
"contract_id": "contract:...",
"amount": "1000"
}GET /api/v1/rgb/onchain/payments
List RGB on-chain payment records.
Response:
{
"payments": [
{
"id": "pay_abc123",
"kind": "...",
"status": "...",
"created_at_unix_secs": "1704067200",
"latest_update_timestamp": "1704067200",
"expires_at_unix_secs": "1704067200",
"invoice": "rgb:tb1q.../12345",
"contract_id": "contract:...",
"amount": "1000",
"txid": "abc123...",
"consignment_key": "consign_abc123",
"consignment_download_path": "/api/v1/rgb/consignments/consign_abc123",
"purpose": null
}
]
}purpose is an internal maintenance marker (utxo_merge / utxo_top_up) and is empty for ordinary user-initiated payments.
GET /api/v1/rgb/consignments/
Download a consignment.
Query parameter: format=raw|gzip|zip (default raw).
Response: a binary archive stream. When opening an RGB channel, the rgb.color_context_data download URL uses this endpoint's template form .../rgb/consignments/{txid}?format=zip.
Error handling
400: invalid RGB data or parameters404: asset, contract or consignment not found409: insufficient RGB asset balance422: consignment validation failed500: RGB operation failed503: node not ready or still syncing
An RGB on-chain send may already have committed RGB state before returning 4xx, so node state may have changed; after a failure, re-read balances and UTXOs instead of retrying blindly.
Examples
Issue a new RGB asset
curl -X POST https://<your-node-domain>/api/v1/rgb/contracts/issue \
-H "Authorization: Bearer <node-credential>" \
-H "Content-Type: application/json" \
-d '{
"issuer_name": "example-issuer",
"contract_name": "My Token",
"ticker": "TEST",
"precision": 8,
"issued_supply": "1000000"
}'Create an RGB Lightning invoice
curl -X POST https://<your-node-domain>/api/v1/rgb/ln/invoice/create \
-H "Authorization: Bearer <node-credential>" \
-H "Content-Type: application/json" \
-d '{
"contract_id": "contract:...",
"asset_amount": "100",
"description": "RGB payment",
"expiry_secs": 3600
}'RGB on-chain transfer
curl -X POST https://<your-node-domain>/api/v1/rgb/onchain/send \
-H "Authorization: Bearer <node-credential>" \
-H "Content-Type: application/json" \
-d '{
"invoice": "rgb:tb1q.../12345",
"fee_rate_sats_per_vb": 2.0
}'