Skip to main content

Documents API

Generate PDF and Excel documents programmatically from your templates.

Overview

The Documents API allows you to:

  • Generate single documents from templates
  • Batch generate multiple documents
  • Track generation job status
  • Download generated documents via signed URLs

Authentication

All endpoints require authentication via API key:

Authorization: Bearer YOUR_API_KEY

Generate Document

Generate a single document from a template.

POST /api/v1/documents/generate

Request Body

FieldTypeRequiredDescription
templateIdstringYesTemplate ID (UUID, shortId, or slug)
formatstringYesOutput format: pdf or xlsx
variablesobjectNoTemplate variables
filenamestringNoCustom filename (without extension)
metadataobjectNoCustom metadata to attach
useCreditbooleanNoForce use of premium credits instead of free quota. Documents generated with credits have no watermark. Default: false

Example Request

curl -X POST https://api.rynko.dev/v1/documents/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "tmpl_invoice",
"format": "pdf",
"variables": {
"invoiceNumber": "INV-2025-001",
"customerName": "Acme Corporation",
"amount": 1250.00,
"lineItems": [
{"description": "Consulting", "quantity": 10, "price": 100},
{"description": "Development", "quantity": 5, "price": 50}
]
},
"filename": "invoice-2025-001"
}'

Response

Document generation is an async operation. The initial response returns job info with queued status:

{
"jobId": "job_abc123def456",
"status": "queued",
"statusUrl": "https://api.rynko.dev/api/v1/documents/jobs/job_abc123def456",
"estimatedWaitSeconds": 5
}

To get the download URL, poll the job status endpoint or use webhooks.

Response Fields

FieldTypeDescription
jobIdstringUnique job identifier
statusstringJob status: queued for new requests
statusUrlstringURL to check job status
estimatedWaitSecondsnumberEstimated time until completion

Batch Generate

Generate multiple documents in a single request.

POST /api/v1/documents/generate/batch

Request Body

FieldTypeRequiredDescription
templateIdstringYesTemplate ID
formatstringYesOutput format: pdf or xlsx
documentsarrayYesArray of document specifications
documents[].variablesobjectYesVariables for this document
documents[].filenamestringNoCustom filename
documents[].metadataobjectNoCustom metadata
useCreditbooleanNoForce use of premium credits instead of free quota. Documents generated with credits have no watermark. Default: false

Example Request

curl -X POST https://api.rynko.dev/v1/documents/generate/batch \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "tmpl_invoice",
"format": "pdf",
"documents": [
{
"variables": {"invoiceNumber": "INV-001", "customerName": "Acme Corp", "amount": 100},
"filename": "invoice-001"
},
{
"variables": {"invoiceNumber": "INV-002", "customerName": "Beta Inc", "amount": 200},
"filename": "invoice-002"
},
{
"variables": {"invoiceNumber": "INV-003", "customerName": "Gamma Ltd", "amount": 300},
"filename": "invoice-003"
}
]
}'

Response

{
"batchId": "batch_xyz789",
"status": "processing",
"totalDocuments": 3,
"completedDocuments": 0,
"failedDocuments": 0,
"createdAt": "2025-01-15T10:00:00Z"
}

Get Job Status

Check the status of a document generation job.

GET /api/v1/documents/jobs/:jobId

Example Request

curl https://api.rynko.dev/v1/documents/jobs/job_abc123def456 \
-H "Authorization: Bearer YOUR_API_KEY"

Response

{
"jobId": "job_abc123def456",
"status": "completed",
"format": "pdf",
"templateId": "tmpl_invoice",
"downloadUrl": "https://storage.rynko.dev/documents/abc123.pdf?signature=...",
"expiresAt": "2025-01-15T12:00:00Z",
"createdAt": "2025-01-15T10:00:00Z",
"completedAt": "2025-01-15T10:00:05Z"
}

Get Batch Status

Check the status of a batch generation.

GET /api/v1/documents/batches/:batchId

Example Request

curl https://api.rynko.dev/v1/documents/batches/batch_xyz789 \
-H "Authorization: Bearer YOUR_API_KEY"

Response

{
"batchId": "batch_xyz789",
"status": "completed",
"totalDocuments": 3,
"completedDocuments": 3,
"failedDocuments": 0,
"documents": [
{
"jobId": "job_001",
"status": "completed",
"downloadUrl": "https://storage.rynko.dev/documents/001.pdf?signature=..."
},
{
"jobId": "job_002",
"status": "completed",
"downloadUrl": "https://storage.rynko.dev/documents/002.pdf?signature=..."
},
{
"jobId": "job_003",
"status": "completed",
"downloadUrl": "https://storage.rynko.dev/documents/003.pdf?signature=..."
}
],
"createdAt": "2025-01-15T10:00:00Z",
"completedAt": "2025-01-15T10:00:15Z"
}

List Jobs

List all document generation jobs.

GET /api/v1/documents/jobs

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
limitinteger20Items per page (max 100)
statusstring-Filter by status
templateIdstring-Filter by template

Example Request

curl "https://api.rynko.dev/v1/documents/jobs?limit=10&status=completed" \
-H "Authorization: Bearer YOUR_API_KEY"

Response

{
"data": [
{
"jobId": "job_abc123",
"status": "completed",
"format": "pdf",
"templateId": "tmpl_invoice",
"createdAt": "2025-01-15T10:00:00Z"
}
],
"meta": {
"page": 1,
"limit": 10,
"total": 150,
"totalPages": 15
}
}

Export Jobs

Export document job logs to CSV or JSON format.

GET /api/v1/documents/jobs/export

Query Parameters

ParameterTypeDefaultDescription
formatstringcsvExport format: csv or json
startDatestring-Filter by start date
endDatestring-Filter by end date
statusstring-Filter by status

Response

Returns a file download with the exported data.


Retry Failed Job

Retry a failed document generation job.

POST /api/v1/documents/jobs/:jobId/retry

Path Parameters

ParameterTypeDescription
jobIdstringJob ID to retry

Response

{
"jobId": "job_new_abc123",
"status": "pending",
"message": "Job queued for retry"
}

Delete Job

Delete a single document job record.

DELETE /api/v1/documents/jobs/:jobId

Path Parameters

ParameterTypeDescription
jobIdstringJob ID to delete

Response

Returns 204 No Content on success.


Bulk Delete Jobs

Delete multiple document job records.

DELETE /api/v1/documents/jobs/bulk

Request Body

FieldTypeRequiredDescription
jobIdsarrayYesArray of job IDs to delete

Example Request

{
"jobIds": ["job_001", "job_002", "job_003"]
}

Response

{
"deleted": 3,
"message": "Jobs deleted successfully"
}

Bulk Retry Jobs

Retry multiple failed document generation jobs.

POST /api/v1/documents/jobs/bulk/retry

Request Body

FieldTypeRequiredDescription
jobIdsarrayYesArray of job IDs to retry

Example Request

{
"jobIds": ["job_001", "job_002", "job_003"]
}

Response

{
"queued": 3,
"message": "Jobs queued for retry"
}

Get Analytics

Get document generation analytics for your team.

GET /api/v1/documents/analytics

Query Parameters

ParameterTypeDescription
startDatestringFilter by start date (ISO format)
endDatestringFilter by end date (ISO format)

Example Request

curl "https://api.rynko.dev/api/v1/documents/analytics?startDate=2025-01-01&endDate=2025-01-31" \
-H "Authorization: Bearer YOUR_API_KEY"

Response

{
"totalDocuments": 1250,
"completedDocuments": 1200,
"failedDocuments": 50,
"byFormat": {
"pdf": 1000,
"xlsx": 250
},
"byDate": [
{"date": "2025-01-01", "count": 45},
{"date": "2025-01-02", "count": 52}
]
}

Job Statuses

StatusDescription
pendingJob is queued
processingDocument is being generated
completedDocument ready for download
failedGeneration failed (check errorMessage field)

Error Codes

CodeHTTPDescription
ERR_TMPL_001404Template not found
ERR_TMPL_002404Document template not found
ERR_TMPL_008400Template schema validation failed
ERR_VALID_002400Variable validation failed
ERR_QUOTA_003429Rate limit exceeded
ERR_QUOTA_008429Monthly document generation quota exceeded
ERR_QUOTA_011429Insufficient document credits
ERR_LIMIT_001400PDF page limit exceeded
ERR_LIMIT_003400Excel row limit exceeded
ERR_LIMIT_007400Loop iteration limit exceeded

See Error Codes for the complete error code reference.


Code Examples

Node.js

import { Rynko } from '@rynko/sdk';

const client = new Rynko({ apiKey: process.env.RYNKO_API_KEY });

// Queue document generation (async operation)
const job = await client.documents.generate({
templateId: 'tmpl_invoice',
format: 'pdf',
variables: {
invoiceNumber: 'INV-2025-001',
customerName: 'Acme Corporation',
amount: 1250.00
},
metadata: {
orderId: 'ord_12345',
customerId: 'cust_67890'
}
});

console.log('Job ID:', job.jobId);
console.log('Status:', job.status); // 'queued'

// Wait for completion to get download URL
const completed = await client.documents.waitForCompletion(job.jobId);
console.log('Download URL:', completed.downloadUrl);
console.log('Metadata:', completed.metadata); // { orderId: 'ord_12345', ... }

Python

from rynko import Rynko

client = Rynko(api_key=os.environ['RYNKO_API_KEY'])

# Queue document generation (async operation)
job = client.documents.generate(
template_id='tmpl_invoice',
format='pdf',
variables={
'invoiceNumber': 'INV-2025-001',
'customerName': 'Acme Corporation',
'amount': 1250.00
},
metadata={
'orderId': 'ord_12345',
'customerId': 'cust_67890'
}
)

print(f"Job ID: {job['jobId']}")
print(f"Status: {job['status']}") # 'queued'

# Wait for completion to get download URL
completed = client.documents.wait_for_completion(job['jobId'])
print(f"Download URL: {completed['downloadUrl']}")
print(f"Metadata: {completed['metadata']}") # {'orderId': 'ord_12345', ...}

Java

import dev.rynko.Rynko;
import dev.rynko.models.GenerateRequest;
import dev.rynko.models.GenerateResult;
import java.util.Map;

Rynko client = new Rynko(System.getenv("RYNKO_API_KEY"));

// Queue document generation (async operation)
GenerateResult job = client.documents().generate(
GenerateRequest.builder()
.templateId("tmpl_invoice")
.format("pdf")
.variable("invoiceNumber", "INV-2025-001")
.variable("customerName", "Acme Corporation")
.variable("amount", 1250.00)
.metadata(Map.of("orderId", "ord_12345", "customerId", "cust_67890"))
.build()
);

System.out.println("Job ID: " + job.getJobId());
System.out.println("Status: " + job.getStatus()); // "queued"

// Wait for completion to get download URL
GenerateResult completed = client.documents().waitForCompletion(job.getJobId());
System.out.println("Download URL: " + completed.getDownloadUrl());
System.out.println("Metadata: " + completed.getMetadata()); // {orderId=ord_12345, ...}

Metadata

Attach custom metadata to document generation requests for tracking and correlation purposes. Metadata is passed through to API responses and webhook payloads.

Usage

Include a metadata object in your generate request:

{
"templateId": "tmpl_invoice",
"format": "pdf",
"variables": { ... },
"metadata": {
"orderId": "ord_12345",
"customerId": "cust_67890",
"source": "api",
"rowNumber": 42
}
}

Constraints

ConstraintValue
StructureFlat object (no nested objects)
Max size10 KB
Value typesstring, number, boolean, null

In Job Status Response

Metadata is included in job status responses:

{
"jobId": "job_abc123def456",
"status": "completed",
"format": "pdf",
"templateId": "tmpl_invoice",
"downloadUrl": "https://storage.rynko.dev/documents/abc123.pdf?signature=...",
"metadata": {
"orderId": "ord_12345",
"customerId": "cust_67890",
"source": "api",
"rowNumber": 42
},
"createdAt": "2025-01-15T10:00:00Z",
"completedAt": "2025-01-15T10:00:05Z"
}

In Webhook Payloads

Metadata is passed through to webhook events:

{
"id": "evt_abc123",
"type": "document.generated",
"timestamp": "2025-01-15T10:00:05Z",
"data": {
"jobId": "job_abc123def456",
"status": "completed",
"downloadUrl": "https://storage.rynko.dev/documents/abc123.pdf?signature=...",
"metadata": {
"orderId": "ord_12345",
"customerId": "cust_67890",
"source": "api",
"rowNumber": 42
}
}
}

Use Cases

  • Order tracking: Link documents to orders in your system
  • User attribution: Track which user triggered generation
  • Batch correlation: Tag documents from the same batch run
  • Source tracking: Identify where requests originated (API, webhook, Sheets Add-on)
  • Custom identifiers: Store your internal IDs for later lookup

Batch Metadata

For batch generation, you can set metadata at the batch level (applies to all documents) or per-document:

{
"templateId": "tmpl_invoice",
"format": "pdf",
"metadata": {
"batchRunId": "run_20250115",
"triggeredBy": "scheduled_job"
},
"documents": [
{
"variables": { "invoiceNumber": "INV-001" },
"metadata": { "rowNumber": 1 }
},
{
"variables": { "invoiceNumber": "INV-002" },
"metadata": { "rowNumber": 2 }
}
]
}

Webhooks

Subscribe to document generation events:

EventDescription
document.generatedDocument successfully generated
document.failedDocument generation failed
batch.completedAll documents in batch completed

See Webhooks for setup instructions.