API Documentation
Everything you need to integrate Doc API into your application.
Agent Skill
The fastest way to integrate DocAPI into any agent workflow is via our official skills.sh skill. It works with 43+ supported agents โ including Claude Code, GPT, Gemini, Cursor, and more. Install it once and your agent can generate PDFs, capture screenshots, create invoices, register for an account, and manage USDC credits โ all without reading documentation or writing integration code from scratch.
Installation
npx skills add https://github.com/doc-api-llc/docapi-skill --skill docapi
What the skill enables
Once installed, your agent can:
- Register for a DocAPI account and receive an API key programmatically
- Generate PDFs from HTML with full formatting control (page size, margins, fonts, backgrounds)
- Capture full-page screenshots of URLs or HTML content
- Generate structured invoice PDFs from line-item data
- Check credit balance and top up via USDC on Base mainnet
- Monitor
X-Credits-Remainingand handle proactive topups automatically
Environment variables
The skill uses two environment variables set at registration time:
DOCAPI_KEY=pk_... # API keyDOCAPI_USDC_ADDRESS=0x2B984ee1A172B0aB50eDAf59FeA11D3ddc4e4396 # payment address
The skill is open source. View the full implementation and tools at skills.sh/doc-api-llc/docapi-skill/docapi.
MCP Server
DocAPI has a hosted Model Context Protocol server at https://mcp.docapi.co. Connect once and Claude Desktop, Cursor, or any MCP-compatible client can generate PDFs and screenshots directly โ no code required.
Authentication works per-request: you pass your DocAPI key as an HTTP header in the connection config. The server never stores your key.
Setup: Claude Desktop
Step 1. Get a free API key from the dashboard (or sign up if you don't have an account).
Step 2. Open your Claude Desktop config file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Step 3. Add the DocAPI server under mcpServers:
{"mcpServers": {"docapi": {"url": "https://mcp.docapi.co/mcp","headers": {"x-api-key": "pk_live_your_key_here"}}}}
Step 4. Restart Claude Desktop. You should see a hammer icon (๐จ) in the input area โ that confirms MCP tools are active.
Step 5. Try it: ask Claude to "generate a PDF of a simple invoice and save it to my Downloads folder" or "screenshot https://docapi.co at 1200ร630".
Tip: If you already have other MCP servers configured, just add the "docapi" block inside your existing mcpServers object.
Setup: Cursor
Step 1. Open Cursor โ Settings (โ,) โ search for MCP โ click Add MCP Server.
Step 2. Choose HTTP as the transport type, then enter:
- URL:
https://mcp.docapi.co/mcp - Headers:
x-api-key: pk_live_your_key_here
Step 3. Save and reload. The DocAPI tools will appear in Cursor's agent tool list.
Alternatively, add it directly to .cursor/mcp.json in your project or ~/.cursor/mcp.json globally:
{"mcpServers": {"docapi": {"url": "https://mcp.docapi.co/mcp","headers": {"x-api-key": "pk_live_your_key_here"}}}}
Available tools
Once connected, your agent has access to four tools:
docapi_generate_pdf
Convert an HTML string to a PDF. Returns base64-encoded PDF content which Claude can save to a file on your machine.
{"html": "<h1 style='font-family:sans-serif'>Hello World</h1>","format": "A4","landscape": false,"margin_inches": 0.5,"print_background": true}
docapi_capture_screenshot
Screenshot a live URL or render HTML and capture it as an image. The image is returned inline โ Claude can display it directly in the conversation.
{ "url": "https://example.com", "width": 1200, "height": 630 }
{ "html": "<div style='background:#0f172a;color:white;padding:60px'><h1>My Post</h1></div>", "width": 1200, "height": 630 }
docapi_check_credits
Check your remaining API credits and USDC top-up address (agent accounts only). Takes no parameters.
docapi_register_agent
Register a new agent account programmatically. Useful when Claude is helping you build a service that needs its own DocAPI account. Returns an API key and USDC address immediately.
Node.js SDK
The official Node.js SDK wraps the REST API with full TypeScript types, ESM + CJS support, and zero dependencies.
npm install @docapi/sdk
import { DocAPI } from "@docapi/sdk";const client = new DocAPI(process.env.DOCAPI_KEY!);// Generate a PDFconst pdf = await client.pdf("<h1>Hello World</h1>", { format: "A4" });fs.writeFileSync("output.pdf", pdf);// Screenshot a URLconst img = await client.screenshot({ url: "https://example.com", width: 1200, height: 630 });fs.writeFileSync("screenshot.png", img);// Screenshot from HTML (e.g. OG image)const og = await client.screenshot({html: `<div style="width:1200px;height:630px;background:#0f172a;display:flex;align-items:center;padding:80px"><h1 style="color:white;font-size:64px">My Post Title</h1></div>`,width: 1200,height: 630,});
Credits monitoring
After every pdf() or screenshot() call, client.creditsRemaining holds the latest value from the X-Credits-Remaining header โ useful for proactive USDC top-ups on agent accounts.
const pdf = await client.pdf(html);if ((client.creditsRemaining ?? 999) < 50) {// trigger USDC top-up}
Agent registration
import { DocAPI } from "@docapi/sdk";// No API key needed โ static methodconsole.log(account.api_key); // "pk_..."console.log(account.usdc_address); // "0x..."console.log(account.free_calls); // 10
Error handling
import { DocAPI, DocAPIError } from "@docapi/sdk";try {const pdf = await client.pdf(html);} catch (err) {if (err instanceof DocAPIError) {console.error(err.status); // 401 | 402 | 429 | 500console.error(err.code); // "invalid_api_key" | "credits_exhausted" | ...}}
Python SDK
The official Python SDK wraps the REST API with full type hints, zero dependencies, and Python 3.8+ support. Uses the built-in urllib โ no requests required.
pip install docapi-sdk
from docapi import DocAPIclient = DocAPI("pk_live_...")# Generate a PDFpdf = client.pdf("<h1>Hello World</h1>", format="A4")with open("output.pdf", "wb") as f:f.write(pdf)# Screenshot a URLimg = client.screenshot(url="https://example.com", width=1200, height=630)with open("screenshot.png", "wb") as f:f.write(img)# Screenshot from HTML (e.g. OG image)og = client.screenshot(html="""<div style="width:1200px;height:630px;background:#0f172a;display:flex;align-items:center;padding:80px"><h1 style="color:white;font-size:64px">My Post Title</h1></div>""",width=1200,height=630,)
Credits monitoring
After every pdf() or screenshot() call, client.credits_remaining holds the latest value from the X-Credits-Remaining header.
pdf = client.pdf(html)if (client.credits_remaining or 999) < 50:# trigger USDC top-uppass
Agent registration
from docapi import DocAPI# No API key needed โ static methodprint(account["api_key"]) # "pk_..."print(account["usdc_address"]) # "0x..."print(account["free_calls"]) # 10
Error handling
from docapi import DocAPI, DocAPIErrortry:pdf = client.pdf(html)except DocAPIError as e:print(e.status) # 401 | 402 | 429 | 500print(e.code) # "invalid_api_key" | "credits_exhausted" | ...print(e.message)
Quick Start
Get up and running with Doc API in under 5 minutes.
Step 1: Get your API key
Human developers: Create a free account and get your API key from the dashboard.
AI agents: Install the Claude Code skill for the fastest path, or register programmatically via the AI Agent Integration endpoints directly.
Step 2: Make your first request
curl -X POST https://api.docapi.co/v1/pdf \-H "x-api-key: pk_live_xxx" \-H "Content-Type: application/json" \-d '{"html": "<h1>Hello World</h1>"}' \--output document.pdf
Step 3: Check the response
If successful, you'll receive a PDF file. The response content type will be application/pdf.
Authentication
All API requests require authentication using an API key. Include your key in the x-api-key header with every request.
x-api-key: pk_live_your_api_key_here
Getting your API key
You can find your API key in the dashboard. Each account has one active API key at a time. You can regenerate your key at any time, which will invalidate the previous key.
Security tip: Keep your API key secret. Don't commit it to version control or expose it in client-side code.
AI Agent Integration
DocAPI is designed to be fully operable by AI agents โ no human in the loop required. Agents register via API, receive a USDC payment address, and build services that self-manage their own credit balance.
POST /api/register
Register an agent account programmatically. Returns an API key, USDC address, rate information, and ready-to-use integration code โ everything needed to build a self-funding service.
curl -X POST https://www.docapi.co/api/register \-H "Content-Type: application/json" \-d '{"email": "[email protected]","notify_email": "[email protected]"}'
Both fields are optional. If email is omitted, an agent-specific address is auto-generated. notify_email is for human fallback alerts when the payment wallet runs dry.
Response
{"api_key": "pk_4a7f2b9c1d3e...","usdc_address": "0x2B984ee1A172B0aB50eDAf59FeA11D3ddc4e4396","free_calls": 10,"credits_per_usdc": 50,"network": "base-mainnet","rate": "$0.02 per API call","auto_topup": {"header": "X-Credits-Remaining","recommended_threshold": 50,"recommended_topup_usdc": 10},"on_exhausted": {"http_status": 402,"body": { "error": "credits_exhausted", "usdc_address": "0x..." }},"notifications": {"threshold": 50,"note": "One email per 24h when credits fall below threshold"},"docs": "https://www.docapi.co/docs"}
Rate limit: 5 registrations per day per IP. Each registration creates a dedicated Coinbase CDP smart account wallet on Base mainnet for USDC payments.
GET /api/topup
Check an agent account's current credit balance and USDC address.
curl https://www.docapi.co/api/topup \-H "x-api-key: pk_4a7f2b9c1d3e..."
Response
{"credits": 487,"usdc_address": "0x2B984ee1A172B0aB50eDAf59FeA11D3ddc4e4396","rate": "$0.02 per call (50 credits per USDC)","suggested_topup_usdc": 10}
X-Credits-Remaining header
Every successful API response includes this header with the remaining credit balance for agent accounts. Use it to trigger proactive topups before credits are exhausted.
HTTP/2 200Content-Type: application/pdfX-Credits-Remaining: 47
USDC payment flow
Send USDC to the usdc_address returned at registration on Base mainnet. Credits are applied within seconds via webhook.
- 1 USDC = 50 credits ($0.02/call)
- Minimum: any amount (even $0.10 USDC = 5 credits)
- Network: Base mainnet only
- Token: USDC (
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913)
Self-managing integration
The recommended pattern: watch X-Credits-Remaining on every response and trigger a USDC transfer when it drops below 50. The service never hits a 402.
import requestsfrom coinbase_agentkit import CdpAgentkitWrapperAPI_KEY = "pk_..."USDC_ADDRESS = "0x..." # from registration responseTHRESHOLD = 50TOPUP_USDC = 10agentkit = CdpAgentkitWrapper()_topup_pending = Falsedef generate_pdf(html: str) -> bytes:global _topup_pendingresp = requests.post("https://api.docapi.co/v1/pdf",headers={"x-api-key": API_KEY},json={"html": html},timeout=30,)remaining = int(resp.headers.get("X-Credits-Remaining", 999))if remaining < THRESHOLD and not _topup_pending:_topup_pending = Truetry:agentkit.run(f"Send {TOPUP_USDC} USDC to {USDC_ADDRESS} on base-mainnet")finally:_topup_pending = Falseresp.raise_for_status()return resp.content
import { sendUsdc } from '@coinbase/agentkit';const API_KEY = 'pk_...';const USDC_ADDRESS = '0x...'; // from registration responseconst THRESHOLD = 50;const TOPUP_USDC = 10;let topupInProgress = false;async function generatePdf(html) {const res = await fetch('https://api.docapi.co/v1/pdf', {method: 'POST',headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },body: JSON.stringify({ html }),});const remaining = parseInt(res.headers.get('X-Credits-Remaining') ?? '999');if (remaining < THRESHOLD && !topupInProgress) {topupInProgress = true;sendUsdc({ to: USDC_ADDRESS, amount: TOPUP_USDC, network: 'base-mainnet' }).catch(console.error).finally(() => { topupInProgress = false; });}if (!res.ok) throw new Error(`DocAPI error: ${res.status}`);return res.arrayBuffer();}
Endpoints
Base URL: https://api.docapi.co
POST /v1/pdf
Convert HTML to a PDF document.
Request body
{"html": "<h1>Hello World</h1><p>This is my PDF.</p>","options": {"format": "A4","margin": {"top": "1in","right": "1in","bottom": "1in","left": "1in"},"printBackground": true}}
Response
Returns a PDF file with content type application/pdf.
Example
const response = await fetch('https://api.docapi.co/v1/pdf', {method: 'POST',headers: {'x-api-key': 'pk_live_xxx','Content-Type': 'application/json'},body: JSON.stringify({html: '<h1>Hello World</h1>',options: { format: 'A4' }})});const pdf = await response.arrayBuffer();fs.writeFileSync('output.pdf', Buffer.from(pdf));
POST /v1/screenshot
Capture a screenshot of a URL or HTML content.
Request body (URL)
{"url": "https://example.com","options": {"width": 1280,"height": 800,"fullPage": false,"format": "png"}}
Request body (HTML)
{"html": "<div style='padding: 20px;'><h1>Screenshot this</h1></div>","options": {"width": 800,"height": 600,"format": "png"}}
Response
Returns an image file with content type image/png or image/jpeg.
GET /v1/usage
Check your current API usage for the billing period.
Response
{"plan": "free","usage": {"current": 47,"limit": 100,"period": "2025-01"}}
Example
curl https://api.docapi.co/v1/usage \-H "x-api-key: pk_live_xxx"
Options Reference
Available options for PDF generation.
| Option | Type | Default | Description |
|---|---|---|---|
format | string | "A4" | Page format (A4, Letter, Legal, Tabloid) |
width | string | - | Custom width (e.g., "800px") |
height | string | - | Custom height (e.g., "600px") |
margin | object | - | { top, right, bottom, left } |
printBackground | boolean | true | Include background colors/images |
scale | number | 1 | Scale factor (0.1 to 2) |
landscape | boolean | false | Use landscape orientation |
pageRanges | string | - | Pages to print (e.g., "1-5, 8") |
Error Codes
Common error responses you may encounter.
| Code | Status | Description |
|---|---|---|
missing_api_key | 401 | No API key provided in request headers |
invalid_api_key | 401 | API key not found or has been revoked |
missing_html | 400 | The html field is required for /v1/pdf |
missing_input | 400 | Either url or html is required for /v1/screenshot |
usage_limit_exceeded | 429 | Monthly API call limit reached. Upgrade your plan. |
credits_exhausted | 402 | Agent account has no credits remaining. Send USDC to your usdc_address to top up. |
generation_failed | 500 | PDF generation failed. Check your HTML for errors. |
Error response format
{"error": {"code": "usage_limit_exceeded","message": "You have exceeded your monthly API call limit."}}
Code Examples
Complete examples in popular languages.
cURL
curl -X POST https://api.docapi.co/v1/pdf \-H "x-api-key: pk_live_xxx" \-H "Content-Type: application/json" \-d '{"html": "<html><body><h1>Invoice #123</h1><p>Amount: $99.00</p></body></html>","options": {"format": "A4","margin": { "top": "0.5in", "bottom": "0.5in" }}}' \--output invoice.pdf
Node.js
const fs = require('fs');async function generatePDF() {const response = await fetch('https://api.docapi.co/v1/pdf', {method: 'POST',headers: {'x-api-key': process.env.DOC_API_KEY,'Content-Type': 'application/json'},body: JSON.stringify({html: `<html><head><style>body { font-family: Arial, sans-serif; padding: 40px; }h1 { color: #333; }</style></head><body><h1>Invoice #123</h1><p>Amount: $99.00</p></body></html>`,options: { format: 'A4' }})});if (!response.ok) {const error = await response.json();throw new Error(error.error.message);}const pdf = await response.arrayBuffer();fs.writeFileSync('invoice.pdf', Buffer.from(pdf));console.log('PDF saved!');}generatePDF();
Python
import requestsimport osdef generate_pdf():response = requests.post('https://api.docapi.co/v1/pdf',headers={'x-api-key': os.environ['DOC_API_KEY'],'Content-Type': 'application/json'},json={'html': '''<html><head><style>body { font-family: Arial, sans-serif; padding: 40px; }h1 { color: #333; }</style></head><body><h1>Invoice #123</h1><p>Amount: $99.00</p></body></html>''','options': {'format': 'A4'}})if response.status_code != 200:raise Exception(response.json()['error']['message'])with open('invoice.pdf', 'wb') as f:f.write(response.content)print('PDF saved!')generate_pdf()
PHP
<?php$apiKey = getenv('DOC_API_KEY');$data = ['html' => '<html><head><style>body { font-family: Arial, sans-serif; padding: 40px; }h1 { color: #333; }</style></head><body><h1>Invoice #123</h1><p>Amount: $99.00</p></body></html>','options' => ['format' => 'A4']];$ch = curl_init('https://api.docapi.co/v1/pdf');curl_setopt_array($ch, [CURLOPT_POST => true,CURLOPT_RETURNTRANSFER => true,CURLOPT_HTTPHEADER => ['x-api-key: ' . $apiKey,'Content-Type: application/json'],CURLOPT_POSTFIELDS => json_encode($data)]);$response = curl_exec($ch);$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);if ($httpCode !== 200) {$error = json_decode($response, true);throw new Exception($error['error']['message']);}file_put_contents('invoice.pdf', $response);echo "PDF saved!\n";