Appearance
Get up and running with Pocketbook API in minutes. This guide will walk you through creating your first certificate and distributing it to recipients.
Table of Contents
Prerequisites
Before you begin, ensure you have:
- Pocketbook Account: Sign up at pocketbook.studio (wallet automatically created)
- Development Environment: Node.js 16+ or modern browser
- API Access (Optional): Enterprise plan for API keys
5-Minute Quick Start
Step 1: Install Dependencies
bash
npm install ethers node-fetch
# or
yarn add ethers node-fetchStep 2: Create Your First Certificate
javascript
const { ethers } = require('ethers');
const fetch = require('node-fetch');
// Configuration
const API_BASE_URL = 'https://api.pocketbook.studio/api';
// 1. Connect Wallet and Authenticate
async function authenticate() {
// Connect to wallet (MetaMask example)
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
// Create authentication message
const timestamp = Math.floor(Date.now() / 1000);
const message = `Authenticate with Pocketbook: ${timestamp}`;
// Sign message
const signature = await signer.signMessage(message);
// Exchange signature for JWT token
const response = await fetch(`${API_BASE_URL}/certificate/auth`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
signature,
address,
message,
timestamp: timestamp.toString()
})
});
const data = await response.json();
return data.data.token;
}
// 2. Create Certificate
async function createCertificate(token) {
const certificateData = {
name: 'Web Development Certificate',
description: 'Awarded for completing Web Development 101',
imageUrl: 'https://your-domain.com/certificate-image.png',
metadata: {
category: 'education',
attributes: [
{ trait_type: 'Course', value: 'Web Development 101' },
{ trait_type: 'Instructor', value: 'Jane Doe' },
{ trait_type: 'Date', value: '2025-01-15' },
{ trait_type: 'Grade', value: 'A+' }
]
}
};
const response = await fetch(`${API_BASE_URL}/certificate/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(certificateData)
});
const data = await response.json();
return data.data;
}
// 3. Create Voucher for Distribution
async function createVoucher(token, certificateId) {
const voucherData = {
certificateId: certificateId,
expiryDays: 30, // Voucher expires in 30 days
metadata: {
recipientEmail: 'student@example.com',
recipientName: 'John Student'
}
};
const response = await fetch(`${API_BASE_URL}/voucher/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(voucherData)
});
const data = await response.json();
return data.data;
}
// Run the workflow
async function main() {
try {
// Step 1: Authenticate
console.log('🔐 Authenticating...');
const token = await authenticate();
console.log('✅ Authenticated successfully');
// Step 2: Create Certificate
console.log('📜 Creating certificate...');
const certificate = await createCertificate(token);
console.log('✅ Certificate created:', certificate.certificateId);
// Step 3: Create Voucher
console.log('🎟️ Creating voucher...');
const voucher = await createVoucher(token, certificate.certificateId);
console.log('✅ Voucher created:', voucher.referenceNumber);
console.log('📤 Share this link with the recipient:');
console.log(` https://pocketbook.studio/claim/${voucher.id}`);
} catch (error) {
console.error('❌ Error:', error.message);
}
}
main();Step 3: Share with Recipient
Send the claim link to your recipient:
https://pocketbook.studio/claim/[VOUCHER_ID]Recipients can claim their certificate by:
- Connecting their wallet
- Clicking "Claim Certificate"
- Signing the transaction (gas-free for recipients!)
Common Use Cases
Use Case 1: Luxury Fashion Authenticity Cards
Scenario: Issue digital authenticity cards for limited-run apparel, tied to SKU, size, and drop metadata.
javascript
async function issueFashionAuthenticity(token, order) {
const certRes = await fetch(`${API_BASE_URL}/certificate/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: `${order.styleName} Authenticity`,
description: `Authenticity for ${order.styleName} - ${order.collection}`,
imageUrl: order.assetUrl, // product or label image
metadata: {
category: 'fashion',
attributes: [
{ trait_type: 'SKU', value: order.sku },
{ trait_type: 'Size', value: order.size },
{ trait_type: 'Colorway', value: order.color },
{ trait_type: 'Drop', value: order.collection },
{ trait_type: 'Serial', value: order.serial }
]
}
})
});
const cert = await certRes.json();
const voucherRes = await fetch(`${API_BASE_URL}/voucher/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
certificateId: cert.data.certificateId,
expiryDays: 365,
metadata: {
recipientEmail: order.customerEmail,
recipientName: order.customerName,
orderId: order.orderId
}
})
});
return voucherRes.json();
}Use Case 2: Fine Jewelry Warranty & Provenance
Scenario: Deliver a transferable warranty card with provenance (materials, carat weight, serials).
javascript
async function issueJewelryWarranty(token, piece) {
const { data } = await (await fetch(`${API_BASE_URL}/certificate/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: `${piece.collection} Warranty & Provenance`,
description: `Coverage and provenance for ${piece.model}`,
imageUrl: piece.certificateImage,
metadata: {
category: 'jewelry',
attributes: [
{ trait_type: 'Model', value: piece.model },
{ trait_type: 'Metal', value: piece.metal },
{ trait_type: 'Stones', value: piece.stones },
{ trait_type: 'Carat Weight', value: piece.caratWeight },
{ trait_type: 'Serial', value: piece.serial }
]
}
})
})).json();
return fetch(`${API_BASE_URL}/voucher/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
certificateId: data.certificateId,
expiryDays: 365 * 5,
metadata: {
recipientEmail: piece.customerEmail,
recipientName: piece.customerName,
purchaseDate: piece.purchaseDate
}
})
}).then(r => r.json());
}Use Case 3: Limited Edition Art Drops
Scenario: Mint provenance certificates for numbered prints or sculptures and bulk-issue vouchers to buyers.
javascript
import FormData from 'form-data';
async function issueArtEditionBatch(apiKey, edition) {
const rows = edition.buyers.map(buyer => [
`${edition.title} #${buyer.number}`,
`Edition ${buyer.number}/${edition.total} by ${edition.artist}`,
edition.imageUrl,
'art',
buyer.email,
buyer.name
]);
const csv = [
'name,description,imageUrl,category,recipientEmail,recipientName',
...rows.map(r => r.join(','))
].join('\n');
const form = new FormData();
form.append('metadata', Buffer.from(csv), 'art-edition.csv');
form.append('createBatch', 'true');
const res = await fetch(`${API_BASE_URL}/bulk-mint`, {
method: 'POST',
headers: {
'x-api-key': apiKey,
...form.getHeaders()
},
body: form
});
return res.json(); // contains jobId
}Use Case 4: Capsule Collaborations & Drops
Scenario: Issue co-branded certificates for collaboration drops (fashion x artist), with per-piece metadata and claim links for customers.
javascript
async function issueCollabCertificate(token, drop) {
const certRes = await fetch(`${API_BASE_URL}/certificate/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: `${drop.brand} x ${drop.partner} ${drop.dropName}`,
description: `Collaboration piece ${drop.itemName}`,
imageUrl: drop.assetUrl,
metadata: {
category: 'collaboration',
attributes: [
{ trait_type: 'Edition', value: `${drop.editionNumber}/${drop.editionSize}` },
{ trait_type: 'Item', value: drop.itemName },
{ trait_type: 'Release', value: drop.releaseDate },
{ trait_type: 'Retailer', value: drop.retailer },
{ trait_type: 'Collab', value: `${drop.brand} x ${drop.partner}` }
]
}
})
});
const cert = await certRes.json();
return fetch(`${API_BASE_URL}/voucher/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
certificateId: cert.data.certificateId,
expiryDays: 180,
metadata: {
recipientEmail: drop.customerEmail,
recipientName: drop.customerName,
orderId: drop.orderId
}
})
}).then(r => r.json());
}Next Steps
Explore Advanced Features
Webhooks: Get real-time notifications for certificate events
Bulk Operations: Process hundreds of certificates efficiently
Custom Templates: Create reusable certificate templates
Analytics: Track certificate distribution and engagement
Integrate with Your Stack
- LMS Integration: Moodle, Canvas, Blackboard
- Event Platforms: Eventbrite, Hopin, Luma
- HR Systems: BambooHR, Workday, SAP
- CRM: Salesforce, HubSpot
- Email: SendGrid, Mailgun, Postmark
Get Help
- Documentation: docs.pocketbook.studio
- API Reference: api.pocketbook.studio/docs
- Community Discord: discord.gg/pocketbook
- Email Support: seth@pocketbook.studio
Ready to build? Start creating certificates at pocketbook.studio 🚀
