PDF Convert
API de conversão de HTML em PDF, PNG ou JPG — fluxo assíncrono, batch, retenção e custos.
Envie HTML e CSS, receba um job assíncrono e baixe o arquivo quando estiver pronto. Suporta conversão unitária, batch com template, retenção configurável e sandbox JavaScript opcional.
- Base path
/v1/tools/document/pdf- Escopos
tools:pdf:readtools:pdf:managetools:manage
Visão geral
O PDF Convert é assíncrono:
POST /convertouPOST /batch→ 202 Accepted com oconversion_id(o{id}das demais rotas).- Um worker renderiza em background (Chromium headless).
- Acompanhe pelo callback
webhook_urlou consultandoGET /{id}. - Baixe com
GET /{id}/downloadquandostatusforcompleted.
Cobrança ao enfileirar
Os créditos são debitados quando o job é aceito. Se o enfileiramento de um batch falhar depois do débito, o valor é estornado automaticamente.
| Operação | Rota |
|---|---|
| Converter HTML em PDF/PNG/JPG | POST/convert |
| Batch com template | POST/batch |
| Reprocessar falha | POST/{id}/retry |
| Listar conversões | GET/ |
| Status da conversão | GET/{id} |
| Baixar arquivo | GET/{id}/download |
| Listar batches | GET/batches |
| Detalhe do batch | GET/batches/{id} |
| Download ZIP do batch | GET/batches/{id}/download |
| Listar templates salvos | GET/templates |
| Salvar template | POST/templates |
| Consultar template | GET/templates/{id} |
| Listar versões do template | GET/templates/{id}/versions |
| Renomear template ou salvar nova versão | PATCH/templates/{id} |
| Excluir template | DELETE/templates/{id} |
| Listar fontes | GET/fonts |
| Enviar fonte | POST/fonts |
| Excluir fonte | DELETE/fonts/{id} |
Custos
Por documento
| Item | Créditos | Notas |
|---|---|---|
| Conversão base | 1,0 | — |
| Retenção efêmera ou até 3 dias | +0,0 | retention_days 0 (~24h) a 3 |
| Retenção 4–7 dias | +0,5 | — |
| Retenção 8–30 dias | +2,5 | — |
| Retenção permanente | +15,0 | retention_days: -1 |
| Sandbox JavaScript | +0,25 | enable_js: true |
Pós-processamento e fontes — Somados ao custo do documento. Só `pdf` aceita pós-processamento.
| Item | Créditos | Notas |
|---|---|---|
| Marca d'água | +0,1 | post_process.watermark |
| Proteção por senha | +0,1 | post_process.protection |
| PDF/A-2b | +0,25 | post_process.pdfa |
| Fontes personalizadas | +0,05 | font_ids (uma vez por documento, não por fonte) |
Desconto de volume no batch — Aplicado sobre base, JavaScript e retenção de cada item.
| Item | Desconto |
|---|---|
| 10+ itens | 5% |
| 20+ itens | 10% |
| 30+ itens | 15% |
| 40+ itens | 20% |
O batch aceita até 500 itens. O retry cobra o custo integral novamente, inclusive os adicionais acima. Salvar templates e enviar fontes não custa créditos. Consultas e downloads via API seguem a franquia diária.
Conversão
Converter HTML em PDF/PNG/JPG
/v1/tools/document/pdf/convert- Custo
- Variável (ver custos)
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:pdf:managetools:manage
Envie html ou url (um dos dois, nunca os dois). Com url, o Chromium abre a página pública e a renderiza; css, google_fonts_url e data são recusados nesse modo (pdf.invalid_option).
| Campo | Limite / valores |
|---|---|
html | máx. 10 MB |
url | alternativa a html: endereço público http/https, até 2048 caracteres (pdf.invalid_url se for privado ou inválido) |
css | máx. 1 MB |
format | pdf (padrão), png, jpg / jpeg |
file_name | nome do arquivo gerado |
title, author, subject, keywords | metadados do documento, até 1000 caracteres cada |
header_html / footer_html | cabeçalho e rodapé repetidos em cada página |
google_fonts_url | URL de CSS do Google Fonts a carregar |
wait_selector / wait_delay | espera um seletor aparecer / um atraso em ms antes de renderizar |
enable_js / custom_js | executa JavaScript em sandbox (SPAs, gráficos) / script extra |
data | objeto com variáveis para placeholders {{campo}} no HTML |
retention_days | 0 (efêmero, ~24h), 1–30 ou -1 (permanente) |
webhook_url | recebe o callback ao terminar |
template_id, template_version, font_ids, post_process | templates salvos, fontes e pós-processamento |
Tamanho de página, margens, mídia, numeração e qualidade estão em Opções de página e render.
Guarde o conversion_id: é o {id} usado para consultar status e baixar o arquivo.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/convert' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440001' \
-H 'Content-Type: application/json' \
-d '{
"html": "<html><body><h1>Fatura</h1></body></html>",
"css": "body { font-family: sans-serif; }",
"format": "pdf",
"page_size": "A4",
"retention_days": 7
}'const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/convert', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'X-Idempotency-Key': '550e8400-e29b-41d4-a716-446655440001',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"html": "<html><body><h1>Fatura</h1></body></html>",
"css": "body { font-family: sans-serif; }",
"format": "pdf",
"page_size": "A4",
"retention_days": 7
}),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/document/pdf/convert",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
"X-Idempotency-Key": "550e8400-e29b-41d4-a716-446655440001",
},
json={
"html": "<html><body><h1>Fatura</h1></body></html>",
"css": "body { font-family: sans-serif; }",
"format": "pdf",
"page_size": "A4",
"retention_days": 7
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/convert');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440001',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"html": "<html><body><h1>Fatura</h1></body></html>",
"css": "body { font-family: sans-serif; }",
"format": "pdf",
"page_size": "A4",
"retention_days": 7
}
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/document/pdf/convert", strings.NewReader(`{
"html": "<html><body><h1>Fatura</h1></body></html>",
"css": "body { font-family: sans-serif; }",
"format": "pdf",
"page_size": "A4",
"retention_days": 7
}`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("X-Idempotency-Key", "550e8400-e29b-41d4-a716-446655440001")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 202
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"conversion_id": "3e4f5a6b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"job_id": "pdf_9b8c7d6e5f",
"status": "pending"
}
}Batch com template
/v1/tools/document/pdf/batch- Custo
- Soma dos itens com desconto
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:pdf:managetools:manage
| Campo | Descrição |
|---|---|
template.html | obrigatório — HTML com placeholders {{campo}} (sintaxe de Go template: {{if}}, {{range}} também funcionam) |
template.css | CSS compartilhado |
items[] | obrigatório, 1 a 500 itens: custom_id (obrigatório, seu identificador), file_name e data |
config | opções aplicadas a todos os itens: page_size, orientation, margens, format, scale, retention_days, google_fonts_url, header_html, footer_html, wait_selector, wait_delay, title, author, enable_js, custom_js e file_name_template |
delivery.method | zip ou list: como o resultado é entregue ao terminar |
delivery.webhook_url | recebe o callback ao terminar |
O batch não aceita url, template_id, font_ids nem post_process: ele usa sempre o template.html do corpo. Os descontos de volume se aplicam sobre base, JavaScript e retenção. Acompanhe o progresso em Detalhe do batch.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/batch' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440002' \
-H 'Content-Type: application/json' \
-d '{
"template": {
"html": "<html><body><h1>{{title}}</h1></body></html>",
"css": "h1 { color: #333; }"
},
"config": { "page_size": "A4", "format": "pdf", "retention_days": 7 },
"items": [
{ "custom_id": "fatura-001", "file_name": "fatura-001.pdf", "data": { "title": "Fatura 001" } },
{ "custom_id": "fatura-002", "file_name": "fatura-002.pdf", "data": { "title": "Fatura 002" } }
],
"delivery": { "method": "zip", "webhook_url": "https://example.com/hooks/pdf" }
}'const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/batch', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'X-Idempotency-Key': '550e8400-e29b-41d4-a716-446655440002',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"template": {
"html": "<html><body><h1>{{title}}</h1></body></html>",
"css": "h1 { color: #333; }"
},
"config": { "page_size": "A4", "format": "pdf", "retention_days": 7 },
"items": [
{ "custom_id": "fatura-001", "file_name": "fatura-001.pdf", "data": { "title": "Fatura 001" } },
{ "custom_id": "fatura-002", "file_name": "fatura-002.pdf", "data": { "title": "Fatura 002" } }
],
"delivery": { "method": "zip", "webhook_url": "https://example.com/hooks/pdf" }
}),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/document/pdf/batch",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
"X-Idempotency-Key": "550e8400-e29b-41d4-a716-446655440002",
},
json={
"template": {
"html": "<html><body><h1>{{title}}</h1></body></html>",
"css": "h1 { color: #333; }"
},
"config": { "page_size": "A4", "format": "pdf", "retention_days": 7 },
"items": [
{ "custom_id": "fatura-001", "file_name": "fatura-001.pdf", "data": { "title": "Fatura 001" } },
{ "custom_id": "fatura-002", "file_name": "fatura-002.pdf", "data": { "title": "Fatura 002" } }
],
"delivery": { "method": "zip", "webhook_url": "https://example.com/hooks/pdf" }
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/batch');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440002',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"template": {
"html": "<html><body><h1>{{title}}</h1></body></html>",
"css": "h1 { color: #333; }"
},
"config": { "page_size": "A4", "format": "pdf", "retention_days": 7 },
"items": [
{ "custom_id": "fatura-001", "file_name": "fatura-001.pdf", "data": { "title": "Fatura 001" } },
{ "custom_id": "fatura-002", "file_name": "fatura-002.pdf", "data": { "title": "Fatura 002" } }
],
"delivery": { "method": "zip", "webhook_url": "https://example.com/hooks/pdf" }
}
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/document/pdf/batch", strings.NewReader(`{
"template": {
"html": "<html><body><h1>{{title}}</h1></body></html>",
"css": "h1 { color: #333; }"
},
"config": { "page_size": "A4", "format": "pdf", "retention_days": 7 },
"items": [
{ "custom_id": "fatura-001", "file_name": "fatura-001.pdf", "data": { "title": "Fatura 001" } },
{ "custom_id": "fatura-002", "file_name": "fatura-002.pdf", "data": { "title": "Fatura 002" } }
],
"delivery": { "method": "zip", "webhook_url": "https://example.com/hooks/pdf" }
}`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("X-Idempotency-Key", "550e8400-e29b-41d4-a716-446655440002")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 202 — conversion_id é o id do batch
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"conversion_id": "3e4f5a6b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"job_id": "batch_1f2e3d4c",
"status": "processing"
}
}Reprocessar falha
/v1/tools/document/pdf/{id}/retry- Custo
- Custo completo novamente
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:managetools:manage
Permitido apenas quando status é failed. O corpo aceita as mesmas opções de Converter, então dá para corrigir o HTML ou as opções antes de tentar de novo. O webhook_url do corpo é ignorado: a conversão mantém o que foi enviado originalmente. O custo é cobrado por inteiro outra vez.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/retry' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"html": "<html><body><h1>Fatura corrigida</h1></body></html>",
"format": "pdf",
"page_size": "A4"
}'const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/retry', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"html": "<html><body><h1>Fatura corrigida</h1></body></html>",
"format": "pdf",
"page_size": "A4"
}),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/retry",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
json={
"html": "<html><body><h1>Fatura corrigida</h1></body></html>",
"format": "pdf",
"page_size": "A4"
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/retry');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"html": "<html><body><h1>Fatura corrigida</h1></body></html>",
"format": "pdf",
"page_size": "A4"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/retry", strings.NewReader(`{
"html": "<html><body><h1>Fatura corrigida</h1></body></html>",
"format": "pdf",
"page_size": "A4"
}`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 202
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"conversion_id": "3e4f5a6b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"job_id": "pdf_4c3b2a19",
"status": "pending"
}
}Opções de página e render
Valem para POST /convert e POST /retry. Valores fora da lista devolvem pdf.invalid_option (ou pdf.invalid_page_size para o tamanho do papel).
| Campo | Valores |
|---|---|
page_size | A3, A4 (padrão), A5, Letter, Legal, Tabloid ou Custom |
paper_width, paper_height | papel personalizado, em polegadas (1 a 200). Só combinam com page_size vazio ou Custom; usados com outro tamanho, dão pdf.invalid_page_size |
orientation | portrait (padrão) ou landscape |
margin_top, margin_bottom, margin_left, margin_right | margens da página |
scale | escala do render |
print_background | imprime cores e imagens de fundo (padrão true) |
media_type | print ou screen: qual @media o CSS enxerga |
color_scheme | light ou dark: valor de prefers-color-scheme |
page_numbers | liga o contador de páginas na posição: header-left, header-center, header-right, footer-left, footer-center ou footer-right |
page_number_format | texto do contador, com {page} e {total} (padrão {page} / {total}, até 200 caracteres). Exige page_numbers |
jpeg_quality | de 1 a 100 (padrão 90). Só vale com format: jpg |
Exemplo: fatura em papel de 8 x 11 polegadas, com contador no rodapé:
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/convert' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"url": "https://example.com/relatorio",
"page_size": "Custom",
"paper_width": 8,
"paper_height": 11,
"media_type": "print",
"page_numbers": "footer-center",
"page_number_format": "Página {page} de {total}"
}'Pós-processamento
post_process age sobre o PDF já renderizado e só vale com format: pdf (com png ou jpg, pdf.invalid_option). Cada recurso é cobrado à parte, veja Custos.
| Campo | Descrição |
|---|---|
post_process.watermark.text | texto da marca d'água, até 200 caracteres |
post_process.watermark.image | alternativa ao texto: imagem PNG ou JPEG em base64, até 1 MiB. Envie exatamente um entre text e image |
watermark.font_size | de 1 a 300 |
watermark.color | cor no formato #rrggbb |
watermark.opacity, watermark.scale | de 0 a 1 |
watermark.rotation | de -180 a 180 graus |
watermark.position | center, top-left, top-center, top-right, left, right, bottom-left, bottom-center ou bottom-right |
watermark.on_top | true desenha a marca por cima do conteúdo |
post_process.pdfa | true converte para PDF/A-2b (arquivamento de longo prazo) |
post_process.protection.user_password | obrigatória se houver protection, até 128 caracteres: senha para abrir o arquivo |
protection.owner_password | senha de proprietário, até 128 caracteres |
protection.permissions | o que o leitor pode fazer: print, copy, modify, annotate, fill_forms, assemble. Lista vazia = nenhuma permissão |
pdfa e protection não se combinam (o PDF/A proíbe criptografia): a API responde pdf.invalid_option. As senhas são guardadas cifradas só para o worker aplicá-las e não voltam nas respostas.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/convert' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"html": "<html><body><h1>Contrato</h1></body></html>",
"format": "pdf",
"post_process": {
"watermark": { "text": "CONFIDENCIAL", "color": "#cc0000", "opacity": 0.2, "rotation": -45, "position": "center" },
"protection": { "user_password": "senha-do-leitor", "permissions": ["print"] }
}
}'Templates salvos
Guarde o HTML de um documento recorrente na conta e renderize-o só com template_id e data. Cada alteração de conteúdo cria uma versão nova; as anteriores continuam consultáveis.
- Em
POST /convert,template_idnão combina comhtmlnemurl(pdf.invalid_option).template_versionescolhe a versão;0ou omitido usa a mais recente. - O
css, oheader_htmle ofooter_htmldo template valem como padrão; se você os enviar na conversão, os seus prevalecem. - Template ou versão inexistente:
pdf.template_not_found. Nome de até 120 caracteres; ohtmlsegue os limites de 10 MB e ocssde 1 MB. - Leituras usam o escopo
tools:pdf:read; escritas,tools:pdf:manage(outools:manage). Nenhuma delas cobra créditos nem consome a franquia diária.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/convert' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"template_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"template_version": 0,
"data": { "numero": "001" }
}'Listar templates salvos
/v1/tools/document/pdf/templates- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:readtools:manage
limit (padrão e máximo 100) e offset. A resposta traz items e total.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/templates?limit=20&offset=0' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/templates?limit=20&offset=0', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/templates?limit=20&offset=0",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/templates?limit=20&offset=0');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/templates?limit=20&offset=0", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"items": [
{
"id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"current_version": 2,
"created_at": "2026-10-01T12:00:00Z",
"updated_at": "2026-10-10T09:30:00Z"
}
],
"total": 1
}
}Salvar template
/v1/tools/document/pdf/templates- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:managetools:manage
name (até 120 caracteres) e html são obrigatórios; description, css, header_html e footer_html são opcionais. Cria a versão 1.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/templates' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"html": "<html><body><h1>Fatura {{numero}}</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": ""
}'const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/templates', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"html": "<html><body><h1>Fatura {{numero}}</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": ""
}),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/document/pdf/templates",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
json={
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"html": "<html><body><h1>Fatura {{numero}}</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": ""
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/templates');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"html": "<html><body><h1>Fatura {{numero}}</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": ""
}
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/document/pdf/templates", strings.NewReader(`{
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"html": "<html><body><h1>Fatura {{numero}}</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": ""
}`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 201
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"current_version": 1,
"created_at": "2026-10-01T12:00:00Z",
"updated_at": "2026-10-10T09:30:00Z"
}
}Consultar template
/v1/tools/document/pdf/templates/{id}- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:readtools:manage
version opcional (padrão: a versão atual). Devolve o template e o conteúdo da version.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000?version=2' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000?version=2', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000?version=2",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000?version=2');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000?version=2", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"template": {
"id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"current_version": 2,
"created_at": "2026-10-01T12:00:00Z",
"updated_at": "2026-10-10T09:30:00Z"
},
"version": {
"template_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"version": 2,
"html": "<html><body><h1>Fatura {{numero}}</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": "",
"created_at": "2026-10-10T09:30:00Z"
}
}
}Listar versões do template
/v1/tools/document/pdf/templates/{id}/versions- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:readtools:manage
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000/versions' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000/versions', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000/versions",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000/versions');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000/versions", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"items": [
{
"template_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"version": 2,
"html": "<html><body><h1>Fatura {{numero}}</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": "",
"created_at": "2026-10-10T09:30:00Z"
},
{
"template_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"version": 1,
"html": "<html><body><h1>Fatura</h1></body></html>",
"css": "h1 { color: #333; }",
"header_html": "",
"footer_html": "",
"created_at": "2026-10-10T09:30:00Z"
}
]
}
}Renomear template ou salvar nova versão
/v1/tools/document/pdf/templates/{id}- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:managetools:manage
Envie name e/ou description para renomear. Com html, é salva uma nova versão com o html, css, header_html e footer_html do corpo, e current_version sobe. Os campos de conteúdo omitidos ficam vazios na nova versão: reenvie o conteúdo completo.
curl -sS -X PATCH 'https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "Fatura padrão v2",
"html": "<html><body><h1>Fatura {{numero}}</h1><p>{{cliente}}</p></body></html>",
"css": "h1 { color: #333; }"
}'const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000', {
method: 'PATCH',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Fatura padrão v2",
"html": "<html><body><h1>Fatura {{numero}}</h1><p>{{cliente}}</p></body></html>",
"css": "h1 { color: #333; }"
}),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.patch(
"https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
json={
"name": "Fatura padrão v2",
"html": "<html><body><h1>Fatura {{numero}}</h1><p>{{cliente}}</p></body></html>",
"css": "h1 { color: #333; }"
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"name": "Fatura padrão v2",
"html": "<html><body><h1>Fatura {{numero}}</h1><p>{{cliente}}</p></body></html>",
"css": "h1 { color: #333; }"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("PATCH", "https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000", strings.NewReader(`{
"name": "Fatura padrão v2",
"html": "<html><body><h1>Fatura {{numero}}</h1><p>{{cliente}}</p></body></html>",
"css": "h1 { color: #333; }"
}`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
"name": "Fatura padrão",
"description": "Fatura mensal com logotipo",
"current_version": 3,
"created_at": "2026-10-01T12:00:00Z",
"updated_at": "2026-10-10T09:30:00Z"
}
}Excluir template
/v1/tools/document/pdf/templates/{id}- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:managetools:manage
Apaga o template e todas as versões. As conversões já geradas não são afetadas.
curl -sS -X DELETE 'https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000', {
method: 'DELETE',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.delete(
"https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("DELETE", "https://api.respawntech.dev/v1/tools/document/pdf/templates/550e8400-e29b-41d4-a716-446655440000", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 204 — sem corpo; apaga o template e todas as versões
Fontes
Envie fontes próprias (woff2 ou ttf) e use-as no HTML com font-family: passe os ids em font_ids (até 20 por conversão) e a plataforma injeta o @font-face correspondente. Fonte inexistente em font_ids: pdf.font_not_found. O adicional de fontes é cobrado uma vez por documento que usa font_ids.
- Até 50 fontes por conta (
pdf.font_limit). - Uma combinação de
family+weight+stylesó pode existir uma vez (pdf.font_exists, 409). - O formato é detectado pelo conteúdo do arquivo, não pela extensão.
Listar fontes
/v1/tools/document/pdf/fonts- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:readtools:manage
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/fonts' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/fonts', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/fonts",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/fonts');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/fonts", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"items": [
{
"id": "2b3c4d5e-6f70-4a8b-9c0d-1e2f3a4b5c6d",
"family": "Inter",
"weight": 400,
"style": "normal",
"format": "woff2",
"size_bytes": 108544,
"created_at": "2026-10-05T14:00:00Z"
}
]
}
}Enviar fonte
/v1/tools/document/pdf/fonts- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:managetools:manage
Envio multipart/form-data com file (obrigatório, woff2 ou ttf, até 5 MiB), family (obrigatório, 1 a 64 letras, números, espaços, - ou _), weight (100 a 900 em passos de 100; padrão 400) e style (normal ou italic; padrão normal). Qualquer violação devolve pdf.font_invalid.
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/fonts' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-F 'file=@Inter-Regular.woff2' \
-F 'family=Inter' \
-F 'weight=400' \
-F 'style=normal'Depois, converta com a fonte:
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/convert' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"html": "<html><body style=\"font-family: Inter\"><h1>Olá</h1></body></html>",
"font_ids": ["2b3c4d5e-6f70-4a8b-9c0d-1e2f3a4b5c6d"]
}'curl -sS -X POST 'https://api.respawntech.dev/v1/tools/document/pdf/fonts' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/fonts', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/document/pdf/fonts",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/fonts');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/document/pdf/fonts", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 201
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "2b3c4d5e-6f70-4a8b-9c0d-1e2f3a4b5c6d",
"family": "Inter",
"weight": 400,
"style": "normal",
"format": "woff2",
"size_bytes": 108544,
"created_at": "2026-10-05T14:00:00Z"
}
}Excluir fonte
/v1/tools/document/pdf/fonts/{id}- Custo
- Grátis
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:managetools:manage
Remove a fonte e o arquivo armazenado.
curl -sS -X DELETE 'https://api.respawntech.dev/v1/tools/document/pdf/fonts/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/fonts/550e8400-e29b-41d4-a716-446655440000', {
method: 'DELETE',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.delete(
"https://api.respawntech.dev/v1/tools/document/pdf/fonts/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/fonts/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("DELETE", "https://api.respawntech.dev/v1/tools/document/pdf/fonts/550e8400-e29b-41d4-a716-446655440000", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 204 — sem corpo; apaga a fonte e o arquivo armazenado
Consulta e download
Listar conversões
/v1/tools/document/pdf- Custo
- Franquia diária, depois 0,005 crédito/leitura via API
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:pdf:readtools:manage
Query: limit (padrão 20), offset e exclude_batch=true para ocultar itens de batch. Na listagem, file_url e error_message não são preenchidos — consulte o status de cada conversão.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf?limit=20&offset=0' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf?limit=20&offset=0', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf?limit=20&offset=0",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf?limit=20&offset=0');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf?limit=20&offset=0", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"items": [
{
"id": "3e4f5a6b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"job_id": "pdf_9b8c7d6e5f",
"status": "completed",
"file_name": "fatura-001.pdf",
"page_size": "A4",
"orientation": "portrait",
"margin_top": 10,
"margin_bottom": 10,
"margin_left": 10,
"margin_right": 10,
"scale": 1,
"format": "pdf",
"enable_js": false,
"cost_credits": 1.5,
"cost_units": 15000,
"retention_days": 7,
"expires_at": "2026-10-01T12:00:00Z",
"is_deleted_from_storage": false,
"html": "<html>…</html>",
"css": "body { font-family: sans-serif; }",
"created_at": "2026-09-24T12:00:00Z",
"updated_at": "2026-09-24T12:00:09Z"
}
],
"total": 57,
"page": 1,
"page_size": 20
}
}Status da conversão
/v1/tools/document/pdf/{id}- Custo
- Franquia diária, depois 0,01 crédito/leitura via API
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:pdf:readtools:manage
status: pending, processing, completed ou failed. Em falha, error_code e error_message explicam o motivo. data traz as variáveis enviadas e file_url aparece quando o job termina — para baixar, use sempre Baixar arquivo.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"id": "3e4f5a6b-7c8d-4e9f-a0b1-c2d3e4f5a6b7",
"job_id": "pdf_9b8c7d6e5f",
"status": "failed",
"file_name": "fatura-001.pdf",
"page_size": "A4",
"orientation": "portrait",
"margin_top": 10,
"margin_bottom": 10,
"margin_left": 10,
"margin_right": 10,
"scale": 1,
"format": "pdf",
"enable_js": false,
"cost_credits": 1.5,
"cost_units": 15000,
"retention_days": 7,
"expires_at": "2026-10-01T12:00:00Z",
"is_deleted_from_storage": false,
"html": "<html>…</html>",
"css": "body { font-family: sans-serif; }",
"created_at": "2026-09-24T12:00:00Z",
"updated_at": "2026-09-24T12:00:09Z",
"error_code": "pdf.render_timeout",
"error_tag": "pdf.render_timeout",
"error_message": "O tempo limite de renderização foi excedido",
"webhook_url": "https://example.com/hooks/pdf",
"data": "{\"cliente\":\"Ana\"}"
}
}Baixar arquivo
/v1/tools/document/pdf/{id}/download- Custo
- Franquia diária, depois 0,03 crédito/leitura via API
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:readtools:manage - Timeout
- 2 minutos
Requer status: completed. O arquivo é descriptografado e descomprimido durante o download. X-Dry-Run não se aplica a downloads.
O campo file_url da conversão (ou do detalhe do batch) é um link assinado com ?sig=&exp=: ele baixa o arquivo sem o cabeçalho X-API-Token e sem consumir a franquia, então serve para entregar o link a um cliente final. Ele vale até a data exp; depois dela, consulte a conversão de novo para obter outro.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/download' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/download', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
const file = Buffer.from(await response.arrayBuffer());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/download",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
open("arquivo", "wb").write(response.content)<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/download');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
file_put_contents('arquivo', $body);package main
import (
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/550e8400-e29b-41d4-a716-446655440000/download", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
if err := os.WriteFile("arquivo", data, 0o644); err != nil {
panic(err)
}
}Resposta 200 — corpo binário com Content-Type do formato (application/pdf, image/png ou image/jpeg) e Content-Disposition: attachment; filename="…"; suporta If-None-Match (304)
Batches
Listar batches
/v1/tools/document/pdf/batches- Custo
- Franquia diária, depois 0,005 crédito/leitura via API
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:pdf:readtools:manage
status do batch: processing, delivering, completed, partially_failed ou failed.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/batches?limit=20&offset=0' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/batches?limit=20&offset=0', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/batches?limit=20&offset=0",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/batches?limit=20&offset=0');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/batches?limit=20&offset=0", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"items": [
{
"id": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"status": "partially_failed",
"total_items": 25,
"completed_items": 24,
"failed_items": 1,
"created_at": "2026-09-24T12:00:00Z"
}
],
"total": 3,
"page": 1,
"page_size": 20
}
}Detalhe do batch
/v1/tools/document/pdf/batches/{id}- Custo
- Franquia diária, depois 0,01 crédito/leitura via API
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:pdf:readtools:manage
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"batch": {
"id": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
"status": "completed",
"total_items": 1,
"completed_items": 1,
"failed_items": 0,
"created_at": "2026-09-24T12:00:00Z"
},
"conversions": [
{
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"job_id": "pdf_9b8c7d6e5f",
"status": "completed",
"file_name": "fatura-ana.pdf",
"page_size": "A4",
"orientation": "portrait",
"margin_top": 10,
"margin_bottom": 10,
"margin_left": 10,
"margin_right": 10,
"scale": 1,
"format": "pdf",
"enable_js": false,
"cost_credits": 1.5,
"cost_units": 15000,
"retention_days": 7,
"expires_at": "2026-10-01T12:00:00Z",
"is_deleted_from_storage": false,
"html": "<html>…</html>",
"css": "body { font-family: sans-serif; }",
"created_at": "2026-09-24T12:00:00Z",
"updated_at": "2026-09-24T12:00:09Z",
"batch_id": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d"
}
],
"template": {
"html": "<html><body><h1>{{title}}</h1></body></html>",
"css": ""
}
}
}Download ZIP do batch
/v1/tools/document/pdf/batches/{id}/download- Custo
- Franquia diária, depois 0,03 crédito/leitura via API
- Dry-run
- Não
- Autenticação
- qualquer um de
tools:pdf:readtools:manage - Timeout
- 2 minutos
Disponível quando o batch termina, inclusive parcialmente se alguns itens falharem. Também aceita o link assinado ?sig=&exp=, sem token.
curl -sS -X GET 'https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000/download' \
-H "X-API-Token: $RESPAWN_API_TOKEN"const response = await fetch('https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000/download', {
method: 'GET',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
},
});
if (!response.ok) throw new Error((await response.json()).error.code);
const file = Buffer.from(await response.arrayBuffer());import os
import requests
response = requests.get(
"https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000/download",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
open("arquivo", "wb").write(response.content)<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000/download');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
file_put_contents('arquivo', $body);package main
import (
"io"
"net/http"
"os"
"time"
)
func main() {
req, err := http.NewRequest("GET", "https://api.respawntech.dev/v1/tools/document/pdf/batches/550e8400-e29b-41d4-a716-446655440000/download", nil)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
if err := os.WriteFile("arquivo", data, 0o644); err != nil {
panic(err)
}
}Resposta 200 — application/zip com os itens concluídos (batch-<id>.zip); itens com falha ficam de fora
Erros
| Código | HTTP | Quando |
|---|---|---|
pdf.invalid_request | 400 | Corpo da requisição inválido. |
pdf.html_required | 400 | html e url ausentes: envie um dos dois. |
pdf.html_too_large | 400 | HTML acima de 10 MB. |
pdf.css_too_large | 400 | CSS acima de 1 MB. |
pdf.invalid_page_size | 400 | Tamanho de página inválido. |
pdf.invalid_format | 400 | Formato diferente de pdf, png ou jpg. |
pdf.invalid_url | 400 | url (ou google_fonts_url) inválida: precisa ser um endereço público http/https de até 2048 caracteres. |
pdf.invalid_option | 400 | Opção inválida ou combinação não permitida (html com url, post_process fora do formato pdf, pdfa com protection, template_id com html…). |
pdf.template_not_found | 404 | Template (ou versão) não encontrado na conta. |
pdf.font_not_found | 404 | Fonte não encontrada na conta. |
pdf.font_invalid | 400 | Fonte inválida: arquivo ausente, acima de 5 MiB, que não seja woff2/ttf, ou family, weight ou style fora do permitido. |
pdf.font_exists | 409 | Já existe uma fonte com a mesma família, peso e estilo. |
pdf.font_limit | 400 | Limite de 50 fontes por conta atingido. |
pdf.retention_invalid | 400 | retention_days inválido. |
pdf.batch_empty | 400 | Batch sem itens. |
pdf.batch_too_large | 400 | Mais de 500 itens no batch. |
pdf.template_required | 400 | Template HTML obrigatório no batch. |
pdf.not_completed | 400 | Download solicitado antes de a conversão terminar. |
pdf.no_file | 400 | Arquivo não disponível (expirado ou não gerado). |
pdf.download_failed | 400 | Falha ao ler ou descomprimir o arquivo. |
pdf.decrypt_failed | 400 | Falha ao preparar o arquivo para download. |
pdf.render_failed | 502 | Falha no render. |
pdf.storage_failed | 502 | Falha ao armazenar o arquivo. |
pdf.enqueue_failed | 502 | Falha ao enfileirar o job. |
pdf.render_timeout | 504 | Tempo esgotado no render. |
pdf.internal | 500 | Erro interno ao processar a conversão. |
pdf.template_failed | assíncrono | Falha ao aplicar os dados do item no template (batch). |
Peculiaridades
- Um batch usa um único template HTML; cada item de
items[].datapreenche os placeholders.custom_idajuda a relacionar os arquivos gerados com os seus registros. - Para PDFs recorrentes, salve um template em vez de reenviar o HTML a cada chamada.
retention_days: 0é efêmero (~24h) — ideal para previews.- Prefira
webhook_urla consultar o status em loop: cada consulta via API conta na franquia diária.
Atualizado em