Getting started

Guia Rápido

Gere seu primeiro PDF em 5 minutos com a API RenderHub

Guia Rápido

Gere seu primeiro PDF em menos de 5 minutos. Este guia te orienta na criação de uma chave de API e na sua primeira requisição.

Pré-requisitos

Você precisa de uma conta RenderHub. Cadastre-se gratuitamente se ainda não tiver.

Passos

1. Crie sua Chave de API

Navegue até o Dashboard e clique em Chaves de API na barra lateral.

  1. Clique em "Criar Chave de API"
  2. Dê um nome (ex: "Chave de Desenvolvimento")
  3. Copie sua chave imediatamente - você não poderá vê-la novamente!

Aviso de Segurança

Nunca exponha sua chave de API em código cliente ou faça commit dela no controle de versão. Armazene em variáveis de ambiente.

2. Faça sua primeira requisição

Vamos gerar um PDF simples a partir de HTML usando cURL:

curl -X POST https://renderhub.com/api/v1/render \
  -H "Authorization: Bearer SUA_CHAVE_API" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "CONVERT",
    "input_type": "html",
    "data": "<html><body><h1>Olá do RenderHub!</h1><p>Meu primeiro PDF.</p></body></html>"
  }'

Substitua SUA_CHAVE_API pela chave que você copiou no passo 1.

3. Baixe seu PDF

A API retorna uma resposta JSON com seu PDF codificado em base64:

{
  "id": "render_abc123",
  "status": "DONE",
  "pdf_base64": "JVBERi0xLjQKJeLjz9...",
  "pages": 1,
  "file_size_kb": 12,
  "duration_ms": 450
}

Para salvar como arquivo:

# Salve a resposta em um arquivo
curl [mesmo comando acima] > response.json

# Extraia e decodifique o PDF em base64 (Linux/Mac)
jq -r '.pdf_base64' response.json | base64 -d > output.pdf

# Abra o PDF!
open output.pdf  # Mac
xdg-open output.pdf  # Linux

Próximo: Teste com Node.js

Aqui está o mesmo exemplo em Node.js:

const axios = require('axios');
const fs = require('fs');

async function generatePDF() {
  try {
    const response = await axios.post('https://renderhub.com/api/v1/render', {
      mode: 'CONVERT',
      input_type: 'html',
      data: '<html><body><h1>Olá do Node.js!</h1></body></html>'
    }, {
      headers: {
        'Authorization': `Bearer ${process.env.RENDERHUB_API_KEY}`,
        'Content-Type': 'application/json'
      }
    });

    // Decodifique base64 e salve em arquivo
    const pdfBuffer = Buffer.from(response.data.pdf_base64, 'base64');
    fs.writeFileSync('output.pdf', pdfBuffer);

    console.log('✅ PDF gerado com sucesso!');
    console.log(`Páginas: ${response.data.pages}`);
    console.log(`Tamanho: ${response.data.file_size_kb} KB`);
    console.log(`Duração: ${response.data.duration_ms}ms`);
  } catch (error) {
    console.error('Erro:', error.response?.data || error.message);
  }
}

generatePDF();

Parabéns!

Você acabou de gerar seu primeiro PDF com RenderHub! 🎉

O Poder dos Templates e Variáveis

Agora veja o verdadeiro poder do RenderHub: gerar PDFs dinâmicos com templates e variáveis.

Modo RENDER: Templates Reutilizáveis

Em vez de enviar HTML completo toda vez, crie um template uma vez e reutilize com diferentes dados:

// 1. Primeiro, crie um template (via Dashboard ou API)
const template = await axios.post('https://renderhub.com/api/v1/templates', {
  name: 'fatura-mensal',
  content: `
    <html>
      <head>
        <style>
          body { font-family: Arial; padding: 40px; }
          .header {
            display: flex;
            justify-content: space-between;
            border-bottom: 3px solid #2563eb;
            padding-bottom: 20px;
          }
          .items { margin: 30px 0; }
          table { width: 100%; border-collapse: collapse; }
          th { background: #f3f4f6; padding: 12px; text-align: left; }
          td { padding: 12px; border-bottom: 1px solid #e5e7eb; }
          .total {
            font-size: 24px;
            font-weight: bold;
            text-align: right;
            margin-top: 20px;
            color: #2563eb;
          }
        </style>
      </head>
      <body>
        <div class="header">
          <div>
            <h1>{{company_name}}</h1>
            <p>CNPJ: {{company_cnpj}}</p>
          </div>
          <div>
            <h2>FATURA #{{invoice_number}}</h2>
            <p>Data: {{invoice_date}}</p>
          </div>
        </div>

        <div style="margin: 30px 0;">
          <h3>Cliente</h3>
          <p><strong>{{customer_name}}</strong></p>
          <p>{{customer_email}}</p>
          <p>{{customer_address}}</p>
        </div>

        <div class="items">
          <h3>Itens</h3>
          <table>
            <thead>
              <tr>
                <th>Descrição</th>
                <th>Quantidade</th>
                <th>Valor Unit.</th>
                <th>Total</th>
              </tr>
            </thead>
            <tbody>
              {{#each items}}
              <tr>
                <td>{{this.description}}</td>
                <td>{{this.quantity}}</td>
                <td>R$ {{this.unit_price}}</td>
                <td>R$ {{this.total}}</td>
              </tr>
              {{/each}}
            </tbody>
          </table>
        </div>

        {{#if discount}}
        <p style="text-align: right; color: #10b981;">
          Desconto: -R$ {{discount}}
        </p>
        {{/if}}

        <div class="total">
          Total: R$ {{total}}
        </div>

        {{#if payment_method}}
        <div style="margin-top: 30px; padding: 20px; background: #f3f4f6;">
          <p><strong>Forma de Pagamento:</strong> {{payment_method}}</p>
          {{#if payment_due_date}}
          <p><strong>Vencimento:</strong> {{payment_due_date}}</p>
          {{/if}}
        </div>
        {{/if}}
      </body>
    </html>
  `
}, {
  headers: { 'Authorization': `Bearer ${API_KEY}` }
});

const templateId = template.data.id; // Guarde esse ID!

// 2. Agora gere PDFs infinitos com dados diferentes:
async function gerarFatura(clienteId) {
  const cliente = await db.clientes.findById(clienteId);
  const pedidos = await db.pedidos.findByCliente(clienteId);

  const response = await axios.post('https://renderhub.com/api/v1/render', {
    mode: 'RENDER',  // ← Modo RENDER usa templates
    template_id: templateId,
    data: {
      // Dados da empresa
      company_name: 'Minha Empresa LTDA',
      company_cnpj: '12.345.678/0001-99',

      // Dados da fatura
      invoice_number: `2024-${cliente.id}`,
      invoice_date: new Date().toLocaleDateString('pt-BR'),

      // Dados do cliente
      customer_name: cliente.nome,
      customer_email: cliente.email,
      customer_address: `${cliente.endereco}, ${cliente.cidade} - ${cliente.estado}`,

      // Lista de itens (array!)
      items: pedidos.map(p => ({
        description: p.produto,
        quantity: p.quantidade,
        unit_price: p.preco.toFixed(2),
        total: (p.quantidade * p.preco).toFixed(2)
      })),

      // Totais
      discount: cliente.desconto ? cliente.desconto.toFixed(2) : null,
      total: calcularTotal(pedidos, cliente.desconto).toFixed(2),

      // Pagamento (condicional)
      payment_method: cliente.formaPagamento,
      payment_due_date: cliente.vencimento
    }
  }, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });

  const pdfBuffer = Buffer.from(response.data.pdf_base64, 'base64');
  fs.writeFileSync(`faturas/cliente_${cliente.id}.pdf`, pdfBuffer);

  return response.data;
}

// Gerar faturas para 100 clientes diferentes
for (const clienteId of clienteIds) {
  await gerarFatura(clienteId);
  console.log(`✅ Fatura gerada para cliente ${clienteId}`);
}

Por Que Templates São Poderosos?

1. Variáveis Simples

<h1>Olá, {{customer_name}}!</h1>
<!-- Dados: { customer_name: "João Silva" } -->
<!-- Resultado: Olá, João Silva! -->

2. Arrays e Loops

<ul>
  {{#each products}}
    <li>{{this.name}} - R$ {{this.price}}</li>
  {{/each}}
</ul>

<!-- Dados: {
  products: [
    { name: "Notebook", price: "3500" },
    { name: "Mouse", price: "50" }
  ]
} -->

3. Condicionais

{{#if isPremium}}
  <p>⭐ Cliente Premium - 10% de desconto!</p>
{{else}}
  <p>Torne-se Premium e ganhe descontos</p>
{{/if}}

<!-- Dados: { isPremium: true } -->

4. Objetos Aninhados

<p>{{user.address.street}}, {{user.address.city}}</p>

<!-- Dados: {
  user: {
    address: {
      street: "Rua das Flores, 123",
      city: "São Paulo"
    }
  }
} -->

5. Helpers de Formatação

<p>Data: {{formatDate createdAt "DD/MM/YYYY"}}</p>
<p>Valor: {{formatCurrency total "BRL"}}</p>

<!-- Dados: {
  createdAt: "2024-01-15T10:30:00Z",
  total: 1500.50
} -->

Exemplo Real: Sistema de Certificados

// Template criado uma vez
const certificadoTemplate = `
  <html>
    <style>
      body {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        text-align: center;
        padding: 100px;
      }
      .border {
        border: 10px solid gold;
        padding: 60px;
      }
      .student {
        font-size: 48px;
        font-weight: bold;
        margin: 40px 0;
        text-transform: uppercase;
      }
    </style>
    <body>
      <div class="border">
        <h1>🎓 CERTIFICADO DE CONCLUSÃO</h1>
        <p style="font-size: 20px;">Certificamos que</p>
        <p class="student">{{student_name}}</p>
        <p style="font-size: 20px;">concluiu com sucesso o curso</p>
        <p style="font-size: 32px; margin: 20px 0;">
          <strong>{{course_name}}</strong>
        </p>
        <p>Carga horária: {{course_hours}} horas</p>
        <p>Concluído em {{completion_date}}</p>

        {{#if has_distinction}}
        <p style="font-size: 24px; color: gold; margin-top: 30px;">
          ⭐ COM DISTINÇÃO ⭐
        </p>
        {{/if}}
      </div>
    </body>
  </html>
`;

// Gerar certificados para 500 alunos
const alunos = await db.alunos.findCompleted();

for (const aluno of alunos) {
  await axios.post('/api/v1/render', {
    mode: 'RENDER',
    template_id: 'tpl_certificado',
    data: {
      student_name: aluno.nome,
      course_name: aluno.curso,
      course_hours: aluno.cargaHoraria,
      completion_date: aluno.dataConclusao,
      has_distinction: aluno.nota >= 9.0
    }
  });
}

Documentação Completa de Templates

Veja o Guia Completo de Templates para aprender sobre arrays aninhados, condicionais complexas, helpers customizados, e muito mais!

Próximos Passos

Agora que você tem o básico, explore recursos mais avançados:

Problemas Comuns

Chave de API não está funcionando?

Certifique-se de incluir o prefixo Bearer:

Authorization: Bearer rh_live_abc123...

PDF está vazio ou corrompido?

Verifique se você está decodificando a string base64 corretamente. Use uma ferramenta como base64decode.org para testar.

Recebendo erros de rate limit?

Você pode estar atingindo sua quota. Verifique o dashboard para estatísticas de uso e considere fazer upgrade do seu plano.

Precisa de Ajuda?


Pronto para mais? Explore Templates →

On this page