Developer Documentation
Everything you need to integrate DocumentUploader into your application
Quick Start
Get up and running in less than 5 minutes. Here's a minimal example to get you started:
npm install document-uploader<!-- 1. Include the script -->
<script type="module" src="https://cdn.jsdelivr.net/npm/document-uploader@2/dist/document-uploader.js"></script>
<!-- 2. Add the component -->
<document-uploader
api-key="your_api_key"
accepted-types="image/*,application/pdf">
</document-uploader>
<!-- 3. Listen for events -->
<script>
document.querySelector('document-uploader')
.addEventListener('file-uploaded', (e) => {
console.log('File uploaded:', e.detail);
});
</script>Installation
NPM
npm install document-uploaderYarn
yarn add document-uploaderCDN (ES Module)
<script type="module">
import { DocumentUploader } from 'https://unpkg.com/document-uploader@latest/dist/document-uploader.js';
</script>CDN (UMD)
<script src="https://unpkg.com/document-uploader@latest/dist/document-uploader.umd.cjs"></script>Configuration Options
Required Options
apiKey: stringYour API key from the dashboard
container: string | HTMLElementContainer element or CSS selector (single container mode)
fields: FieldConfig[]Array of field configurations (multi-field mode)
Note: Either container or fields is required, but not both.
Optional Options
| Option | Type | Default | Description |
|---|---|---|---|
| persistSession | boolean | true | Auto-save session to localStorage |
| maxRetries | number | 3 | Max retry attempts for failed uploads |
| theme | ThemeConfig | - | Visual theme customization |
| texts | TextsConfig | - | Text/label customization |
| layout | LayoutConfig | - | Layout and visibility options |
Multi-Field Mode
Multi-field mode allows you to handle multiple upload fields in a single form. Perfect for scenarios like uploading multiple document types (ID front, ID back, utility bill).
Example: KYC Document Upload
<!-- 1. ID Card Front -->
<div>
<label>ID Card Front</label>
<document-uploader
id="id-front"
api-key="your_api_key"
max-files="1"
category="id-front">
</document-uploader>
</div>
<!-- 2. ID Card Back -->
<div>
<label>ID Card Back</label>
<document-uploader
id="id-back"
api-key="your_api_key"
max-files="1"
category="id-back">
</document-uploader>
</div>
<script>
// Optional: Share session between fields
const front = document.getElementById('id-front');
const back = document.getElementById('id-back');
front.addEventListener('session-created', (e) => {
back.setAttribute('session-id', e.detail);
});
</script>Customization
Fully customize the widget appearance with themes, texts, and layout options.
Theme Presets
THEME_PRESETS.light- Default themeTHEME_PRESETS.dark- Dark modeTHEME_PRESETS.minimal- Clean designTHEME_PRESETS.rounded- Rounded cornersTHEME_PRESETS.compact- Space-efficient
Widget Builder
Use our visual Widget Builder to customize and generate your configuration code.
Open Widget BuilderCustom Theme Example
const uploader = new DocumentUploader({
apiKey: 'your_api_key',
container: '#uploader',
theme: {
colors: {
primary: '#8b5cf6', // Purple
secondary: '#f59e0b', // Amber
background: '#fefce8', // Light yellow
surface: '#fef9c3',
text: '#1f2937'
},
borderRadius: '16px',
shadow: '0 4px 16px rgba(0,0,0,0.08)'
},
texts: {
title: 'Upload Your Documents',
uploadingText: 'Uploading...',
successMessage: 'Upload successful!'
}
});Webhooks
Configure webhooks to automatically process uploaded files. Perfect for AI processing, notifications, or triggering workflows.
Webhook Payload
{
"event": "upload.completed",
"timestamp": "2025-01-15T10:30:00.000Z",
"upload_id": "uuid",
"file_url": "https://...",
"metadata": { ... }
}Verifying Webhook Signatures
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return signature === digest;
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, 'your_secret')) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
const { event, file } = req.body;
console.log('File uploaded:', file.url);
res.status(200).send('OK');
});Attributes & Events
Attributes
| Attribute | Description |
|---|---|
| api-key | Your API key (Required) |
| max-files | Maximum number of files allowed |
| accepted-types | Comma-separated list of accepted MIME types |
| category | Category string for organizing uploads |
| session-id | ID of an existing session to restore/join |
| payload | Custom JSON payload for associating sessions with external entities (e.g., user_id, order_id) |
Events
| Event Name | Detail |
|---|---|
| file-uploaded | Fired when a file is successfully uploaded. e.detail contains the file object. |
| file-removed | Fired when a file is removed (deleted from storage and database). e.detail contains the file object. |
| session-created | Fired when a new session is created. e.detail contains [sessionId, payload]. |
| session-restored | Fired when a session is restored. e.detail contains [sessionId, uploads, payload]. |
| webhook-executed | NEWFired when a webhook is executed after a file upload. e.detail contains webhook execution details (status, response, timing). |
| error | Fired when an error occurs. e.detail contains the error message. |
NEW Webhook Execution Feedback
Real-time feedback when webhooks are executed
The webhook-executed event provides real-time feedback about webhook deliveries. Perfect for tracking webhook responses, debugging integrations, or showing upload status to users.
<document-uploader
api-key="dk_your_api_key"
></document-uploader>
<script>
const uploader = document.querySelector('document-uploader');
uploader.addEventListener('webhook-executed', (e) => {
const [webhook] = e.detail;
console.log('Webhook ID:', webhook.webhookId);
console.log('Upload ID:', webhook.uploadId);
console.log('Event:', webhook.event); // 'upload.completed'
console.log('Status:', webhook.status); // 'success' or 'failed'
console.log('HTTP Status:', webhook.statusCode);
console.log('Response:', webhook.responseBody);
console.log('Execution time:', webhook.executionTimeMs, 'ms');
console.log('Retry attempt:', webhook.retryAttempt);
if (webhook.status === 'success') {
// Show success notification
console.log('Webhook delivered successfully!');
} else {
// Handle webhook failure
console.error('Webhook failed:', webhook.errorMessage);
}
});
</script>Event Payload Properties:
webhookId- The webhook configuration IDuploadId- The upload that triggered the webhookevent- Event type (e.g., 'upload.completed')status- 'success' or 'failed'statusCode- HTTP response status coderesponseBody- Full webhook responseresponseHeaders- Response headerserrorMessage- Error details if failedexecutionTimeMs- Execution time in millisecondsretryAttempt- Retry attempt number (0 = first attempt)timestamp- When the webhook was executed
Payload Usage
Associate sessions with external entities like users or orders
Use the payload attribute to store custom data with your session. The payload is returned when the session is created or restored.
<document-uploader
api-key="dk_your_api_key"
payload='{"userId": "user_123", "orderId": "order_456"}'
></document-uploader>
<script>
const uploader = document.querySelector('document-uploader');
// When a new session is created
uploader.addEventListener('session-created', (e) => {
const [sessionId, payload] = e.detail;
console.log('Session:', sessionId);
console.log('Payload:', payload);
// { userId: 'user_123', orderId: 'order_456' }
});
// When an existing session is restored
uploader.addEventListener('session-restored', (e) => {
const [sessionId, uploads, payload] = e.detail;
console.log('Restored session:', sessionId);
console.log('Previous uploads:', uploads.length);
console.log('Payload:', payload);
});
// Get payload anytime via method
const currentPayload = uploader.getPayload();
</script>Security
API Key Authentication
Each request is authenticated with your unique API key. Keep your API keys secure and never expose them in public repositories.
Rate Limiting
Automatic rate limiting per IP address with Turnstile CAPTCHA challenge after multiple requests.
File Type Validation
Only images (JPG, PNG, GIF, WebP, HEIC) and PDFs are allowed. Validation is enforced on both client and server.
Webhook Signatures
All webhook requests include HMAC-SHA256 signatures for payload verification and security.
Framework Examples
React Integration
import { useEffect, useRef } from 'react';
import { DocumentUploader } from 'document-uploader';
function UploadComponent({ apiKey, onUpload }) {
const uploaderContainer = useRef(null);
const uploaderRef = useRef(null);
useEffect(() => {
if (!uploaderContainer.current) return;
const initUploader = async () => {
uploaderRef.current = new DocumentUploader({
apiKey,
container: uploaderContainer.current,
onFileUploaded: onUpload
});
await uploaderRef.current.render();
};
initUploader();
return () => {
if (uploaderRef.current) {
uploaderRef.current.destroy();
}
};
}, [apiKey, onUpload]);
return <div ref={uploaderContainer} />;
}Vue Integration
<template>
<div ref="uploaderContainer"></div>
</template>
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
import { DocumentUploader } from 'document-uploader';
const props = defineProps(['apiKey']);
const emit = defineEmits(['upload']);
const uploaderContainer = ref(null);
let uploader = null;
onMounted(async () => {
if (!uploaderContainer.value) return;
uploader = new DocumentUploader({
apiKey: props.apiKey,
container: uploaderContainer.value,
onFileUploaded: (file) => emit('upload', file)
});
await uploader.render();
});
onUnmounted(() => {
if (uploader) {
uploader.destroy();
}
});
</script>Need Help?
Check out our live demo, Widget Builder, or contact support