Back to Integration Docs
AI Integration Guide

LLM-Optimized Integration Guide

This guide is specifically designed for AI coding assistants like Claude Code, Cursor, GitHub Copilot, and other LLM-powered tools. Copy or download this guide and provide it to your AI assistant for seamless 3PM Extractor integration.

Important for AI Assistants

This is 3PM Extractor, an embeddable AI document extraction platform. It is NOT a standalone file storage service or OCR tool. The appSecret and embedToken must never be exposed to the browser — use session-based auth via POST /api/embed/sessions from your backend.

Quick Start Checklist

Setup (One-time)

Register application in Admin Dashboard
Copy appId and appSecret
Call POST /api/embed/onboard to create tenant
Store embedToken securely on backend
Set environment variables

Implementation

Create backend route for session creation
Frontend fetches sessionId from your backend
Render iframe with ?sessionId=ess_xxx
Listen for postMessage events (optional)
Set up webhooks for notifications (optional)

Key Concepts

Embed Token

Long-lived secret returned from onboarding. Server-side only! Never expose in client code.

Session ID

Short-lived token (1 day TTL) safe for the browser. Created via POST /api/embed/sessions.

Document Templates

Define typed fields (String, Number, Object, List) that the AI extracts from uploaded documents.

Multi-tenant

Each onboarded organization is an isolated tenant with its own users, documents, and extractions.

Architecture Flow

Host Application (yours)
  |
  |-- Backend (Node.js / Python / any)
  |     |
  |     |-- POST /api/embed/onboard      --> One-time: create tenant + user + embedToken (uses appId + appSecret)
  |     |-- POST /api/embed/sessions      --> Per-page-load: create session (uses appId + appSecret + embedToken)
  |     |
  |     |-- After session is created, use X-Session-Id for everything:
  |     |     |-- POST /api/embed/users   --> Add new users to your tenant
  |     |     |-- GET  /api/embed/users   --> List users in your tenant
  |     |     |-- POST /api/embed/extract --> Upload & extract documents
  |     |
  |     |-- Stores: appId, appSecret, embedToken (NEVER in frontend)
  |     |
  |-- Frontend (React / Vue / any)
        |
        |-- <iframe src="/embed?sessionId=ess_xxx" />   (only sessionId exposed)
        |-- window.addEventListener('message', ...)      (listen for events)

Environment Variables

.env.localenv
# 3PM Extractor Configuration
EXTRACTOR_BASE_URL=https://extractor.decoded.digital
EXTRACTOR_APP_ID=673abc123def456789012345
EXTRACTOR_APP_SECRET=ask_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EXTRACTOR_EMBED_TOKEN=ext_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# For frontend (safe to expose)
NEXT_PUBLIC_EXTRACTOR_URL=https://extractor.decoded.digital

API Quick Reference

POST/api/embed/onboardOne-time setup

Create tenant, owner user, and embed token in one call

// Request
{
  "organizationName": "Acme Corp",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@acme.com",
  "appId": "673abc123def456789012345",
  "appSecret": "ask_your_app_secret_here"
}

// Response
{
  "data": {
    "tenant": { "id": "...", "name": "Acme Corp" },
    "user": { "id": "...", "email": "john@acme.com", "role": "owner" },
    "embedToken": { "id": "...", "key": "ext_xxx...", "expiresAt": null },
    "appId": "673abc123def456789012345"
  },
  "error": null
}
POST/api/embed/sessionsPer page load

Create a short-lived session for iframe embedding (1 day TTL)

// Request (from your backend)
{
  "appId": "YOUR_APP_ID",
  "appSecret": "ask_YOUR_APP_SECRET",
  "embedToken": "ext_YOUR_EMBED_TOKEN",
  "userEmail": "user@example.com"
}

// Response
{
  "data": {
    "sessionId": "ess_abc123...",
    "expiresAt": "2026-04-08T12:00:00Z",
    "userEmail": "user@example.com",
    "tenantId": "...",
    "appId": "..."
  }
}
POST/api/embed/extract

Upload a file and start AI extraction

curl -X POST \
  -H "X-Session-Id: ess_xxx" \
  -F "file=@invoice.pdf" \
  https://extractor.decoded.digital/api/embed/extract

# Response: { "data": { "extractionId": "...", "status": "processing" } }
GET/api/embed/verify

Verify session and get tenant information

// Headers: X-Session-Id: ess_xxx
// Response
{
  "data": {
    "valid": true,
    "tenantId": "...",
    "embedTokenName": "My Token",
    "userEmail": "user@example.com"
  }
}

Authentication Methods

# Session-based auth (for all calls after onboarding):
X-Session-Id: ess_xxx...
# One header. Session contains all context (app, tenant, user).
# Works for: user creation, user listing, extractions, documents, etc.

# App-Secret auth (only for initial onboarding):
X-App-Id: YOUR_APP_ID
X-App-Secret: ask_xxx...
# Used only for POST /api/embed/onboard and POST /api/embed/sessions.

Available Embed Pages

PageURL PathDescription
File Upload/embed?sessionId=ess_xxxUpload files and extract data
Documents/embed/documents?sessionId=ess_xxxManage document templates
Extractions/embed/extractions?sessionId=ess_xxxView extraction history with search/filters
Settings/embed/settings?sessionId=ess_xxxIntegrations, webhooks, embed tokens

Framework Integration

The full AI Integration Guide includes complete code examples for:

Next.js

App Router + API Routes

Express.js

Backend + HTML Frontend

React

Reusable Component

Python

Client Library

Next.js Quick Start

Backend session route + frontend iframe component:

app/api/extractor/session/route.tstypescript
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  // 1. Get authenticated user email from your auth system
  const userEmail = 'user@example.com'; // Replace with your auth

  // 2. Create session with Extractor
  const response = await fetch(
    `${process.env.EXTRACTOR_BASE_URL}/api/embed/sessions`,
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        appId: process.env.EXTRACTOR_APP_ID,
        appSecret: process.env.EXTRACTOR_APP_SECRET,
        embedToken: process.env.EXTRACTOR_EMBED_TOKEN,
        userEmail,
      }),
    }
  );

  const data = await response.json();
  if (!response.ok) {
    return NextResponse.json({ error: 'Failed' }, { status: 500 });
  }

  // 3. Return only sessionId to frontend
  return NextResponse.json({ sessionId: data.data.sessionId });
}
components/ExtractorEmbed.tsxtsx
'use client';
import { useEffect, useState } from 'react';

export function ExtractorEmbed({ page = 'upload', height = 600 }) {
  const [sessionId, setSessionId] = useState(null);

  useEffect(() => {
    fetch('/api/extractor/session', { method: 'POST' })
      .then(res => res.json())
      .then(data => setSessionId(data.sessionId))
      .catch(console.error);
  }, []);

  if (!sessionId) return <div>Loading...</div>;

  const pagePath = page === 'upload' ? '' : `/${page}`;
  const src = `${process.env.NEXT_PUBLIC_EXTRACTOR_URL}/embed${pagePath}?sessionId=${sessionId}`;

  return (
    <iframe
      src={src}
      width="100%"
      height={height}
      frameBorder="0"
      allow="clipboard-write"
    />
  );
}

Extraction Status Flow

uploaded → analyzing → analyzed → extracting → completed
              ↓                       ↓
        analysis failed        extraction failed
              ↓                       ↓
            failed                  failed

Statuses: uploaded, analyzing, analyzed, extracting, completed,
          analysis failed, extraction failed, failed

All Endpoints

MethodEndpointAuthDescription
POST/api/embed/onboardBodyCreate tenant + user + token
POST/api/embed/sessionsBodyCreate session
GET/api/embed/verifySessionVerify session
POST/api/embed/extractSessionUpload & extract
GET/api/embed/extractionsSessionList extractions
GET/api/embed/extractions/:idSessionGet extraction
POST/api/embed/extractions/:id/retrySessionRetry failed
GET/api/embed/documentsSessionList templates
POST/api/embed/documentsSessionCreate template
POST/api/embed/usersSessionCreate user
POST/api/embed/webhooksSessionCreate webhook

Full endpoint list with request/response examples available in the downloadable guide.

Ready to Integrate?

Download the complete AI Integration Guide with full code examples for Next.js, Express.js, React, Python, and more. Paste it into Claude Code, Cursor, or any AI assistant.

Last updated: April 2026