docwal-sdk
v1.0.1
Published
Official Node.js SDK for DocWal API - Issue and manage verifiable digital credentials
Maintainers
Readme
DocWal Node.js SDK
Official Node.js/TypeScript SDK for DocWal API - Issue and manage verifiable digital credentials.
Installation
npm install docwal-sdk
yarn add docwal-sdkQuick Start
import { DocWalClient } from 'docwal-sdk';
// Initialize client
const client = new DocWalClient({
apiKey: 'docwal_live_xxxxx'
});
// Issue a credential
const result = await client.credentials.issue({
templateId: 'template-123',
individualEmail: '[email protected]',
credentialData: {
student_name: 'John Doe',
degree: 'Bachelor of Science',
major: 'Computer Science',
graduation_date: '2024-05-15',
gpa: '3.8'
}
});
console.log(`Credential issued! Doc ID: ${result.doc_id}`);
console.log(`Claim token: ${result.claim_token}`);Authentication
Get your API key from your DocWal dashboard:
- Login to https://docwal.com
- Navigate to Settings → API Keys
- Click "Generate API Key"
- Copy and store securely
Requirements:
- Pilot tier or above
- Owner or Admin role
Environment Configuration
// Production (default)
const client = new DocWalClient({
apiKey: 'docwal_live_xxxxx'
});
// Staging
const client = new DocWalClient({
apiKey: 'docwal_test_xxxxx',
baseUrl: 'https://sandbox.docwal.com/api'
});
// Custom timeout
const client = new DocWalClient({
apiKey: 'docwal_live_xxxxx',
timeout: 60000 // milliseconds
});TypeScript Support
Full TypeScript support with type definitions included:
import {
DocWalClient,
IssueCredentialParams,
IssueCredentialResponse,
Credential,
Template
} from 'docwal-sdk';Usage Examples
Issue Single Credential
// Basic credential
const result = await client.credentials.issue({
templateId: 'template-123',
individualEmail: '[email protected]',
credentialData: {
student_name: 'John Doe',
degree: 'Bachelor of Science',
graduation_date: '2024-05-15'
}
});
// With PDF attachment
import fs from 'fs';
const pdfBuffer = fs.readFileSync('certificate.pdf');
const result = await client.credentials.issue({
templateId: 'template-123',
individualEmail: '[email protected]',
credentialData: { student_name: 'John Doe' },
documentFile: pdfBuffer,
claimTokenExpiresHours: 168 // 7 days
});Batch Issue Credentials
const credentialsList = [
{
individual_email: '[email protected]',
credential_data: {
student_name: 'Alice Smith',
degree: 'Bachelor of Arts',
graduation_date: '2024-05-15'
}
},
{
individual_email: '[email protected]',
credential_data: {
student_name: 'Bob Johnson',
degree: 'Bachelor of Science',
graduation_date: '2024-05-15'
}
}
];
const result = await client.credentials.batchIssue(
'template-123',
credentialsList,
true // send notifications
);
console.log(`Success: ${result.success_count}/${result.total_rows}`);Batch Upload with ZIP
import fs from 'fs';
// ZIP structure:
// batch_credentials.zip
// ├── credentials.csv
// └── documents/
// ├── student001.pdf
// ├── student002.pdf
// └── student003.pdf
const zipBuffer = fs.readFileSync('batch_credentials.zip');
const result = await client.credentials.batchUpload(
'template-123',
zipBuffer,
true // send notifications
);
console.log(`Processed: ${result.total_rows}`);
console.log(`Success: ${result.success_count}`);
console.log(`Failed: ${result.failure_count}`);
for (const item of result.results) {
if (item.status === 'success') {
console.log(`Row ${item.row}: ${item.doc_id}`);
} else {
console.log(`Row ${item.row}: ${item.error}`);
}
}List and Get Credentials
// List all credentials
const credentials = await client.credentials.list(50, 0);
for (const cred of credentials) {
console.log(`${cred.doc_id}: ${cred.template_name}`);
}
// Get specific credential
const credential = await client.credentials.get('DOC123456');
console.log(`Issued to: ${credential.ownership?.individual_email}`);
console.log(`Status: ${credential.ownership?.is_claimed ? 'Claimed' : 'Pending'}`);Revoke Credential
const result = await client.credentials.revoke(
'DOC123456',
'Student expelled for academic misconduct'
);
console.log(result.message);Resend Claim Link
const result = await client.credentials.resendClaimLink(
'DOC123456',
168 // 7 days
);
console.log(`Sent to: ${result.recipient_email}`);
console.log(`Expires: ${result.claim_token_expires}`);Download Credential File
import fs from 'fs';
// Download PDF file
const pdfBuffer = await client.credentials.download('DOC123456');
fs.writeFileSync('credential.pdf', pdfBuffer);Template Management
// List templates
const templates = await client.templates.list();
// Get template
const template = await client.templates.get('template-123');
// Create template
const template = await client.templates.create({
name: 'Bachelor Degree Certificate',
description: 'Template for bachelor degree graduation certificates',
credentialType: 'certificate',
schema: {
student_name: {
type: 'string',
required: true,
label: 'Student Name'
},
degree: {
type: 'string',
required: true,
label: 'Degree Program'
},
graduation_date: {
type: 'date',
required: true,
label: 'Graduation Date'
}
},
version: '1.0'
});
// Update template
await client.templates.update('template-123', {
description: 'Updated description'
});
// Delete template (soft delete)
await client.templates.delete('template-123');API Key Management
// Generate new API key (Owner/Admin only)
const result = await client.apiKeys.generate();
console.log(`New API key: ${result.api_key}`);
console.log('⚠️ Store securely - shown only once!');
// Get API key info
const info = await client.apiKeys.info();
console.log(`Masked key: ${info.api_key_masked}`);
console.log(`Created: ${info.created_at}`);
console.log(`Last used: ${info.last_used_at}`);
// Regenerate API key
const result = await client.apiKeys.regenerate();
console.log(`New API key: ${result.api_key}`);
// Revoke API key
await client.apiKeys.revoke();Team Management
// List team members
const team = await client.team.list();
console.log(`Active members: ${team.stats.active_members}`);
console.log(`Pending invitations: ${team.stats.pending_invitations}`);
// Check email before inviting
const check = await client.team.checkEmail('[email protected]');
if (check.recommendation === 'add_directly') {
console.log('User exists - can add directly');
} else if (check.recommendation === 'send_invitation') {
console.log("User doesn't exist - must send invitation");
}
// Invite team member
const result = await client.team.invite({
email: '[email protected]',
role: 'issuer',
sendEmail: true
});
// Update member role
await client.team.updateRole('member-123', 'admin');
// Deactivate member
await client.team.deactivate('member-123', 'Employee on leave');
// Reactivate member
await client.team.reactivate('member-123');
// Remove member permanently
await client.team.remove('member-123');Error Handling
import {
DocWalClient,
AuthenticationError,
ValidationError,
NotFoundError,
RateLimitError
} from 'docwal-sdk';
const client = new DocWalClient({ apiKey: 'docwal_live_xxxxx' });
try {
const result = await client.credentials.issue({
templateId: 'invalid-template',
individualEmail: '[email protected]',
credentialData: {}
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Authentication failed:', error.message);
console.error('Check your API key');
} else if (error instanceof ValidationError) {
console.error('Validation error:', error.message);
console.error('Check required fields');
} else if (error instanceof NotFoundError) {
console.error('Resource not found:', error.message);
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded');
} else {
console.error('Error:', error);
}
}Rate Limits
- Pilot: 500 requests/hour
- Standard: 1,000 requests/hour
- Enterprise: Unlimited
When rate limit is exceeded, RateLimitError is thrown.
Express.js Integration Example
import express from 'express';
import { DocWalClient } from 'docwal-sdk';
const app = express();
const docwal = new DocWalClient({ apiKey: process.env.DOCWAL_API_KEY! });
app.use(express.json());
app.post('/api/issue-credential', async (req, res) => {
try {
const result = await docwal.credentials.issue({
templateId: req.body.template_id,
individualEmail: req.body.email,
credentialData: req.body.data
});
res.json({ success: true, data: result });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.listen(3000);Support
- Email: [email protected]
- Documentation: https://docwal.com/docs
- API Reference: https://docwal.com/api/docs
- GitHub: https://github.com/docwal/docwal-nodejs
License
MIT License - see LICENSE file for details.
