UniSat Inscribe API provides complete Bitcoin inscription services, supporting standard inscriptions and various protocol templates (BRC-20, Runes, etc.). This document provides detailed instructions on how to use the Inscribe API to create orders, make payments, and track order status.
The basic inscription order process is as follows:
Create Order โ Payment โ Order Processing โ Inscription Complete
โ โ โ โ
pending โ pending โ inscribing โ minted
Use the POST /v2/inscribe/order/create endpoint to create a basic inscription order.
| Parameter | Type | Required | Description |
|---|---|---|---|
| receiveAddress | string | Yes | Bitcoin address to receive the inscription |
| feeRate | number | Yes | Transaction fee rate (sat/vB) |
| outputValue | integer | Yes | UTXO amount for each inscription (usually 546 sats) |
| files | array | Yes | List of files to inscribe |
| devAddress | string | No | Developer address (for collecting additional fees) |
| devFee | integer | No | Developer fee (sats) |
curl -X POST "https://open-api.unisat.io/v2/inscribe/order/create" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"receiveAddress": "bc1p...",
"feeRate": 10,
"outputValue": 546,
"files": [
{
"filename": "hello.txt",
"dataURL": "data:text/plain;charset=utf-8;base64,SGVsbG8gV29ybGQ="
}
]
}'
After creating an order, you need to pay the amount of sats to the payAddress in the response.
Payment amount calculation:
amount = outputValue ร fileCount + networkSats + serviceFee + devFee
For detailed fee calculation, please refer to:
pending โ Pending payment
payment_success โ Payment successful
inscribing โ Inscribing (transaction broadcasted)
minted โ Inscription complete (transaction confirmed)
Use GET /v2/inscribe/order/{orderId} to query the latest order status.
Recommendation: Query order status every 10 seconds
curl -X GET "https://open-api.unisat.io/v2/inscribe/order/{orderId}" \
-H "Authorization: Bearer YOUR_API_KEY"
BRC-20 is the most popular token protocol on Bitcoin. UniSat supports three different types of BRC-20 tokens:
| Protocol Type | Ticker Length | Deploy Method | Minting Permission | Use Cases |
|---|---|---|---|---|
| 4-byte | 4 characters | Standard payment | Anyone can mint | Fair launch, community |
| 5-byte | 5 characters | Standard payment | Deployer only | Project tokens, controlled |
| 6-byte | 6 characters | PSBT signing | Configurable (self_mint) | Timed launch, permissions |
Most commonly used BRC-20 token type:
ordi, sats)Authorized 5-character tokens:
pizza, names)6-character token deployment method:
self_mint to configure minting permissionsโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Need fair launch? โ
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโ
โ
Yes โโดโ No
โ โ
4-byte Need minting control?
Standard โ
Yes โโดโ No
โ โ
5-byte Need 6-char or timed activation?
Authorized โ
Yes โโดโ No
โ โ
6-byte Choose simplest
Protocol 4-byte
Runes is another token protocol on Bitcoin that uses OP_RETURN to store data, more efficient and natively supports the UTXO model.
POST /v2/inscribe/order/create/runes-etch
curl -X POST "https://open-api.unisat.io/v2/inscribe/order/create/runes-etch" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"receiveAddress": "bc1p...",
"feeRate": 50,
"outputValue": 546,
"files": [{
"filename": "logo.png",
"dataURL": "data:image/png;base64,...",
"runes_etch": {
"etching": {
"spacedRune": "MYโขRUNE",
"symbol": "M",
"divisibility": 8,
"premine": "1000000",
"terms": {
"amount": "100",
"cap": "21000000",
"height": [840000, 1000000]
}
}
}
}]
}'
Complete Runes Etch parameter descriptions and configuration details:
POST /v2/inscribe/order/create/runes-mint
curl -X POST "https://open-api.unisat.io/v2/inscribe/order/create/runes-mint" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"receiveAddress": "bc1p...",
"feeRate": 30,
"outputValue": 546,
"runeid": "840000:1",
"count": 5
}'
block:tx840000:1 = Transaction 1 in block 840000Complete Runes Mint parameter descriptions:
GET /v2/inscribe/order/list
curl -X GET "https://open-api.unisat.io/v2/inscribe/order/list?cursor=0&size=20&status=minted" \
-H "Authorization: Bearer YOUR_API_KEY"
GET /v2/inscribe/order/summary
Get order statistics for the current API Key (total, pending, inscribing, minted, etc.).
POST /v2/inscribe/order/{orderId}/refund
When an order has issues (such as payment containing inscriptions, incorrect payment amount, etc.), you can request a refund.
Fee = 0Fee = min(3000 + (n - 20) ร 150, 4999)Detailed fee rules:
Q: How long after payment does inscription start?
Q: What happens if I pay the wrong amount?
payment_notenough, need to make up the differencepayment_overpay, can choose to continue or refundQ: Which BRC-20 protocol should I choose?
Q: Whatโs the difference between Runes and BRC-20?
Q: How to get an API Key?
Q: Is a test environment available?
https://open-api-testnet.unisat.iohttps://open-api-signet.unisat.io| Network | Base URL |
|---|---|
| Bitcoin Mainnet | https://open-api.unisat.io |
| Bitcoin Testnet | https://open-api-testnet.unisat.io |
| Bitcoin Testnet4 | https://open-api-testnet4.unisat.io |
| Bitcoin Signet | https://open-api-signet.unisat.io |
| Fractal Mainnet | https://open-api-fractal.unisat.io |
| Fractal Testnet | https://open-api-fractal-testnet.unisat.io |
async function createOrder(params) {
try {
const response = await fetch(
"https://open-api.unisat.io/v2/inscribe/order/create",
{
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(params),
}
);
const data = await response.json();
if (data.code === 0) {
return data.data;
} else {
throw new Error(data.msg);
}
} catch (error) {
console.error("Failed to create order:", error);
throw error;
}
}
async function pollOrderStatus(orderId, maxAttempts = 60) {
for (let i = 0; i < maxAttempts; i++) {
const order = await getOrder(orderId);
if (order.status === "minted") {
console.log("Inscription complete!");
return order;
} else if (order.status === "closed" || order.status === "refunded") {
throw new Error(`Order error: ${order.status}`);
}
// Wait 10 seconds before next query
await new Promise((resolve) => setTimeout(resolve, 10000));
}
throw new Error("Order timeout");
}
function estimateTotalCost(fileCount, fileSize, feeRate) {
// 1. UTXO cost
const minUtxoTotal = 546 * fileCount;
// 2. Network fees (simplified estimate)
const avgTxSize = 200 + fileSize;
const networkSats = avgTxSize * feeRate;
// 3. Service fee
let serviceFee = 0;
if (fileCount > 20) {
serviceFee = Math.min(3000 + (fileCount - 20) * 150, 4999);
}
// 4. Total cost
const total = minUtxoTotal + networkSats + serviceFee;
return {
minUtxoTotal,
networkSats,
serviceFee,
total,
};
}
For any questions or suggestions, please contact the UniSat team!