API Reference
Convert AFP (Advanced Function Presentation) files to PDF via a single HTTP endpoint. No dependencies, no setup — just send a file, get a PDF back.
How it works
One endpoint. Send your AFP file, receive a PDF binary. That's it.
https://scribo-i9ld.polsia.appAll endpoints accept and return JSON for metadata. The conversion endpoint returns a raw PDF binary.
Scribo accepts AFP files in two upload modes:
- Raw binary — send the AFP file as the request body with
Content-Type: application/octet-stream - Multipart form — send as a standard file upload with
Content-Type: multipart/form-data(field name:file)
On success, the response is a raw application/pdf binary with metadata in response headers (page count, processing time, document name).
API keys
The conversion endpoint requires an API key. Pass it in the Authorization header as a Bearer token.
Authorization: Bearer sk_your_api_key_here
API keys look like sk_ followed by a 32-character hex string. Keep them secret — treat them like passwords.
Getting a key
Call POST /api/keys with your email address. Free-tier keys are issued instantly — no credit card required.
curl -X POST \ https://scribo-i9ld.polsia.app/api/keys \ -H "Content-Type: application/json" \ -d '{"email": "you@company.com"}'
{
"success": true,
"api_key": "sk_3f7a2b1c8d4e9f0a1b2c3d4e5f6a7b8c",
"plan": "free",
"usage": 0,
"limit": 100,
"message": "API key created. Include it as: Authorization: Bearer sk_..."
}
POST /api/keys with the same email returns your existing key — so you don't need to store it anywhere special.Get your API key
Free-tier keys are provisioned instantly. 100 conversions per month, no credit card.
Request a free API key
Instant · No credit cardPaste and run this in your terminal, replacing the email:
curl -X POST \
https://scribo-i9ld.polsia.app/api/keys \
-H "Content-Type: application/json" \
-d '{"email": "you@company.com"}'
Your key arrives in the JSON response. Copy the api_key value.
POST /api/convert
Convert an AFP file to PDF. Requires an API key. Returns the PDF binary on success.
Request headers
| Header | Type | Description |
|---|---|---|
| Authorization required | string | Bearer token — Bearer sk_your_api_key |
| Content-Type optional | string | application/octet-stream for raw binary, or multipart/form-data for form upload. Auto-detected if omitted. |
Request body
Send the AFP file as the raw request body (application/octet-stream) or as a multipart form upload with the field name file.
Maximum file size: 50 MB.
Response — 200 OK
On success, returns Content-Type: application/pdf with the PDF binary. Metadata is provided in response headers.
# Response headers Content-Type: application/pdf Content-Disposition: attachment; filename="DOCNAME.pdf" X-Page-Count: 4 # number of pages in the PDF X-Processing-Time-Ms: 8 # server-side conversion time (ms) X-Document-Name: STMT_2024_Q4 # document name from AFP metadata X-Renderer-Version: 2 # internal renderer version
Example: raw binary upload
curl -X POST \ https://scribo-i9ld.polsia.app/api/convert \ -H "Authorization: Bearer sk_your_api_key" \ -H "Content-Type: application/octet-stream" \ --data-binary @document.afp \ -o output.pdf
Example: multipart form upload
curl -X POST \ https://scribo-i9ld.polsia.app/api/convert \ -H "Authorization: Bearer sk_your_api_key" \ -F "file=@document.afp" \ -o output.pdf
POST /api/demo/convert
Key-free demo conversion. No authentication required. Rate-limited by IP to prevent abuse.
Same request format as POST /api/convert but no API key required. Intended for the browser-based demo on the landing page.
POST /api/convert with an API key for production workloads.On success, returns the PDF binary inline (Content-Disposition: inline). Also sets X-Demo-Remaining in response headers to show how many demo calls remain.
curl -X POST \ https://scribo-i9ld.polsia.app/api/demo/convert \ -F "file=@document.afp" \ -o preview.pdf
POST /api/keys
Generate or retrieve a free-tier API key. Idempotent — calling with the same email always returns the same key.
Request body (JSON)
| Field | Type | Description |
|---|---|---|
| email required | string | Your email address. Used to identify your key — no spam, no newsletter. |
{
"success": true,
"api_key": "sk_3f7a2b1c8d4e9f0a1b2c3d4e5f6a7b8c",
"plan": "free",
"usage": 0,
"limit": 100,
"message": "API key created. Include it as: Authorization: Bearer sk_..."
}
GET /api/usage
Check how many conversions you've used this billing period and when your quota resets.
Pass your API key as a Bearer token. Returns usage and plan details.
{
"success": true,
"usage": 12,
"limit": 100,
"plan": "free",
"resets_at": "2026-05-19T00:00:00.000Z"
}
curl https://scribo-i9ld.polsia.app/api/usage \ -H "Authorization: Bearer sk_your_api_key"
Rate limits
Limits are per API key and reset every 30 days.
| Plan | Conversions / Month | Max File Size | Support |
|---|---|---|---|
| Free | 100 | 50 MB | Community |
| Pro | 10,000 | 50 MB | Priority email |
| Demo (no key) | 10 / hour (per IP) | 50 MB | — |
When you hit your limit, the API returns HTTP 429 with a JSON error and a resets_at timestamp. Contact us to upgrade to Pro.
Error codes
All errors return JSON with a success: false field and a human-readable error message.
400401Authorization header format: Bearer sk_your_key.
413429resets_at timestamp. Upgrade to Pro for 10,000/month.
500503Error response shape
{
"success": false,
"error": "File does not appear to be in AFP format...",
"details": [] // optional — parse error details for 400s
}
Response headers
On a successful conversion, these headers are set alongside the PDF binary:
| Header | Description |
|---|---|
| X-Page-Count | Number of pages in the rendered PDF. |
| X-Processing-Time-Ms | Server-side conversion time in milliseconds. |
| X-Document-Name | Document name extracted from AFP metadata. |
| X-Renderer-Version | Internal AFP renderer version for debugging. |
| X-Demo-Remaining | (/api/demo/convert only) Demo calls remaining this hour. |
Integrate in minutes
Copy-paste examples for the most common languages. Replace sk_your_api_key with your actual key.
# Raw binary upload — saves result to output.pdf curl -X POST \ https://scribo-i9ld.polsia.app/api/convert \ -H "Authorization: Bearer sk_your_api_key" \ -H "Content-Type: application/octet-stream" \ --data-binary @document.afp \ -o output.pdf # Multipart form upload (easier for most shells) curl -X POST \ https://scribo-i9ld.polsia.app/api/convert \ -H "Authorization: Bearer sk_your_api_key" \ -F "file=@document.afp" \ -o output.pdf
// Node.js 18+ — uses built-in fetch import { readFileSync, writeFileSync } from 'fs'; const API_KEY = 'sk_your_api_key'; const afpData = readFileSync('./document.afp'); const response = await fetch('https://scribo-i9ld.polsia.app/api/convert', { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/octet-stream', }, body: afpData, }); if (!response.ok) { const err = await response.json(); throw new Error(`Conversion failed: ${err.error}`); } // Save PDF to disk const pdfBuffer = Buffer.from(await response.arrayBuffer()); writeFileSync('./output.pdf', pdfBuffer); // Inspect metadata from headers console.log('Pages:', response.headers.get('x-page-count')); console.log('Time:', response.headers.get('x-processing-time-ms'), 'ms');
# pip install requests import requests API_KEY = "sk_your_api_key" with open("document.afp", "rb") as f: afp_data = f.read() response = requests.post( "https://scribo-i9ld.polsia.app/api/convert", headers={"Authorization": f"Bearer {API_KEY}"}, data=afp_data, # or use files={"file": open("document.afp", "rb")} for multipart ) response.raise_for_status() # raises on 4xx/5xx with open("output.pdf", "wb") as f: f.write(response.content) print(f"Pages: {response.headers.get('X-Page-Count')}") print(f"Time: {response.headers.get('X-Processing-Time-Ms')}ms")
// Java 11+ HttpClient (built-in, no dependencies) import java.net.URI; import java.net.http.*; import java.nio.file.*; var client = HttpClient.newHttpClient(); var afpBytes = Files.readAllBytes(Path.of("document.afp")); var request = HttpRequest.newBuilder() .uri(URI.create("https://scribo-i9ld.polsia.app/api/convert")) .header("Authorization", "Bearer sk_your_api_key") .header("Content-Type", "application/octet-stream") .POST(HttpRequest.BodyPublishers.ofByteArray(afpBytes)) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofByteArray()); if (response.statusCode() != 200) { throw new RuntimeException("Error: " + response.statusCode()); } Files.write(Path.of("output.pdf"), response.body()); System.out.println("Pages: " + response.headers().firstValue("x-page-count").orElse("?")); System.out.println("Time: " + response.headers().firstValue("x-processing-time-ms").orElse("?") + "ms");
Interactive curl command
Paste your API key below to generate a ready-to-run curl command.
POST /api/convert
Paste your key, copy the commandcurl -X POST \ https://scribo-i9ld.polsia.app/api/convert \ -H "Authorization: Bearer sk_your_api_key" \ -H "Content-Type: application/octet-stream" \ --data-binary @document.afp \ -o output.pdf
Replace document.afp with the path to your AFP file.
Don't have an API key yet? Get one free →