API Reference
boleto.eth is a Web3 ticketing protocol that issues permanent ENS subdomain identities and ERC-721 NFT tickets for events. Platforms integrate via REST API — no smart contract knowledge required.
Base URL
https://boleto-api-production.up.railway.app
Authentication
Protected endpoints require an API key in the Authorization header. API keys are issued automatically when you activate your first event — one key per promoter wallet.
Authorization: Bearer blt_your_api_key_here
Save your API key
Your API key is only shown once when you activate your first event. Store it securely. If lost, contact support with your promoter wallet address.
Smart Contracts
BoletoTickets (Ethereum Mainnet)
0x9650d442779368e0A039351eD7c75c3E93de372D
Platform Treasury
0x0104c88ea4f55c26df89f5cd3ec62f3c8288d69b
mintWithVoucher() — buyer self-mint
// Solidity interface function mintWithVoucher( bytes32 eventId, // from /voucher response address to, // buyer wallet string seatNumber, // from /voucher response string tokenUri, // from /voucher response bytes signature // from /voucher response ) external
Endpoints
NFT Metadata
Each ticket NFT follows the OpenSea metadata standard. Metadata is generated and pinned to IPFS automatically when the first voucher or mint is requested for a seat. All CSV columns you provide at event creation are included as NFT traits.
{
"name": "Bad Bunny — Miami 2025 — Seat A-101",
"description": "Official boleto.eth ticket for Bad Bunny — Miami 2025",
"image": "ipfs://<your_event_banner>",
"animation_url": "ipfs://<qr_code_png>",
"attributes": [
{ "trait_type": "ENS Name", "value": "badbunny-miami25.boleto.eth" },
{ "trait_type": "Event", "value": "Bad Bunny — Miami 2025" },
{ "trait_type": "Seat", "value": "A-101" },
{ "trait_type": "Section", "value": "Floor VIP" },
{ "trait_type": "Row", "value": "A" },
{ "trait_type": "Gate", "value": "1" }
]
}The animation_url is a scannable QR code PNG that links to the boleto.eth verification page. On OpenSea, this displays when a buyer interacts with their ticket.
Platform Integration
boleto.eth is designed as a backend rail. Platforms keep their own UX — buyers never leave your app.
Create event + upload seats
const res = await fetch('https://boleto-api-production.up.railway.app/v1/events', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
artistSlug: 'badbunny', eventSlug: 'miami25',
promoterWallet: '0xYOUR_WALLET',
eventName: 'Bad Bunny — Miami 2025',
tickets: csvRows // your seat inventory
})
})
const { invoiceId, feeDue, paymentAddress } = await res.json()
// Send feeDue USDC to paymentAddress, then call /confirmPull inventory for your seat map
const { tickets } = await fetch(
`https://boleto-api-production.up.railway.app/v1/events/${eventId}/inventory`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
).then(r => r.json())
// tickets[] has: seatNumber, priceUsdc, minted, ownerWallet
// Render in your own seat map UIOn purchase — voucher (buyer pays gas)
// After buyer pays on your platform:
const voucher = await fetch(
`https://boleto-api-production.up.railway.app/v1/events/${eventId}/voucher`,
{
method: 'POST',
headers: { Authorization: `Bearer ${API_KEY}` },
body: JSON.stringify({ seatNumber: 'A-101', buyerWallet: '0x...' })
}
).then(r => r.json())
// Pass voucher to your frontend:
// buyer calls contract.mintWithVoucher(...voucher) from their walletOn purchase — backend mint (gasless)
// Platform pays gas, buyer receives NFT silently:
await fetch(`https://boleto-api-production.up.railway.app/v1/events/${eventId}/mint`, {
method: 'POST',
headers: { Authorization: `Bearer ${API_KEY}` },
body: JSON.stringify({ seatNumber: 'A-101', toWallet: '0xBUYER' })
})
// NFT lands in buyer wallet. Done.Venue scanning
// QR code on every NFT links to:
// https://boleto.eth.limo/verify?event=badbunny-miami25.boleto.eth&seat=A-101
// Shows valid/invalid + owner wallet in real time
// Or verify in your own scanner app:
const inv = await fetch(`/v1/events/${eventId}/inventory`).then(r => r.json())
const ticket = inv.tickets.find(t => t.seatNumber === scannedSeat)
const isValid = ticket?.minted && ticket?.ownerWallet === expectedWallet