Quick Start Guide - Accept Monero Payments in 10 Minutes
https://libremonero.com/api/v1
✅ HTTPS only | 🌍 Production ready | ⚡ ~10s detection time
First, register your merchant account programmatically:
curl -X POST https://libremonero.com/api/v1/merchant/register \
-H "Content-Type: application/json" \
-d '{
"merchant_name": "My Coffee Shop",
"primary_address": "44CgjoCp3bGWm8BxUCcGQ8ZA6MDxjm261jQ7nswEembGYBcqbmgENepD4sPcLXfRueiRhejRjD2NaR2KjoCPYR3m5FZwTD8",
"view_key": "93a058fd1ca3aaa09d23486b4b571ca0cf69e037baa70ccba8dead2d53d3600d",
"webhook_url": "https://yoursite.com/webhook"
}'
Expected Response:
{
"merchant_id": "701c07c2-0eb1-433f-8554-66ce431b07c1",
"api_key": "sk_live_6b3cf24b6f43bc46846458de8595f2f5",
"message": "Merchant registered successfully. Save your API key securely - it won't be shown again."
}
⚠️ Save the API key! You'll need it for all future requests.
💡 Alternative: Use the web interface at /merchant
Generate a unique Monero subaddress for your customer:
curl -X POST https://libremonero.com/api/v1/address/create \
-H "Content-Type: application/json" \
-H "X-API-Key: sk_live_6b3cf24b6f43bc46846458de8595f2f5" \
-d '{
"amount": 0.05,
"order_id": "order_123",
"metadata": {"customer_id": "user_456"}
}'
Expected Response:
{
"payment_id": "5958d3f2-f922-43d9-9f71-c84257ac76d7",
"subaddress": "85f4yFQznHcbJFzxCBYBNmfY4WdFuobsfNbw6LEeYAdjKCK5o7knjWC2debWh1c4QR2p5wbZgpx6WCLen3fsVUCN6XxfqL3",
"subaddress_index": 5,
"amount": 0.05,
"expires_at": "2025-12-18T23:26:08.703693Z"
}
Display the subaddress and generate a QR code. Customer sends exactly 0.05 XMR to this address.
💡 QR Code format: monero:SUBADDRESS?tx_amount=0.05
Poll for payment status or wait for webhook:
curl https://libremonero.com/api/v1/payment/status/5958d3f2-f922-43d9-9f71-c84257ac76d7 \
-H "X-API-Key: sk_live_6b3cf24b6f43bc46846458de8595f2f5"
Response when detected:
{
"payment_id": "5958d3f2-f922-43d9-9f71-c84257ac76d7",
"status": "detected",
"confirmations": 0,
"amount": 0.05,
"expected_amount": 0.05,
"within_tolerance": true,
"txid": "abc123...",
"created_at": "2025-12-18T22:26:08Z"
}
When payment is detected (~10 seconds), we POST to your webhook URL:
{
"event": "payment.detected",
"payment_id": "5958d3f2-f922-43d9-9f71-c84257ac76d7",
"merchant_id": "701c07c2-0eb1-433f-8554-66ce431b07c1",
"status": "detected",
"subaddress": "85f4yFQzn...",
"expected_amount": 0.05,
"actual_amount": 0.05,
"txid": "abc123...",
"confirmations": 0,
"order_id": "order_123",
"metadata": {"customer_id": "user_456"}
}
✅ Verify webhook signature using HMAC-SHA256 with your webhook_secret
POST /api/v1/address/create
Headers:
Content-Type: application/json
X-API-Key: YOUR_API_KEY
Request Body:
{
"amount": 0.05, // XMR amount (optional)
"order_id": "order_123", // Your order reference
"metadata": {} // Optional custom data
}
Response:
{
"payment_id": "uuid",
"subaddress": "8...",
"amount": 0.05,
"expires_at": "2025-12-16T12:00:00Z"
}
GET /api/v1/payment/{payment_id}/status
Headers:
X-API-Key: YOUR_API_KEY
Response:
{
"payment_id": "uuid",
"status": "detected", // pending, detected, confirming, confirmed
"confirmations": 3,
"amount": 0.05,
"txid": "..."
}
GET /api/v1/payment/{payment_id}/status/public
Same as above but doesn't require API key (for customer-facing pages).
When a payment is detected, we POST to your webhook URL:
{
"payment_id": "uuid",
"status": "detected",
"amount": 0.05,
"confirmations": 0,
"txid": "...",
"subaddress": "8...",
"order_id": "order_123",
"metadata": {}
}
| Status | Description | Action |
|---|---|---|
detected |
Payment seen in mempool (0 confirmations) | Show "Payment received, confirming..." |
confirming |
1-9 confirmations | Wait for full confirmation |
confirmed |
10+ confirmations | ✅ Deliver product/service |
underpaid |
Amount too low | Request additional payment |
overpaid |
Amount too high | Accept (within tolerance) |
| Feature | Free | Pro | Enterprise |
|---|---|---|---|
| Detections/day | 20 | 5,000 | Unlimited |
| Detections/month | 300 | 100,000 | Unlimited |
| API requests/month | 30,000 | 1,000,000 | Unlimited |
| Detection speed | 5-10 sec | 3 sec | <1 sec |
| Wallet | Shared pool | Dedicated | Multiple |
| Price | €0 | €8/mo | Contact us |
import requests
API_KEY = "sk_live_..."
BASE_URL = "https://libremonero.com/api/v1"
# Create payment
response = requests.post(
f"{BASE_URL}/address/create",
headers={
"Content-Type": "application/json",
"X-API-Key": API_KEY
},
json={
"amount": 0.05,
"order_id": "order_123"
}
)
payment = response.json()
print(f"Pay to: {payment['subaddress']}")
print(f"Amount: {payment['amount']} XMR")
const API_KEY = "sk_live_...";
const BASE_URL = "https://libremonero.com/api/v1";
// Create payment
const response = await fetch(`${BASE_URL}/address/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
},
body: JSON.stringify({
amount: 0.05,
order_id: 'order_123'
})
});
const payment = await response.json();
console.log(`Pay to: ${payment.subaddress}`);
console.log(`Amount: ${payment.amount} XMR`);
$api_key = "sk_live_...";
$base_url = "https://libremonero.com/api/v1";
// Create payment
$ch = curl_init("$base_url/address/create");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"X-API-Key: $api_key"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'amount' => 0.05,
'order_id' => 'order_123'
]));
$response = curl_exec($ch);
$payment = json_decode($response);
echo "Pay to: " . $payment->subaddress . "\n";
echo "Amount: " . $payment->amount . " XMR\n";