Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
PDF.co API integration with managed OAuth. Convert, merge, split, edit PDFs and extract data. Use this skill when users want to convert PDFs to/from other fo...
PDF.co API integration with managed OAuth. Convert, merge, split, edit PDFs and extract data. Use this skill when users want to convert PDFs to/from other fo...
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Access the PDF.co API with managed authentication. Convert, merge, split, and edit PDFs with full document manipulation capabilities.
# Get PDF info python <<'EOF' import urllib.request, os, json data = json.dumps({'url': 'https://example.com/sample.pdf'}).encode() req = urllib.request.Request('https://gateway.maton.ai/pdf-co/v1/pdf/info', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
https://gateway.maton.ai/pdf-co/{native-api-path} Replace {native-api-path} with the actual PDF.co API endpoint path. The gateway proxies requests to api.pdf.co and automatically injects your API credentials.
All requests require the Maton API key in the Authorization header: Authorization: Bearer $MATON_API_KEY Environment Variable: Set your API key as MATON_API_KEY: export MATON_API_KEY="YOUR_API_KEY"
Sign in or create an account at maton.ai Go to maton.ai/settings Copy your API key
Manage your PDF.co connections at https://ctrl.maton.ai.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=pdf-co&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'pdf-co'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF Response: { "connection": { "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80", "status": "ACTIVE", "creation_time": "2025-12-08T07:20:53.488460Z", "last_updated_time": "2026-01-31T20:03:32.593153Z", "url": "https://connect.maton.ai/?session_token=...", "app": "pdf-co", "metadata": {} } } Open the returned url in a browser to complete authorization.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If you have multiple PDF.co connections, specify which one to use with the Maton-Connection header: python <<'EOF' import urllib.request, os, json data = json.dumps({'url': 'https://example.com/sample.pdf'}).encode() req = urllib.request.Request('https://gateway.maton.ai/pdf-co/v1/pdf/info', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF If omitted, the gateway uses the default (oldest) active connection.
Get metadata and information about a PDF file. POST /pdf-co/v1/pdf/info Content-Type: application/json { "url": "https://example.com/document.pdf" }
POST /pdf-co/v1/pdf/convert/to/text Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "0-", "inline": true } Response: { "body": "Extracted text content...", "pageCount": 5, "error": false, "status": 200, "name": "document.txt", "credits": 10, "remainingCredits": 9990 }
POST /pdf-co/v1/pdf/convert/to/csv Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "0-", "inline": true, "lang": "eng" }
POST /pdf-co/v1/pdf/convert/to/json Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "0-", "inline": true }
POST /pdf-co/v1/pdf/convert/to/html Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "0-", "name": "output.html" }
POST /pdf-co/v1/pdf/convert/to/xlsx Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "0-", "name": "output.xlsx" }
POST /pdf-co/v1/pdf/convert/to/png Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "0", "name": "page.png" }
POST /pdf-co/v1/pdf/convert/to/jpg Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "0", "name": "page.jpg" }
POST /pdf-co/v1/pdf/convert/from/html Content-Type: application/json { "html": "<html><body><h1>Hello World</h1></body></html>", "name": "output.pdf", "paperSize": "Letter", "orientation": "Portrait", "margins": "10 10 10 10" } Response: { "url": "https://pdf-temp-files.s3.amazonaws.com/...", "pageCount": 1, "error": false, "status": 200, "name": "output.pdf", "remainingCredits": 9980 }
POST /pdf-co/v1/pdf/convert/from/url Content-Type: application/json { "url": "https://example.com", "name": "webpage.pdf", "paperSize": "A4", "orientation": "Portrait" }
Combine multiple PDFs into a single document. POST /pdf-co/v1/pdf/merge Content-Type: application/json { "url": "https://example.com/doc1.pdf,https://example.com/doc2.pdf", "name": "merged.pdf" } Response: { "url": "https://pdf-temp-files.s3.amazonaws.com/merged.pdf", "pageCount": 10, "error": false, "status": 200, "name": "merged.pdf", "remainingCredits": 9970, "duration": 1500 }
Split a PDF into multiple files. POST /pdf-co/v1/pdf/split Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "1-3,4-6,7-" } Response: { "urls": [ "https://pdf-temp-files.s3.amazonaws.com/part1.pdf", "https://pdf-temp-files.s3.amazonaws.com/part2.pdf", "https://pdf-temp-files.s3.amazonaws.com/part3.pdf" ], "pageCount": 10, "error": false, "status": 200, "remainingCredits": 9960 }
POST /pdf-co/v1/pdf/edit/delete-pages Content-Type: application/json { "url": "https://example.com/document.pdf", "pages": "2,4,6" }
Add text, images, or other content to a PDF. POST /pdf-co/v1/pdf/edit/add Content-Type: application/json { "url": "https://example.com/document.pdf", "name": "annotated.pdf", "annotations": [ { "text": "CONFIDENTIAL", "x": 100, "y": 100, "size": 24, "pages": "0-" } ] }
POST /pdf-co/v1/pdf/edit/replace-text Content-Type: application/json { "url": "https://example.com/document.pdf", "searchString": "old text", "replaceString": "new text" }
POST /pdf-co/v1/pdf/edit/delete-text Content-Type: application/json { "url": "https://example.com/document.pdf", "searchString": "text to remove" }
POST /pdf-co/v1/pdf/security/add Content-Type: application/json { "url": "https://example.com/document.pdf", "ownerPassword": "owner123", "userPassword": "user456" }
POST /pdf-co/v1/pdf/security/remove Content-Type: application/json { "url": "https://example.com/document.pdf", "password": "currentpassword" }
Automatically extract structured data from invoices. POST /pdf-co/v1/ai-invoice-parser Content-Type: application/json { "url": "https://example.com/invoice.pdf" }
Extract data using templates. POST /pdf-co/v1/pdf/documentparser Content-Type: application/json { "url": "https://example.com/document.pdf", "templateId": "your-template-id" }
POST /pdf-co/v1/barcode/generate Content-Type: application/json { "value": "1234567890", "type": "QRCode", "name": "barcode.png" }
POST /pdf-co/v1/barcode/read/from/url Content-Type: application/json { "url": "https://example.com/barcode.png", "types": "QRCode,Code128,Code39,EAN13,UPCA" }
For async operations, check job status. POST /pdf-co/v1/job/check Content-Type: application/json { "jobId": "abc123" }
For large files or batch operations, use async processing: POST /pdf-co/v1/pdf/merge Content-Type: application/json { "url": "https://example.com/large1.pdf,https://example.com/large2.pdf", "async": true, "name": "merged.pdf" } Response: { "jobId": "abc123", "status": "working", "error": false } Then poll the job status: POST /pdf-co/v1/job/check Content-Type: application/json { "jobId": "abc123" }
const response = await fetch( 'https://gateway.maton.ai/pdf-co/v1/pdf/merge', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://example.com/doc1.pdf,https://example.com/doc2.pdf', name: 'merged.pdf' }) } ); const result = await response.json(); console.log(result.url);
import os import requests response = requests.post( 'https://gateway.maton.ai/pdf-co/v1/pdf/merge', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, json={ 'url': 'https://example.com/doc1.pdf,https://example.com/doc2.pdf', 'name': 'merged.pdf' } ) result = response.json() print(result['url'])
All file URLs must be publicly accessible or use PDF.co temporary storage Multiple URLs for merge operations should be comma-separated Page indices are 0-based (first page is 0) Page ranges use format: 0-2 (pages 0,1,2), 3- (page 3 to end), 0,2,4 (specific pages) Output files are stored temporarily and expire after 60 minutes by default Use async: true for large files to avoid timeout Use inline: true to get content directly in response instead of URL IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments
StatusMeaning400Missing PDF.co connection or invalid request401Invalid or missing Maton API key429Rate limited4xx/5xxPassthrough error from PDF.co API
Check that the MATON_API_KEY environment variable is set: echo $MATON_API_KEY Verify the API key is valid by listing connections: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Ensure your URL path starts with pdf-co. For example: Correct: https://gateway.maton.ai/pdf-co/v1/pdf/merge Incorrect: https://gateway.maton.ai/v1/pdf/merge
PDF.co API Documentation PDF.co API Reference Maton Community Maton Support
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.