Send Bitcoin On-Chain

Send Bitcoin from your Neutron wallet to an external Bitcoin address via on-chain transaction.

Overview

Your Neutron Wallet  ──►  Neutron  ──BTC on-chain──►  External Wallet

Use case: Withdrawing Bitcoin to a hardware wallet, exchange, or any external Bitcoin address.

📘

Prefer Lightning? On-chain sends incur network fees and require confirmations. For instant, low-fee transfers, use Lightning send instead.

Flow

  1. Create the transaction with the destination Bitcoin address — returns a quote with fees
  2. Review the fees in the quoted response
  3. Confirm the transaction — Neutron broadcasts to the Bitcoin network
  4. Wait for blockchain confirmations
  5. Receive webhook notification when complete (if configured)

Step 1: Create Transaction

curl -X POST https://api.neutron.me/api/v2/transaction \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "sourceReq": {
      "ccy": "BTC",
      "method": "neutronpay"
    },
    "destReq": {
      "ccy": "BTC",
      "method": "on-chain",
      "amtRequested": 0.001,
      "reqDetails": {
        "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
      }
    }
  }'

Request Fields

FieldTypeRequiredDescription
sourceReq.ccystring"BTC"
sourceReq.methodstring"neutronpay" (from your wallet)
destReq.ccystring"BTC"
destReq.methodstring"on-chain"
destReq.amtRequestednumberAmount in BTC (e.g., 0.001 = 100,000 sats)
destReq.reqDetails.addressstringDestination Bitcoin address
extRefIdstringYour reference ID — returned in webhooks
⚠️

Amounts are in BTC, not satoshis. 0.00000100 = 100 sats.

⚠️

Set the amount on one side only (source OR dest), not both.

⚠️

Minimum send amount: 0.00001 BTC (1,000 sats). Amounts below this will be rejected.

Supported Address Formats

FormatExample prefixDescription
Bech32 (SegWit)bc1q...Recommended — lowest fees
Bech32m (Taproot)bc1p...Taproot addresses
P2SH3...Wrapped SegWit
Legacy1...Legacy format — higher fees

Response

{
  "txnId": "d5a2c7b4-3456-4def-8901-abcdef123456",
  "accountId": "ne01-abc123def456",
  "txnState": "quoted",
  "sourceReq": {
    "ccy": "BTC",
    "method": "neutronpay",
    "amtRequested": 0.001,
    "neutronpayFees": 0.0000015,
    "networkFees": 0.0000045,
    "reqStatus": "0",
    "createAt": 1770342000000
  },
  "destReq": {
    "ccy": "BTC",
    "method": "on-chain",
    "amtRequested": 0.001,
    "reqStatus": "0",
    "reqDetails": {
      "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
    }
  },
  "fxRate": 1,
  "createdAt": 1770342000000
}

Review the fee breakdown in sourceReq before confirming:

FieldDescription
neutronpayFeesNeutron's service fee
networkFeesBitcoin network mining fee
Total deductedamtRequested + neutronpayFees + networkFees

Step 2: Confirm Transaction

After reviewing fees, confirm to broadcast:

curl -X PUT https://api.neutron.me/api/v2/transaction/d5a2c7b4-3456-4def-8901-abcdef123456/confirm \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
⚠️

The Content-Type: application/json header is required on PUT requests, even with no request body.

After confirmation, Neutron deducts the amount + fees from your wallet and broadcasts the transaction to the Bitcoin network.

SDK Examples

TypeScript (neutron-sdk)

import { Neutron } from "neutron-sdk";

const neutron = new Neutron({
  apiKey: process.env.NEUTRON_API_KEY,
  apiSecret: process.env.NEUTRON_API_SECRET,
});

// Create on-chain send
const txn = await neutron.transactions.create({
  sourceReq: { ccy: "BTC", method: "neutronpay" },
  destReq: {
    ccy: "BTC",
    method: "on-chain",
    amtRequested: 0.001,
    reqDetails: { address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh" },
  },
});

// Review fees
console.log("Neutron fee:", txn.sourceReq.neutronpayFees);
console.log("Network fee:", txn.sourceReq.networkFees);

// Confirm to broadcast
await neutron.transactions.confirm(txn.txnId);

Python (neutron-python)

from neutron import Neutron

client = Neutron(api_key="...", api_secret="...")

# Create on-chain send
txn = client.transactions.create({
    "sourceReq": {"ccy": "BTC", "method": "neutronpay"},
    "destReq": {
        "ccy": "BTC",
        "method": "on-chain",
        "amtRequested": 0.001,
        "reqDetails": {"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"},
    },
})

# Review fees
print("Neutron fee:", txn["sourceReq"]["neutronpayFees"])
print("Network fee:", txn["sourceReq"]["networkFees"])

# Confirm to broadcast
client.transactions.confirm(txn["txnId"])

Transaction States

StateMeaning
quotedTransaction created — review fees before confirming
srccreatedFunds deducted from wallet
destsentBitcoin transaction broadcast to the network
completedTransaction confirmed on-chain ✅
failedTransaction failed (e.g., insufficient balance)

See Transaction Status Types for the complete state reference.

Fees

On-chain sends include two fee components:

FeeDescription
Neutron feeService fee charged by Neutron
Network feeBitcoin mining fee — varies with network congestion

Both are shown in the quoted response before you confirm. The total deducted from your wallet is amtRequested + neutronpayFees + networkFees.

Notes

  • No KYC required for Bitcoin on-chain transactions. KYC is only needed for fiat payouts.
  • Ensure sufficient wallet balance to cover the amount plus fees before confirming.
  • On-chain transactions are irreversible once broadcast. Double-check the destination address.
  • Minimum send amount: 0.00001 BTC (1,000 sats).
  • Transaction speed depends on network congestion. Neutron selects an appropriate fee rate for timely confirmation.
  • Amounts are always in BTC, not satoshis (100 sats = 0.00000100).

Related