DocsRouterDocsRouter
Api

Chat Completions

OpenAI-compatible endpoint for document OCR

Chat Completions

The /v1/chat/completions endpoint is the recommended way to use DocsRouter. It's fully compatible with OpenAI and OpenRouter SDKs, making integration seamless with your existing codebase.

Endpoint

POST https://api.docsrouter.com/v1/chat/completions

Authentication

All requests to this endpoint require authentication via the Authorization header using a Bearer token.

Authorization: Bearer YOUR_API_KEY

Keep your API key secure. Never expose it in client-side code, public repositories, or browser applications. Always make API calls from your server.

You can generate API keys from the DocsRouter Dashboard. Each key can be named for easy identification and revoked individually if compromised.

Request Headers

HeaderRequiredDescription
AuthorizationYesBearer token with your API key: Bearer YOUR_API_KEY
Content-TypeYesMust be application/json
X-Request-IDNoOptional unique identifier for request tracing

Request Body

The request follows the OpenAI chat completions format:

{
  "model": "google/gemini-2.0-flash-001",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "Extract all text from this document"
        },
        {
          "type": "image_url",
          "image_url": {
            "url": "https://example.com/invoice.png"
          }
        }
      ]
    }
  ],
  "docsrouter": {
    "extract_tables": true,
    "output_format": "json"
  }
}

Parameters

ParameterTypeRequiredDescription
modelstringYesModel ID (e.g., google/gemini-2.0-flash-001)
messagesarrayYesArray of message objects
temperaturenumberNoSampling temperature (0-2)
max_tokensnumberNoMaximum tokens to generate
docsrouterobjectNoDocsRouter-specific options

DocsRouter Options

OptionTypeDefaultDescription
extract_tablesbooleanfalseExtract tables as structured data
extract_key_valuesbooleanfalseExtract form key-value pairs
output_formatstring"text"Output format: text, markdown, or json
language_hintstringnullISO 639-1 language code hint

Message Content Types

Messages can contain text, images, and files (PDFs):

{
  "role": "user",
  "content": [
    { "type": "text", "text": "Your instructions here" },
    { "type": "image_url", "image_url": { "url": "https://..." } }
  ]
}

Image URL formats supported:

  • HTTP/HTTPS URLs: https://example.com/document.png
  • Data URIs: data:image/png;base64,iVBORw0KGgo...

PDF File Support

You can send PDF documents directly using the file content type:

{
  "role": "user",
  "content": [
    { "type": "text", "text": "Extract all text from this PDF" },
    {
      "type": "file",
      "file": {
        "filename": "document.pdf",
        "file_data": "https://example.com/document.pdf"
      }
    }
  ]
}

File data formats supported:

  • HTTP/HTTPS URLs: https://example.com/document.pdf
  • Data URIs: data:application/pdf;base64,JVBERi0xLjQ...

PDF Processing Plugins

Configure PDF processing with the plugins parameter:

{
  "model": "google/gemini-2.0-flash-001",
  "messages": [...],
  "plugins": [
    {
      "id": "file-parser",
      "pdf": {
        "engine": "mistral-ocr"
      }
    }
  ]
}

Available PDF engines:

EngineDescriptionPricing
pdf-textBest for well-structured PDFs with clear textFree
mistral-ocrBest for scanned documents or PDFs with images$0.10 per 1,000 pages
nativeUse model's native file processing (if supported)Charged as input tokens

If no engine is specified, DocsRouter defaults to the model's native capabilities, falling back to pdf-text.

Response

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "created": 1734567890,
  "model": "google/gemini-2.0-flash-001",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "INVOICE\n\nInvoice #: INV-2024-001\nDate: December 15, 2024\n\nBill To:\nAcme Corporation\n123 Business St\n..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 1200,
    "completion_tokens": 450,
    "total_tokens": 1650
  },
  "docsrouter": {
    "confidence": 94,
    "detected_language": "en",
    "pages_processed": 1,
    "tables_detected": 2,
    "tables": [
      {
        "page_number": 1,
        "headers": ["Item", "Quantity", "Price"],
        "rows": [
          ["Widget A", "10", "$99.00"],
          ["Widget B", "5", "$49.50"]
        ],
        "confidence": 92
      }
    ],
    "provider": "openrouter",
    "provider_cost_cents": 1.2,
    "platform_fee_cents": 0.4,
    "total_cost_cents": 1.6,
    "processing_time_ms": 1850
  }
}

Response Fields

Standard OpenAI fields:

  • id - Unique completion ID
  • object - Always chat.completion
  • created - Unix timestamp
  • model - Model used
  • choices - Array of completion choices
  • usage - Token usage statistics

DocsRouter extensions (docsrouter object):

  • confidence - OCR confidence score (0-100)
  • detected_language - Detected document language
  • pages_processed - Number of pages processed
  • tables_detected - Number of tables found
  • tables - Extracted table data (if extract_tables was true)
  • provider_cost_cents - Provider cost in cents
  • platform_fee_cents - DocsRouter fee in cents
  • total_cost_cents - Total cost in cents
  • processing_time_ms - Processing time in milliseconds

Examples

Basic Image OCR

curl -X POST https://api.docsrouter.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.0-flash-001",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "Extract all text from this document"},
        {"type": "image_url", "image_url": {"url": "https://example.com/invoice.png"}}
      ]
    }]
  }'

Processing a PDF with Mistral OCR

For best PDF processing, use the mistral-ocr engine which calls Mistral's dedicated OCR API directly:

curl -X POST https://api.docsrouter.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.0-flash-001",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "Extract all text from this PDF"},
        {
          "type": "file",
          "file": {
            "filename": "document.pdf",
            "file_data": "https://example.com/document.pdf"
          }
        }
      ]
    }],
    "plugins": [{
      "id": "file-parser",
      "pdf": {"engine": "mistral-ocr"}
    }]
  }'

PDF with Base64 Data

# First, encode your PDF to base64
PDF_BASE64=$(base64 -i document.pdf)

curl -X POST https://api.docsrouter.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.0-flash-001",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "Extract all text"},
        {
          "type": "file",
          "file": {
            "filename": "document.pdf",
            "file_data": "data:application/pdf;base64,'"$PDF_BASE64"'"
          }
        }
      ]
    }],
    "plugins": [{
      "id": "file-parser",
      "pdf": {"engine": "mistral-ocr"}
    }]
  }'

With Table Extraction

curl -X POST https://api.docsrouter.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.0-flash-001",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "Extract all text and tables from this invoice"},
        {"type": "image_url", "image_url": {"url": "https://example.com/invoice.png"}}
      ]
    }],
    "docsrouter": {
      "extract_tables": true,
      "output_format": "json"
    }
  }'

Image with Base64 Data

# Encode image to base64
IMG_BASE64=$(base64 -i document.png)

curl -X POST https://api.docsrouter.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.0-flash-001",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "Extract all text"},
        {"type": "image_url", "image_url": {"url": "data:image/png;base64,'"$IMG_BASE64"'"}}
      ]
    }]
  }'

Streaming

DocsRouter supports streaming responses for real-time text extraction. Enable streaming by setting stream: true:

curl -X POST https://api.docsrouter.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.0-flash-001",
    "stream": true,
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "Extract all text from this document"},
        {"type": "image_url", "image_url": {"url": "https://example.com/invoice.png"}}
      ]
    }]
  }'

Streaming responses are sent as Server-Sent Events (SSE):

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"delta":{"content":"INVOICE"},"index":0}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"delta":{"content":" #001"},"index":0}]}

data: [DONE]

Rate Limits

The API implements rate limiting to ensure fair usage and system stability:

TierRequests/MinuteRequests/Day
Free10100
Starter601,000
Pro30010,000
EnterpriseCustomCustom

Rate limit headers are included in every response:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1734567890

If you exceed your rate limit, you'll receive a 429 Too Many Requests response. Check the Retry-After header for when you can retry.

Error Handling

Errors follow the OpenAI error format:

{
  "error": {
    "message": "No images found in messages",
    "type": "invalid_request_error",
    "param": "messages",
    "code": "missing_image"
  }
}

HTTP Status Codes

Status CodeDescriptionCommon Causes
400Bad RequestInvalid JSON, missing required fields, invalid image URL
401UnauthorizedMissing or invalid API key
402Payment RequiredInsufficient credits in your account
403ForbiddenAPI key doesn't have permission for this operation
404Not FoundInvalid model ID or endpoint
413Payload Too LargeImage or PDF exceeds size limits (max 20MB)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error
502Bad GatewayUpstream provider (Google, OpenAI, etc.) is unavailable
503Service UnavailableDocsRouter is temporarily unavailable

Common Error Codes

CodeDescriptionSolution
missing_imageNo image or file found in messagesInclude at least one image_url or file content block
invalid_image_urlImage URL is not accessibleEnsure the URL is publicly accessible or use base64
unsupported_formatFile format not supportedUse PNG, JPG, WEBP, GIF, or PDF
model_not_foundSpecified model doesn't existCheck /v1/models for available models
insufficient_creditsAccount balance too lowAdd credits in the dashboard
context_length_exceededDocument too large for modelUse a model with larger context or split the document

Best Practices

Optimizing for Speed

  1. Use Gemini 2.0 Flash for most documents - it's the fastest and most cost-effective
  2. Compress images before sending - smaller files process faster
  3. Use streaming for real-time feedback in user-facing applications
  4. Batch similar documents when possible

Optimizing for Accuracy

  1. Use higher-quality models (GPT-4o, Claude Sonnet) for complex documents
  2. Provide clear instructions in your prompt about what to extract
  3. Use mistral-ocr engine for scanned PDFs with poor quality
  4. Set language_hint if you know the document language

Handling Large Documents

  1. Multi-page PDFs: Use the file content type with mistral-ocr engine
  2. Large images: Resize to max 4096x4096 pixels before sending
  3. Many documents: Process in parallel with proper rate limiting

On this page