Mint Inscriptions Endpoint
Learn how to mint ordinal inscriptions and BSV21 tokens from your Droplit instance.
Mint Inscriptions Endpoint
This endpoint allows you to mint ordinal inscriptions or BSV21 tokens using funds from your Droplit instance. The inscription data is encoded on-chain and sent to the specified recipient address.
- Endpoint:
POST /faucet/{droplitName}/mint- Replace
{droplitName}with the name of your Droplit.
- Replace
- Authentication: Required (see Authentication)
Request Body
The request body must be a JSON object with the following structure:
{
"recipientAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"contentType": "text/plain",
"data": "Hello, Ordinals!",
"encoding": "utf8",
"feeRate": 100,
"broadcast": true,
"bsv21": {
"ticker": "SATS",
"max": "21000000",
"limit": "1000",
"dec": 8
}
}Required Fields
recipientAddress(string): BSV address that will receive the inscription.contentType(string): MIME type of the inscription data.- Examples:
"text/plain","application/json","image/png","application/bsv-20"
- Examples:
data(string): The inscription content. Encoding depends on theencodingfield.
Optional Fields
encoding(string): Encoding format for the data field. Default:"utf8""utf8": UTF-8 text data"base64": Base64-encoded binary data (for images, etc.)"hex": Hex-encoded binary data
feeRate(number): Fee rate in satoshis per kilobyte. Default: 100broadcast(boolean): Whether to broadcast the transaction immediately. Default: truebsv21(object): Optional BSV21 token metadata. Include this to mint a token:ticker(string): Token ticker symbol (e.g., "SATS")max(string): Maximum token supply (use string for large numbers)limit(string): Maximum minting amount per transactiondec(number): Number of decimal places (0-8)
Inscription Types
Text Inscription
Simple text inscriptions for messages, notes, or data:
{
"recipientAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"contentType": "text/plain",
"data": "Hello, Ordinals!",
"encoding": "utf8",
"feeRate": 100,
"broadcast": true
}JSON Inscription
Structured data inscriptions:
{
"recipientAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"contentType": "application/json",
"data": "{\"title\": \"My NFT\", \"description\": \"This is metadata\"}",
"encoding": "utf8",
"feeRate": 100,
"broadcast": true
}Image Inscription
Binary image data must be base64-encoded:
{
"recipientAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"contentType": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
"encoding": "base64",
"feeRate": 100,
"broadcast": true
}BSV21 Token
To mint a BSV21 token, include the bsv21 metadata:
{
"recipientAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"contentType": "application/bsv-20",
"data": "{}",
"encoding": "utf8",
"feeRate": 100,
"broadcast": true,
"bsv21": {
"ticker": "SATS",
"max": "21000000",
"limit": "1000",
"dec": 8
}
}Example: Curl
Replace <YOUR_WIF>, <DROPLIT_NAME>, <GENERATED_AUTH_TOKEN_VALUE>, and <YOUR_DROPLIT_API_URL> with your actual values.
# 1. Define variables
PAYLOAD_BODY='{
"recipientAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"contentType": "text/plain",
"data": "Hello, Ordinals!",
"encoding": "utf8",
"feeRate": 100,
"broadcast": true
}'
PATHNAME_VALUE="/faucet/<DROPLIT_NAME>/mint"
# Note: For the AUTH_TOKEN_VALUE, you need to generate it using a bitcoin-auth library.
# The message to sign is: PATHNAME_VALUE + PAYLOAD_BODY
AUTH_TOKEN_VALUE="<GENERATED_AUTH_TOKEN_VALUE>"
YOUR_DROPLIT_API_URL="http://localhost:8080" # Or your deployed URL
DROPLIT_NAME="your-droplit-name"
# 2. Make the request
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Auth-Token: ${AUTH_TOKEN_VALUE}" \
-d "${PAYLOAD_BODY}" \
${YOUR_DROPLIT_API_URL}/faucet/${DROPLIT_NAME}/mintExample: JavaScript (Node.js using node-fetch and bitcoin-auth)
import fetch from 'node-fetch';
import { AuthConfig, getAuthToken } from 'bitcoin-auth';
async function mintInscription() {
const droplitName = "your-droplit-name"; // Replace
const userWIF = "your-private-key-wif"; // Replace
const droplitApiUrl = "http://localhost:8080"; // Replace with your API URL
const requestPath = `/faucet/${droplitName}/mint`;
const payload = {
recipientAddress: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", // Replace
contentType: "text/plain",
data: "Hello from Droplit!",
encoding: "utf8",
feeRate: 10,
broadcast: true,
};
const bodyString = JSON.stringify(payload);
const authConfig: AuthConfig = {
privateKeyWif: userWIF,
requestPath: requestPath,
body: bodyString,
};
try {
const authToken = await getAuthToken(authConfig);
console.log('Auth Token:', authToken);
const response = await fetch(`${droplitApiUrl}${requestPath}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Auth-Token": authToken,
},
body: bodyString,
});
let responseData;
const contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
responseData = await response.json();
} else {
responseData = await response.text();
}
if (!response.ok) {
console.error('API Error:', responseData);
throw new Error(`HTTP error! Status: ${response.status} - ${responseData}`);
}
console.log("Mint successful:", responseData);
// Expected response includes inscriptionId, txid, fee, etc.
} catch (error) {
console.error("Error minting inscription:", error);
}
}
mintInscription();Example: Minting an Image
import fs from 'fs';
async function mintImage() {
const droplitName = "your-droplit-name";
const userWIF = "your-private-key-wif";
const droplitApiUrl = "http://localhost:8080";
// Read image file and convert to base64
const imageBuffer = fs.readFileSync('./my-image.png');
const base64Image = imageBuffer.toString('base64');
const requestPath = `/faucet/${droplitName}/mint`;
const payload = {
recipientAddress: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
contentType: "image/png",
data: base64Image,
encoding: "base64",
feeRate: 10,
broadcast: true,
};
const bodyString = JSON.stringify(payload);
const authConfig: AuthConfig = {
privateKeyWif: userWIF,
requestPath: requestPath,
body: bodyString,
};
const authToken = await getAuthToken(authConfig);
const response = await fetch(`${droplitApiUrl}${requestPath}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Auth-Token": authToken,
},
body: bodyString,
});
const responseData = await response.json();
console.log("Image inscribed:", responseData);
}Example: Minting a BSV21 Token
async function mintBSV21Token() {
const droplitName = "your-droplit-name";
const userWIF = "your-private-key-wif";
const droplitApiUrl = "http://localhost:8080";
const requestPath = `/faucet/${droplitName}/mint`;
const payload = {
recipientAddress: "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
contentType: "application/bsv-20",
data: JSON.stringify({ description: "My awesome token" }),
encoding: "utf8",
feeRate: 10,
broadcast: true,
bsv21: {
ticker: "MYTOKEN",
max: "1000000",
limit: "100",
dec: 8,
},
};
const bodyString = JSON.stringify(payload);
const authConfig: AuthConfig = {
privateKeyWif: userWIF,
requestPath: requestPath,
body: bodyString,
};
const authToken = await getAuthToken(authConfig);
const response = await fetch(`${droplitApiUrl}${requestPath}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Auth-Token": authToken,
},
body: bodyString,
});
const responseData = await response.json();
console.log("Token minted:", responseData);
}Success Response
On success, the API returns a JSON object with details about the minted inscription:
{
"success": true,
"txid": "abcdef123456...",
"inscriptionId": "abcdef123456..._0",
"outputIndex": 0,
"fee": 150,
"size": 250,
"feeRate": 100,
"broadcasted": true,
"contentType": "text/plain",
"inscriptionSize": 18
}Response Fields
success(boolean): Alwaystrueon successtxid(string): Transaction ID of the inscription transactioninscriptionId(string): Unique inscription identifier (txid + output index)outputIndex(number): Output index containing the inscriptionfee(number): Total transaction fee in satoshissize(number): Transaction size in bytesfeeRate(number): Actual fee rate used (satoshis per byte)broadcasted(boolean): Whether the transaction was broadcast to the networkcontentType(string): MIME type of the inscribed contentinscriptionSize(number): Size of the inscription data in bytes
Error Responses
Common errors include:
400 Bad Request
Invalid request parameters or inscription data:
{
"success": false,
"error": "invalid_request",
"message": "Recipient address is required"
}401 Unauthorized
Missing or invalid authentication token:
{
"success": false,
"error": "unauthorized",
"message": "Invalid or missing X-Auth-Token"
}402 Payment Required
Insufficient balance in Droplit:
{
"success": false,
"error": "insufficient_funds",
"message": "Not enough balance to mint inscription",
"details": {
"availableSatoshis": 1000,
"requiredSatoshis": 5000
}
}413 Payload Too Large
Inscription data exceeds size limits:
{
"success": false,
"error": "inscription_too_large",
"message": "Inscription data exceeds maximum size",
"details": {
"inscriptionTooLarge": true,
"maxSize": 500000
}
}422 Unprocessable Entity
Invalid content type or encoding:
{
"success": false,
"error": "invalid_content",
"message": "Invalid content type for inscription",
"details": {
"invalidContentType": true
}
}500 Internal Server Error
Server-side issue during minting:
{
"success": false,
"error": "server_error",
"message": "Failed to create inscription transaction"
}Best Practices
-
Check Balance First: Ensure your Droplit has sufficient funds before minting. Each inscription requires:
- Inscription output (546 satoshis minimum)
- Transaction fees (typically 150-500 satoshis depending on size)
-
Optimize Image Size: For image inscriptions, compress images before uploading:
- Keep images under 500KB for reasonable fees
- Use PNG or WebP for best compression
- Consider reducing resolution for large images
-
Validate JSON: Always validate JSON data before sending to ensure it's properly formatted.
-
Use Appropriate Content Types: Choose the correct MIME type:
- Text:
text/plain - JSON:
application/json - Images:
image/png,image/jpeg,image/webp,image/svg+xml - BSV21 tokens:
application/bsv-20
- Text:
-
Handle Errors Gracefully: Check the
successfield in responses and handle errors appropriately:if (response.success) { console.log(`Inscription created: ${response.inscriptionId}`); } else { console.error(`Error: ${response.message}`); } -
Test with Small Inscriptions: Start with small text inscriptions to verify your setup before minting larger images or tokens.
-
Monitor Transaction Confirmations: After broadcasting, monitor the transaction on a block explorer to ensure it's confirmed on-chain.
Fee Estimation
Inscription fees depend on:
- Inscription Size: Larger content costs more
- Fee Rate: Higher rates get faster confirmation
- Network Conditions: Congestion may require higher fees
Typical fee ranges:
- Small text (< 100 bytes): 150-300 satoshis
- Medium JSON (100-1000 bytes): 300-1500 satoshis
- Large image (10-100KB): 1500-50000 satoshis
- BSV21 token: 500-1000 satoshis
Use the response fee field to track actual costs for budgeting.