API v1 · REST

Visão Geral da API

Bem-vindo à documentação da API externa do RHUP. Nossa API RESTful permite que você integre o seu sistema corporativo (ERP, folha de pagamento, etc.) diretamente com a nossa plataforma de gestão de crachás.

A API atual (v1) é focada no inbound de dados. Ou seja, você pode automatizar a inserção e atualização de funcionários, bem como o envio das fotos para o crachá.

Base URL: https://api.rhup.com.br/api/v1

Autenticação

A API do RHUP utiliza autenticação baseada em chaves por requisição (sem necessidade de tokens temporários/OAuth).

Você precisa enviar dois headers obrigatórios em todas as requisições:

  • X-Client-Id: O UUID público da sua credencial.
  • X-Api-Key: O segredo criptográfico gerado.
Atenção: O X-Api-Key é exibido apenas uma vez no momento da criação da credencial no painel do RHUP. Mantenha-o seguro!
curl -H "X-Client-Id: seu-uuid" \
     -H "X-Api-Key: seu-segredo" \
     https://api.rhup.com.br/api/v1/health
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.rhup.com.br/api/v1/health"))
    .header("X-Client-Id", "seu-uuid")
    .header("X-Api-Key", "seu-segredo")
    .build();

HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
import requests

headers = {
    "X-Client-Id": "seu-uuid",
    "X-Api-Key": "seu-segredo"
}
response = requests.get("https://api.rhup.com.br/api/v1/health", headers=headers)
const response = await fetch("https://api.rhup.com.br/api/v1/health", {
  headers: {
    "X-Client-Id": "seu-uuid",
    "X-Api-Key": "seu-segredo"
  }
});
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.rhup.com.br/api/v1/health', [
    'headers' => [
        'X-Client-Id' => 'seu-uuid',
        'X-Api-Key' => 'seu-segredo',
    ]
]);
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Client-Id", "seu-uuid");
client.DefaultRequestHeaders.Add("X-Api-Key", "seu-segredo");

var response = await client.GetAsync("https://api.rhup.com.br/api/v1/health");

Quick Start

Inicie sua integração em 3 passos simples:

  1. Gere as chaves: No painel web do RHUP, acesse Configurações > Integrações API e crie uma nova credencial. Copie o Client ID e a API Key.
  2. Pegue o Token da Empresa: Para saber em qual empresa os dados serão inseridos, copie o identificador da empresa (pode ser o "Token Fixo", "Token Customizado" ou o CNPJ) disponível no painel.
  3. Faça seu primeiro request: Use o código ao lado para inserir um funcionário de teste.
curl -X POST https://api.rhup.com.br/api/v1/funcionarios \
  -H "Content-Type: application/json" \
  -H "X-Client-Id: SEU_CLIENT_ID" \
  -H "X-Api-Key: SUA_API_KEY" \
  -d '{
    "operacao": 2,
    "tokenEmpresa": "TOKEN_DA_SUA_EMPRESA",
    "funcionarios": [
      {
        "cpf": "123.456.789-00",
        "nome": "João Silva",
        "matricula": "12345"
      }
    ]
  }'

Health Check

GET /health

Endpoint público para verificar se a API está online e operante. Não requer autenticação.

curl https://api.rhup.com.br/api/v1/health
const response = await fetch("https://api.rhup.com.br/api/v1/health");
const data = await response.json();
import requests

response = requests.get("https://api.rhup.com.br/api/v1/health")
data = response.json()
Exemplo de Resposta
{
  "status": "ok"
}

Inserir ou Atualizar Funcionários

POST /funcionarios

Este endpoint processa lotes de funcionários (até 200 por vez). Ele opera em dois modos definidos pelo campo operacao:

  • operacao: 1 (Apenas Edit): Atualiza funcionários existentes. Retorna erro se o CPF não for encontrado.
  • operacao: 2 (Upsert): Insere se o CPF não existir, atualiza se já existir.

Atributos Raiz do JSON

Campo Tipo Descrição
operacao * int 1 (Edit) ou 2 (Upsert)
tokenEmpresa * string Identificador do tenant (Token ou CNPJ)
funcionarios * array Lista de objetos funcionário (max 200)
Semântica de Edição: Para atualizar, envie apenas os campos que deseja mudar. Se enviar um campo como null, o valor será limpo no banco. O cpf nunca é alterado.

Possíveis Erros e Como Contornar

Erro Comum Solução
VALIDATION_ERROR em operacao Verifique se passou 1 ou 2 no formato numérico (não string).
NOT_FOUND (CPF não encontrado) Ocorre na operação 1. Mude para 2 se quiser cadastrar caso não exista.
PAYLOAD_TOO_LARGE O array de funcionarios passou de 200 itens. Divida em lotes menores.
curl -X POST https://api.rhup.com.br/api/v1/funcionarios \
  -H "Content-Type: application/json" \
  -H "X-Client-Id: SEU_CLIENT_ID" \
  -H "X-Api-Key: SUA_API_KEY" \
  -d '{
    "operacao": 2,
    "tokenEmpresa": "ABC123XYZ",
    "funcionarios": [
      {
        "cpf": "123.456.789-00",
        "nome": "Maria Souza",
        "matricula": "99887",
        "nomeCargo": "Desenvolvedora Frontend",
        "dataAdmissao": "2026-01-15"
      }
    ]
  }'
const payload = {
  operacao: 2,
  tokenEmpresa: "ABC123XYZ",
  funcionarios: [
    {
      cpf: "123.456.789-00",
      nome: "Maria Souza",
      matricula: "99887",
      nomeCargo: "Desenvolvedora Frontend",
      dataAdmissao: "2026-01-15"
    }
  ]
};

const response = await fetch("https://api.rhup.com.br/api/v1/funcionarios", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Client-Id": "SEU_CLIENT_ID",
    "X-Api-Key": "SUA_API_KEY"
  },
  body: JSON.stringify(payload)
});
const data = await response.json();
import requests

payload = {
    "operacao": 2,
    "tokenEmpresa": "ABC123XYZ",
    "funcionarios": [
        {
            "cpf": "123.456.789-00",
            "nome": "Maria Souza",
            "matricula": "99887",
            "nomeCargo": "Desenvolvedora Frontend",
            "dataAdmissao": "2026-01-15"
        }
    ]
}

headers = {
    "X-Client-Id": "SEU_CLIENT_ID",
    "X-Api-Key": "SUA_API_KEY"
}

response = requests.post("https://api.rhup.com.br/api/v1/funcionarios", json=payload, headers=headers)
data = response.json()
$client = new \GuzzleHttp\Client();

$payload = [
    'operacao' => 2,
    'tokenEmpresa' => 'ABC123XYZ',
    'funcionarios' => [
        [
            'cpf' => '123.456.789-00',
            'nome' => 'Maria Souza',
            'matricula' => '99887',
            'nomeCargo' => 'Desenvolvedora Frontend',
            'dataAdmissao' => '2026-01-15'
        ]
    ]
];

$response = $client->request('POST', 'https://api.rhup.com.br/api/v1/funcionarios', [
    'headers' => [
        'X-Client-Id' => 'SEU_CLIENT_ID',
        'X-Api-Key' => 'SUA_API_KEY',
    ],
    'json' => $payload
]);
Exemplo de Response (Sucesso)
{
  "success": true,
  "operacao": 2,
  "tokenEmpresa": "ABC123XYZ",
  "total": 1,
  "inseridos": 1,
  "atualizados": 0,
  "erros": 0,
  "resultados": [
    {
      "linha": 1,
      "cpf": "123.456.789-00",
      "nome": "Maria Souza",
      "status": "inserido",
      "id": 105,
      "erro": null
    }
  ]
}

Envio de Foto (Multipart)

Para enviar fotos anexadas aos funcionários, mude o Content-Type para multipart/form-data.

  • O campo payload deve conter todo o JSON da requisição.
  • Os campos foto_0, foto_1, etc. contêm as imagens (JPEG ou PNG, máx 5MB).
  • O sufixo numérico (0, 1) indica o índice do funcionário no array funcionarios ao qual a foto pertence.

Possíveis Erros e Como Contornar

Erro Comum Solução
Arquivo não reconhecido Verifique se os nomes dos campos (foto_0, foto_1) correspondem exatamente aos índices do array funcionarios no JSON.
Tamanho excedido Reduza a imagem para menos de 5MB. Prefira enviar JPG com compressão.
Erro no formato do Payload Garanta que o campo payload está enviando uma string JSON válida, e não um [object Object].
curl -X POST https://api.rhup.com.br/api/v1/funcionarios \
  -H "X-Client-Id: SEU_CLIENT_ID" \
  -H "X-Api-Key: SUA_API_KEY" \
  -F 'payload={"operacao":2,"tokenEmpresa":"ABC123XYZ","funcionarios":[{"cpf":"111.222.333-44","nome":"Maria"}]}' \
  -F "foto_0=@/caminho/para/maria.jpg"
const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');

const payload = {
  operacao: 2,
  tokenEmpresa: "ABC123XYZ",
  funcionarios: [ { cpf: "111.222.333-44", nome: "Maria" } ]
};

const form = new FormData();
form.append('payload', JSON.stringify(payload));
form.append('foto_0', fs.createReadStream('/caminho/para/maria.jpg'));

const response = await fetch("https://api.rhup.com.br/api/v1/funcionarios", {
  method: "POST",
  headers: {
    "X-Client-Id": "SEU_CLIENT_ID",
    "X-Api-Key": "SUA_API_KEY",
    ...form.getHeaders()
  },
  body: form
});
import requests
import json

payload = {
    "operacao": 2,
    "tokenEmpresa": "ABC123XYZ",
    "funcionarios": [ {"cpf": "111.222.333-44", "nome": "Maria"} ]
}

headers = {
    "X-Client-Id": "SEU_CLIENT_ID",
    "X-Api-Key": "SUA_API_KEY"
}

files = {
    'payload': (None, json.dumps(payload), 'application/json'),
    'foto_0': ('maria.jpg', open('/caminho/para/maria.jpg', 'rb'), 'image/jpeg')
}

response = requests.post("https://api.rhup.com.br/api/v1/funcionarios", headers=headers, files=files)

Códigos de Erro

A API usa os códigos HTTP padrão. O corpo da resposta de erro sempre segue a mesma estrutura.

HTTP Código Motivo
400VALIDATION_ERRORDados faltando ou inválidos.
401INVALID_CREDENTIALSChaves incorretas ou ausentes.
401CREDENTIAL_REVOKEDCredencial foi revogada no painel.
402PLAN_INACTIVEA assinatura da empresa está pendente.
404NOT_FOUNDEmpresa não encontrada no seu tenant.
413PAYLOAD_TOO_LARGEMais de 200 itens num único request.
Exemplo de Erro de Validação (400)
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Campos obrigatórios não preenchidos",
    "details": [
      {
        "field": "operacao",
        "message": "operacao é obrigatório (1 ou 2)"
      }
    ]
  }
}

FAQ

Posso mandar o CPF com pontos e traços?

Sim. O sistema limpa automaticamente a pontuação do CPF (deixa só números) antes de salvar ou processar.

O que acontece se um funcionário falhar num lote de 200?

A API processa linha por linha. O request principal retornará HTTP 200 OK, mas o array resultados listará o status: "erro" especificamente para a linha que falhou, detalhando o porquê.

Como apago um dado (ex: nome do cargo) no modo Edit?

Envie a propriedade com o valor explícito null.


Changelog

v1.0 Julho de 2026
  • Lançamento inicial da API externa.
  • POST /funcionarios — inserção e atualização em lote (até 200 por request), com foto opcional via multipart/form-data.
  • GET /health — verificação de disponibilidade.
  • Autenticação por headers X-Client-Id + X-Api-Key.