Doc API

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

bash
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-Remaining and handle proactive topups automatically

Environment variables

The skill uses two environment variables set at registration time:

bash
DOCAPI_KEY=pk_... # API key
DOCAPI_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:

claude_desktop_config.json
{
"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:

~/.cursor/mcp.json
{
"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.

json
{
"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.

json
{ "url": "https://example.com", "width": 1200, "height": 630 }
json
{ "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.

bash
npm install @docapi/sdk
typescript
import { DocAPI } from "@docapi/sdk";
const client = new DocAPI(process.env.DOCAPI_KEY!);
// Generate a PDF
const pdf = await client.pdf("<h1>Hello World</h1>", { format: "A4" });
fs.writeFileSync("output.pdf", pdf);
// Screenshot a URL
const 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.

typescript
const pdf = await client.pdf(html);
if ((client.creditsRemaining ?? 999) < 50) {
// trigger USDC top-up
}

Agent registration

typescript
import { DocAPI } from "@docapi/sdk";
// No API key needed โ€” static method
const account = await DocAPI.register({ notify_email: "[email protected]" });
console.log(account.api_key); // "pk_..."
console.log(account.usdc_address); // "0x..."
console.log(account.free_calls); // 10

Error handling

typescript
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 | 500
console.error(err.code); // "invalid_api_key" | "credits_exhausted" | ...
}
}

View on npm ยท GitHub ยท Zero dependencies ยท ESM + CJS ยท Full TypeScript types

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.

bash
pip install docapi-sdk
python
from docapi import DocAPI
client = DocAPI("pk_live_...")
# Generate a PDF
pdf = client.pdf("<h1>Hello World</h1>", format="A4")
with open("output.pdf", "wb") as f:
f.write(pdf)
# Screenshot a URL
img = 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.

python
pdf = client.pdf(html)
if (client.credits_remaining or 999) < 50:
# trigger USDC top-up
pass

Agent registration

python
from docapi import DocAPI
# No API key needed โ€” static method
account = DocAPI.register(notify_email="[email protected]")
print(account["api_key"]) # "pk_..."
print(account["usdc_address"]) # "0x..."
print(account["free_calls"]) # 10

Error handling

python
from docapi import DocAPI, DocAPIError
try:
pdf = client.pdf(html)
except DocAPIError as e:
print(e.status) # 401 | 402 | 429 | 500
print(e.code) # "invalid_api_key" | "credits_exhausted" | ...
print(e.message)

View on PyPI ยท GitHub ยท Zero dependencies ยท Python 3.8+ ยท Full type hints

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

bash
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.

http
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.

bash
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

json
{
"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": {
"low_balance_email": "[email protected]",
"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.

bash
curl https://www.docapi.co/api/topup \
-H "x-api-key: pk_4a7f2b9c1d3e..."

Response

json
{
"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
HTTP/2 200
Content-Type: application/pdf
X-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.

Python (with Coinbase AgentKit)
import requests
from coinbase_agentkit import CdpAgentkitWrapper
API_KEY = "pk_..."
USDC_ADDRESS = "0x..." # from registration response
THRESHOLD = 50
TOPUP_USDC = 10
agentkit = CdpAgentkitWrapper()
_topup_pending = False
def generate_pdf(html: str) -> bytes:
global _topup_pending
resp = 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 = True
try:
agentkit.run(f"Send {TOPUP_USDC} USDC to {USDC_ADDRESS} on base-mainnet")
finally:
_topup_pending = False
resp.raise_for_status()
return resp.content
JavaScript (with Coinbase AgentKit)
import { sendUsdc } from '@coinbase/agentkit';
const API_KEY = 'pk_...';
const USDC_ADDRESS = '0x...'; // from registration response
const 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

json
{
"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

Node.js
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)

json
{
"url": "https://example.com",
"options": {
"width": 1280,
"height": 800,
"fullPage": false,
"format": "png"
}
}

Request body (HTML)

json
{
"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

json
{
"plan": "free",
"usage": {
"current": 47,
"limit": 100,
"period": "2025-01"
}
}

Example

bash
curl https://api.docapi.co/v1/usage \
-H "x-api-key: pk_live_xxx"

Options Reference

Available options for PDF generation.

OptionTypeDefaultDescription
formatstring"A4"Page format (A4, Letter, Legal, Tabloid)
widthstring-Custom width (e.g., "800px")
heightstring-Custom height (e.g., "600px")
marginobject-{ top, right, bottom, left }
printBackgroundbooleantrueInclude background colors/images
scalenumber1Scale factor (0.1 to 2)
landscapebooleanfalseUse landscape orientation
pageRangesstring-Pages to print (e.g., "1-5, 8")

Error Codes

Common error responses you may encounter.

CodeStatusDescription
missing_api_key401No API key provided in request headers
invalid_api_key401API key not found or has been revoked
missing_html400The html field is required for /v1/pdf
missing_input400Either url or html is required for /v1/screenshot
usage_limit_exceeded429Monthly API call limit reached. Upgrade your plan.
credits_exhausted402Agent account has no credits remaining. Send USDC to your usdc_address to top up.
generation_failed500PDF generation failed. Check your HTML for errors.

Error response format

json
{
"error": {
"code": "usage_limit_exceeded",
"message": "You have exceeded your monthly API call limit."
}
}

Code Examples

Complete examples in popular languages.

cURL

bash
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

javascript
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

python
import requests
import os
def 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
<?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";
Documentation | Doc API