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-uploader

Yarn

yarn add document-uploader

CDN (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: string

Your API key from the dashboard

container: string | HTMLElement

Container 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 booleantrue Auto-save session to localStorage
maxRetries number3 Max retry attempts for failed uploads
themeThemeConfig- Visual theme customization
textsTextsConfig- Text/label customization
layoutLayoutConfig- 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 theme
  • THEME_PRESETS.dark - Dark mode
  • THEME_PRESETS.minimal - Clean design
  • THEME_PRESETS.rounded - Rounded corners
  • THEME_PRESETS.compact - Space-efficient

Widget Builder

Use our visual Widget Builder to customize and generate your configuration code.

Open Widget Builder

Custom 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

AttributeDescription
api-keyYour API key (Required)
max-filesMaximum number of files allowed
accepted-typesComma-separated list of accepted MIME types
categoryCategory string for organizing uploads
session-idID of an existing session to restore/join
payloadCustom JSON payload for associating sessions with external entities (e.g., user_id, order_id)

Events

Event NameDetail
file-uploadedFired when a file is successfully uploaded. e.detail contains the file object.
file-removedFired when a file is removed (deleted from storage and database). e.detail contains the file object.
session-createdFired when a new session is created. e.detail contains [sessionId, payload].
session-restoredFired when a session is restored. e.detail contains [sessionId, uploads, payload].
webhook-executedNEWFired when a webhook is executed after a file upload. e.detail contains webhook execution details (status, response, timing).
errorFired 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 ID
  • uploadId - The upload that triggered the webhook
  • event - Event type (e.g., 'upload.completed')
  • status - 'success' or 'failed'
  • statusCode - HTTP response status code
  • responseBody - Full webhook response
  • responseHeaders - Response headers
  • errorMessage - Error details if failed
  • executionTimeMs - Execution time in milliseconds
  • retryAttempt - 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

DocumentUploader logo

© 2025 DocumentUploader. All rights reserved.