Quickstart
Generate your first document — PDF or DOCX — in under 5 minutes.
1. Get your API key
Sign in to DocPayload and open Dashboard > Settings > API access > Manage keys > Generate Key. A key is a Client ID and a Client secret: copy the secret right away, it is shown only once. Note your Tenant ID from the same dialog.
2. Get an access token
Exchange the Client ID and secret for an access token:
curl -X POST https://api.docpayload.com/v1/api-auth/token -H "Content-Type: application/json" -d '{ "clientId": "YOUR_CLIENT_ID", "clientSecret": "YOUR_CLIENT_SECRET" }'
# { "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 3600, ... }
Every other call sends Authorization: Bearer YOUR_ACCESS_TOKEN. The token lasts an hour: reuse it until it expires rather than requesting one per call. See Authentication for the details.
3. Create a document definition
A document definition is a JSON object that describes your document. The same definition renders to PDF or DOCX — you choose the format at request time.
{
"document": {
"metadata": {
"title": "My First Document",
"author": "DocPayload"
},
"pageSetup": {
"size": "A4",
"orientation": "portrait",
"margin": [50, 40, 50, 40]
},
"styles": {
"title": { "fontSize": 22, "fontWeight": "bold", "color": "#1A1A2E" },
"body": { "fontSize": 11, "color": "#333333", "textAlign": "justify" }
},
"content": [
{ "p": "Hello from DocPayload!", "style": "title" },
{ "p": "This document was generated from a JSON definition using the DocPayload API. You can add [b]bold text[/b], [i]italic text[/i], [color, #0066CC]colored text[/color], tables, lists, images, barcodes, and much more.", "style": "body" }
]
}
}
4. Generate a document
Append /pdf or /docx to the endpoint to choose the output format. PDF is the default when omitted. The examples below use /pdf; each one generates the document, then downloads it with the same token.
- cURL
- C#
- JavaScript
- Python
curl -X POST https://api.docpayload.com/v1/{YOUR_TENANT_ID}/documents/generate-from-payload/pdf -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -H "Content-Type: application/json" -d @definition.json
# Download the file at the downloadUrl from the response, with the same token
curl "DOWNLOAD_URL" -H "Authorization: Bearer YOUR_ACCESS_TOKEN" -o document.pdf
using var client = new HttpClient();
// Exchange the API key for an access token
var tokenResponse = await client.PostAsJsonAsync(
"https://api.docpayload.com/v1/api-auth/token",
new
{
clientId = Environment.GetEnvironmentVariable("DOCPAYLOAD_CLIENT_ID"),
clientSecret = Environment.GetEnvironmentVariable("DOCPAYLOAD_CLIENT_SECRET"),
});
tokenResponse.EnsureSuccessStatusCode();
var token = (await tokenResponse.Content.ReadFromJsonAsync<JsonElement>())
.GetProperty("access_token").GetString();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
// Generate
var json = File.ReadAllText("definition.json");
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.docpayload.com/v1/{YOUR_TENANT_ID}/documents/generate-from-payload/pdf", content);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<JsonElement>();
var downloadUrl = result.GetProperty("downloadUrl").GetString();
// Download with the same token
var bytes = await client.GetByteArrayAsync(downloadUrl);
await File.WriteAllBytesAsync("document.pdf", bytes);
import { readFile, writeFile } from 'node:fs/promises';
// Exchange the API key for an access token
const tokenResponse = await fetch('https://api.docpayload.com/v1/api-auth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
clientId: process.env.DOCPAYLOAD_CLIENT_ID,
clientSecret: process.env.DOCPAYLOAD_CLIENT_SECRET,
}),
});
const { access_token } = await tokenResponse.json();
const auth = { 'Authorization': `Bearer ${access_token}` };
// Generate
const response = await fetch('https://api.docpayload.com/v1/{YOUR_TENANT_ID}/documents/generate-from-payload/pdf', {
method: 'POST',
headers: { ...auth, 'Content-Type': 'application/json' },
body: await readFile('definition.json', 'utf8'),
});
const { downloadUrl } = await response.json();
// Download with the same token
const file = await fetch(downloadUrl, { headers: auth });
await writeFile('document.pdf', Buffer.from(await file.arrayBuffer()));
import os
import requests
# Exchange the API key for an access token
token_response = requests.post(
"https://api.docpayload.com/v1/api-auth/token",
json={
"clientId": os.environ["DOCPAYLOAD_CLIENT_ID"],
"clientSecret": os.environ["DOCPAYLOAD_CLIENT_SECRET"],
},
)
token_response.raise_for_status()
auth = {"Authorization": f"Bearer {token_response.json()['access_token']}"}
# Generate
with open("definition.json", "rb") as f:
response = requests.post(
"https://api.docpayload.com/v1/{YOUR_TENANT_ID}/documents/generate-from-payload/pdf",
headers={**auth, "Content-Type": "application/json"},
data=f.read(),
)
response.raise_for_status()
download_url = response.json()["downloadUrl"]
# Download with the same token
file = requests.get(download_url, headers=auth)
file.raise_for_status()
with open("document.pdf", "wb") as out:
out.write(file.content)
The generate call answers with the document's downloadUrl:
{
"status": "Succeeded",
"documentId": "a1b2c3d4e5f67890abcdef1234567890",
"fileName": "docpayload_v1-a1b2c3d4e5f67890abcdef1234567890.pdf",
"downloadUrl": "https://api.docpayload.com/v1/{YOUR_TENANT_ID}/assets/docs/docpayload_v1-a1b2c3d4e5f67890abcdef1234567890.pdf",
"fileSizeBytes": 29811,
"errorCodes": []
}
5. Open your document
That's it! The downloadUrl needs the same Authorization: Bearer header as every other call, so fetch it with the token and save the bytes, as the examples do; opening the link in a browser without the header is answered 401.
Works with any stack
You just generated a document with a standard HTTP request. Replace /pdf with /docx to switch formats — same definition, same API call. If your stack can POST JSON, you're ready.
PHP with curl_exec, Java with HttpClient, Ruby with Net::HTTP, Go with net/http, WordPress with wp_remote_post, legacy systems with any HTTP library — they all work. The code you just saw in the examples above is all you need. No special library to install or keep updated.
Point your IDE at the published JSON Schema and you'll get autocomplete on every property and red squiggles on typos before you ever hit the API:
{
"$schema": "https://schemas.docpayload.com/v1/document-definition.schema.json",
"document": { "content": [{ "p": "Hello." }] }
}
That one line in your JSON file is all most editors need.
Next steps
- Document Definition — Learn the full schema
- Inline Formatting — Bold, italic, colors, images, barcodes
- Data Binding — Build reusable templates with dynamic data
- Playground — Try it live in the browser