leapocr
v2.0.1
Published
Official JavaScript/TypeScript SDK for LeapOCR API
Readme
LeapOCR JavaScript SDK
Official JavaScript/TypeScript SDK for LeapOCR - Transform documents into structured data using AI-powered OCR.
Overview
LeapOCR provides enterprise-grade document processing with AI-powered data extraction. This SDK offers a JavaScript/TypeScript-native interface for seamless integration into your Node.js and browser applications.
Installation
npm install leapocr
# or
yarn add leapocr
# or
pnpm add leapocrQuick Start
Prerequisites
- Node.js 18 or higher
- LeapOCR API key (sign up here)
Basic Example
import { LeapOCR } from "leapocr";
// Initialize the SDK with your API key
const client = new LeapOCR({
apiKey: process.env.LEAPOCR_API_KEY,
});
// Submit a document for processing
const job = await client.ocr.processURL("https://example.com/document.pdf", {
format: "structured",
model: "standard-v2",
});
// Wait for processing to complete
const result = await client.ocr.waitUntilDone(job.jobId);
console.log("Extracted data:", result.data);Key Features
- TypeScript First - Full type safety with comprehensive TypeScript definitions
- Multiple Processing Formats - Structured data extraction, markdown output, or per-page processing
- Flexible Model Selection - Choose from standard, pro, or custom AI models
- Custom Schema Support - Define extraction schemas for your specific use case
- Built-in Retry Logic - Automatic handling of transient failures
- Universal Runtime - Works in Node.js and modern browsers
- Direct File Upload - Efficient multipart uploads for local files
- Webhook Verification Helper - Verify incoming
X-R2-Signatureheaders with the raw request body
Processing Models
| Model | Use Case | Credits/Page | Priority |
| ------------- | ------------------------------ | ------------ | -------- |
| standard-v2 | General purpose (default) | 1 | 2 |
| pro-v2 | Highest quality, all languages | 3 | 6 |
Specify a model in the processing options. Defaults to standard-v2.
Usage Examples
Processing from URL
const client = new LeapOCR({
apiKey: process.env.LEAPOCR_API_KEY,
});
const job = await client.ocr.processURL("https://example.com/invoice.pdf", {
format: "structured",
model: "standard-v2",
instructions: "Extract invoice number, date, and total amount",
});
const result = await client.ocr.waitUntilDone(job.jobId);
console.log(`Processing completed in ${result.processing_time_seconds}s`);
console.log(`Credits used: ${result.credits_used}`);
console.log("Data:", result.data);Processing Local Files
import { readFileSync } from "fs";
const client = new LeapOCR({
apiKey: process.env.LEAPOCR_API_KEY,
});
const job = await client.ocr.processFile("./invoice.pdf", {
format: "structured",
model: "pro-v2",
schema: {
invoice_number: "string",
total_amount: "number",
invoice_date: "string",
vendor_name: "string",
},
});
const result = await client.ocr.waitUntilDone(job.jobId);
console.log("Extracted data:", result.data);Custom Schema Extraction
const schema = {
type: "object",
properties: {
patient_name: { type: "string" },
date_of_birth: { type: "string" },
medications: {
type: "array",
items: {
type: "object",
properties: {
name: { type: "string" },
dosage: { type: "string" },
},
},
},
},
};
const job = await client.ocr.processFile("./medical-record.pdf", {
format: "structured",
schema,
});Output Formats
| Format | Description | Use Case |
| ------------ | ------------------ | ---------------------------------------------- |
| structured | Single JSON object | Extract specific fields across entire document |
| markdown | Text per page | Convert document to readable text |
Monitoring Job Progress
// Poll for status updates
const pollInterval = 2000; // 2 seconds
const maxAttempts = 150; // 5 minutes max
let attempts = 0;
while (attempts < maxAttempts) {
const status = await client.ocr.getJobStatus(job.jobId);
console.log(
`Status: ${status.status} (${status.progress?.toFixed(1)}% complete)`,
);
if (status.status === "completed") {
const result = await client.ocr.getJobResult(job.jobId);
console.log("Processing complete!");
break;
}
await new Promise((resolve) => setTimeout(resolve, pollInterval));
attempts++;
}Using Template Slugs
// Process a document using a predefined template
const job = await client.ocr.processFile("./invoice.pdf", {
templateSlug: "my-invoice-template",
});
await client.ocr.waitUntilDone(job.jobId);
const result = await client.ocr.getJobResult(job.jobId);
console.log("Extracted data:", result.pages);Deleting Jobs
// Delete a completed job to free up resources
await client.ocr.deleteJob(job.jobId);
console.log("Job deleted successfully");For more examples, see the examples/ directory.
Configuration
Custom Configuration
import { LeapOCR } from "leapocr";
const client = new LeapOCR({
apiKey: "your-api-key",
baseURL: "https://api.leapocr.com", // optional
timeout: 30000, // 30 seconds (optional)
});Environment Variables
export LEAPOCR_API_KEY="your-api-key"
export LEAPOCR_BASE_URL="https://api.leapocr.com" # optionalError Handling
The SDK provides typed errors for robust error handling:
import {
AuthenticationError,
ValidationError,
JobFailedError,
TimeoutError,
NetworkError,
} from "leapocr";
try {
const result = await client.ocr.waitUntilDone(job.jobId);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error("Authentication failed - check your API key");
} else if (error instanceof ValidationError) {
console.error("Validation error:", error.message);
} else if (error instanceof NetworkError) {
// Retry the operation
console.error("Network error, retrying...");
} else if (error instanceof JobFailedError) {
console.error("Processing failed:", error.message);
} else if (error instanceof TimeoutError) {
console.error("Operation timed out");
}
}Error Types
AuthenticationError- Invalid API key or authentication failuresAuthorizationError- Permission denied for requested resourceRateLimitError- API rate limit exceededValidationError- Input validation errorsFileError- File-related errors (size, format, etc.)JobError- Job processing errorsJobFailedError- Job completed with failure statusTimeoutError- Operation timeoutsNetworkError- Network/connectivity issues (retryable)APIError- General API errors
Webhook Signature Verification
Use verifyWebhookSignature() with the raw request body exactly as received. LeapOCR sends customer webhooks with X-Webhook-Signature and X-Webhook-Timestamp, and signs timestamp + "." + rawBody with your webhook secret.
import { verifyWebhookSignature } from "leapocr";
export async function POST(request: Request): Promise<Response> {
const rawBody = await request.text();
const signature = request.headers.get("x-webhook-signature") ?? "";
const timestamp = request.headers.get("x-webhook-timestamp") ?? "";
const isValid = await verifyWebhookSignature(
rawBody,
signature,
timestamp,
process.env.LEAPOCR_WEBHOOK_SECRET!,
);
if (!isValid) {
return new Response("Invalid signature", { status: 401 });
}
const payload = JSON.parse(rawBody);
return Response.json({ ok: true, objectKey: payload.object_key });
}Do not verify against JSON.stringify(parsedBody). Use the original request text or bytes and the timestamp header.
API Reference
Full API documentation is available in the TypeScript definitions.
Core Methods
// Initialize SDK
new LeapOCR(config: ClientConfig)
// Process documents
client.ocr.processURL(url: string, options?: UploadOptions): Promise<UploadResult>
client.ocr.processFile(filePath: string, options?: UploadOptions): Promise<UploadResult>
client.ocr.processFileBuffer(buffer: Buffer, filename: string, options?: UploadOptions): Promise<UploadResult>
// Job management
client.ocr.getJobStatus(jobId: string): Promise<JobStatus>
client.ocr.getJobResult(jobId: string): Promise<OCRJobResult>
client.ocr.waitUntilDone(jobId: string, options?: PollOptions): Promise<JobStatus>
client.ocr.deleteJob(jobId: string): Promise<void>Processing Options
interface UploadOptions {
format?: "structured" | "markdown";
model?: OCRModel;
schema?: Record<string, any>;
instructions?: string;
templateSlug?: string;
}Development
Prerequisites
- Node.js 18+
- pnpm 9+
Setup
# Install dependencies
pnpm install
# Build the SDK
pnpm buildCommon Tasks
pnpm build # Build the SDK
pnpm test # Run unit tests
pnpm typecheck # Type check
pnpm format # Format code
pnpm dev # Development mode with watch
pnpm generate # Generate types from OpenAPI specContributing
We welcome contributions! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support & Resources
- Documentation: docs.leapocr.com
- NPM Package: npmjs.com/package/leapocr
- Issues: GitHub Issues
- Website: leapocr.com
Version: 0.0.5
