Visão geral
A EventsPro API v1 é uma API REST somente para leitura, com respostas JSON em UTF-8. Ela permite consultar os eventos de um organizador e sincronizar participantes com CRMs, ERPs, aplicativos de credenciamento, plataformas de marketing e outras soluções autorizadas.
Autenticação segura
Chaves individuais armazenadas por hash, revogáveis e com escopo controlado.
Sincronização incremental
Consulte somente registros alterados dentro de uma janela consistente.
Proteção de carga
Paginação por cursor e limites por chave evitam sobrecarga no servidor.
Primeiros passos
Uma integração mínima pode ser validada em quatro etapas.
Crie uma chave
Acesse o painel, escolha o escopo e copie o segredo exibido uma única vez.
Gerenciar chaves de APITeste a disponibilidade
Faça uma chamada sem autenticação para GET /health.
Liste seus eventos
Envie a chave em Authorization: Bearer e consulte GET /events.
Sincronize participantes
Percorra o cursor e salve updated_until para a próxima execução.
curl --request GET \
--url 'https://www.eventspro.com.br/api/v1/events?per_page=50&after_id=0' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ep_live_SUA_CHAVE'
Autenticação e chaves
Todos os endpoints, exceto /health, exigem uma chave ativa. O método recomendado é o header Bearer.
Authorization: Bearer ep_live_SUA_CHAVE
Accept: application/json
Também é aceito o header alternativo:
X-API-Key: ep_live_SUA_CHAVE
Accept: application/json
Escopos disponíveis
| Escopo | Acesso | Uso recomendado |
|---|---|---|
| account | Todos os eventos atuais e futuros pertencentes à conta. | Integrações institucionais, data warehouse, CRM e ERP. |
| event | Somente o evento escolhido ao criar a chave. | Fornecedores e integrações contratadas para um evento específico. |
- Não envie e-mail e senha para a API.
- Não coloque a chave em query string, URL, HTML ou JavaScript executado no navegador.
- Armazene a chave em variável de ambiente ou cofre de segredos do servidor integrador.
- Crie uma chave separada para cada sistema e ambiente, facilitando auditoria e revogação.
Convenções HTTP
Todas as datas são representadas no padrão ISO 8601 ou no timezone configurado pela plataforma.
| Item | Convenção |
|---|---|
| Protocolo | HTTPS obrigatório em produção. |
| Formato | application/json; charset=UTF-8 |
| Métodos atuais | GET — API v1 somente para leitura. |
| Timezone | America/Sao_Paulo |
| Cache | Respostas protegidas retornam Cache-Control: no-store, private. |
| Rastreamento | Cada chamada retorna X-Request-Id e meta.request_id. |
Envelope de sucesso
{
"data": {
"events": []
},
"meta": {
"request_id": "5ae05c67f15d4cf18b7e7a3a",
"pagination": {
"per_page": 50,
"after_id": 0,
"next_after_id": null,
"has_more": false
}
}
}
Referência de endpoints
O parâmetro {event} aceita o ID, URI principal ou URI curta do evento.
| Método | Endpoint | Autenticação | Finalidade |
|---|---|---|---|
| GET | /health | Não | Status da API. |
| GET | /events | Sim | Lista eventos acessíveis. |
| GET | /events/{event} | Sim | Detalha um evento. |
| GET | /events/{event}/participants | Sim | Lista e sincroniza participantes. |
| GET | /events/{event}/participants/{id} | Sim | Busca participante pelo ID. |
| GET | /events/{event}/participants/code/{code} | Sim | Busca pelo código do ingresso. |
| GET | /events/{event}/participants/document/{type}/{document} | Sim | Busca pelo documento. |
Health check
curl --request GET --url 'https://www.eventspro.com.br/api/v1/health'
{
"status": "ok",
"version": "v1",
"timestamp": "2026-08-14T10:30:00-03:00",
"meta": {
"request_id": "5ae05c67f15d4cf18b7e7a3a"
}
}
Eventos
Consulte os eventos pertencentes à conta associada à chave.
Listar eventos
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| per_page | int | 50 | Quantidade entre 1 e 100. |
| after_id | int | 0 | Cursor retornado pela página anterior. |
| status | string | — | Filtra pelo status interno do evento. |
| updated_since | datetime | — | Retorna eventos atualizados desde a data ISO 8601. |
GET https://www.eventspro.com.br/api/v1/events?per_page=50&after_id=0
Authorization: Bearer ep_live_SUA_CHAVE
Detalhar evento
{
"data": {
"event": {
"id": 125,
"uri": "congresso-eventspro-2026",
"short_uri": "evt2026",
"name": {
"pt": "Congresso EventsPro 2026",
"en": "EventsPro Congress 2026",
"es": "Congreso EventsPro 2026"
},
"schedule_type": "traditional",
"visibility": "public",
"status": "active",
"starts_at": "2026-09-10 08:00:00",
"ends_at": "2026-09-12 18:00:00",
"capacity": 1200,
"media": {
"logo": "https://www.eventspro.com.br/storage/images/event-logo.png",
"banner": "https://www.eventspro.com.br/storage/images/event-banner.jpg",
"voucher": null
},
"created_at": "2026-05-10 12:00:00",
"updated_at": "2026-08-14 09:30:00"
}
},
"meta": {
"request_id": "5ae05c67f15d4cf18b7e7a3a"
}
}
Participantes
A listagem reúne dados do ingresso, participante, endereço, empresa, pagamento, check-in e, quando solicitado, campos personalizados do formulário.
Listar participantes
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| per_page | int | 50 | Quantidade entre 1 e 200. |
| after_id | int | 0 | Cursor estável da próxima página. |
| payment_status | string | valid | valid, all ou até 20 códigos numéricos separados por vírgula. |
| include_custom_fields | bool | false | Inclui campos personalizados. Ative apenas quando necessário. |
| include_deleted | bool | false | Inclui registros removidos para reconciliação. |
| updated_since | datetime | — | Início da janela incremental. |
| updated_until | datetime | Hora da 1ª chamada | Fim fixo da janela; repita em todas as páginas. |
GET https://www.eventspro.com.br/api/v1/events/125/participants?per_page=50&after_id=0&payment_status=valid&include_custom_fields=false&include_deleted=false
Authorization: Bearer ep_live_SUA_CHAVE
Estrutura do participante
| Objeto | Conteúdo |
|---|---|
| ticket | Código, número, URL, categoria, preço e observações do ingresso. |
| participant | Nome, e-mail, documento, gênero, idade, nascimento, telefones, nacionalidade e credencial. |
| address | País, CEP, logradouro, número, complemento, bairro, cidade e estado. |
| company | Empresa, cargo, documento, telefone e endereço empresarial. |
| payment | Pedido, status, valor, moeda, método, transação e data do pagamento. |
| check_in | Situação e datas de criação, atualização ou remoção do check-in. |
| custom_fields | Campos dinâmicos indexados por form_sql. |
| changed_at | Maior data de alteração entre participante, pedido, check-in, endereço, empresa e campos personalizados. |
| deleted_at | Data de remoção lógica do vínculo do participante, quando existente. |
{
"data": {
"participants": [
{
"id": 380,
"registration_id": 921,
"event_id": 125,
"ticket": {
"code": "AB12CD34EF",
"number": "000380",
"url": "https://www.eventspro.com.br/ingresso/evt2026/AB12CD34EF",
"category": {"id": 15, "name": "Participante", "price": "250.00"},
"observations": null
},
"participant": {
"first_name": "Maria",
"last_name": "Silva",
"email": "maria@example.com",
"document": {"type_id": 1, "type": "CPF", "number": "00000000000"},
"phone_cell": "+5545999999999",
"badge_name": "Maria Silva"
},
"address": {"city": "Foz do Iguaçu", "state": "PR", "deleted_at": null},
"company": {"name": "Empresa Exemplo", "job": "Analista", "deleted_at": null},
"payment": {
"order_id": 710,
"status_code": 2,
"status": "paid",
"status_label": "Pago",
"order_amount": "250.00",
"currency": "BRL",
"method": "credit_card",
"transaction_code": "ORDER123",
"paid_at": "2026-08-10 14:20:00"
},
"check_in": {"completed": true, "created_at": "2026-09-10 08:02:00"},
"custom_fields": {},
"registered_at": "2026-08-10 14:18:00",
"changed_at": "2026-09-10 08:02:00",
"deleted_at": null
}
]
},
"meta": {
"request_id": "5ae05c67f15d4cf18b7e7a3a",
"event_id": 125,
"pagination": {
"per_page": 50,
"after_id": 0,
"next_after_id": 380,
"has_more": true
},
"filters": {
"updated_since": null,
"updated_until": "2026-08-14 10:30:00",
"payment_status": "valid",
"include_custom_fields": false,
"include_deleted": false
}
}
}
Buscas individuais
Paginação por cursor
A API não usa páginas numéricas. O cursor after_id mantém a leitura eficiente mesmo em eventos grandes e evita o custo crescente de OFFSET no banco.
- Comece com after_id=0.
- Leia meta.pagination.next_after_id.
- Enquanto has_more=true, envie o cursor recebido na próxima chamada.
- Finalize quando has_more=false.
GET /events/125/participants?per_page=50&after_id=0
GET /events/125/participants?per_page=50&after_id=380
GET /events/125/participants?per_page=50&after_id=447
Sincronização incremental
Use uma janela fixa para importar alterações sem perder registros que mudem enquanto as páginas estão sendo processadas.
Primeira sincronização
GET https://www.eventspro.com.br/api/v1/events/125/participants?updated_since=2026-08-01T00%3A00%3A00-03%3A00&after_id=0&payment_status=all&include_custom_fields=true&include_deleted=true
Na primeira resposta, capture meta.filters.updated_until. Repita esse mesmo valor nas páginas seguintes:
GET /events/125/participants
?updated_since=2026-08-01T00%3A00%3A00-03%3A00
&updated_until=2026-08-14%2010%3A30%3A00
&after_id=380
&payment_status=all
&include_custom_fields=true
&include_deleted=true
Checkpoint
Quando has_more for falso, salve o updated_until concluído como o updated_since da próxima execução.
O que altera changed_at?
Alterações no participante, vínculo com o evento, pedido, pagamento, check-in, endereço, empresa, endereço da empresa e campos personalizados são consideradas na data changed_at.
Limites e desempenho
Os limites protegem a estabilidade da plataforma e são aplicados em janelas de 60 segundos.
| Grupo | Limite padrão | Identificação |
|---|---|---|
| Health check | 60 requisições/minuto | Por IP |
| Tentativas de autenticação | 300 requisições/minuto | Por IP |
| Eventos | 120 requisições/minuto | Por chave |
| Participantes | Até 60 requisições/minuto | Por chave |
Headers de limite
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1786714260
Retry-After: 18
O header Retry-After é enviado somente quando o limite foi excedido.
- Não faça uma requisição por participante; use listagem paginada.
- Use sincronização incremental após a importação inicial.
- Solicite campos personalizados apenas quando forem consumidos.
- Em resposta 429, aguarde Retry-After e aplique retry com atraso e jitter.
- Não execute várias rotinas concorrentes usando a mesma chave e o mesmo evento.
Erros
Erros possuem código estável, mensagem legível e identificador de requisição.
{
"error": {
"code": "event_not_found",
"message": "Evento não encontrado para esta chave de API."
},
"meta": {
"request_id": "5ae05c67f15d4cf18b7e7a3a"
}
}
| HTTP | Significado | Ação recomendada |
|---|---|---|
| 200 | Requisição concluída. | Processe data e meta. |
| 400 | Evento obrigatório não informado. | Revise a URL ou event_id/event_uri. |
| 401 | Chave ausente, inválida, expirada ou revogada. | Revise o header e rotacione a chave quando necessário. |
| 403 | Chave sem acesso ao evento. | Use o evento associado ou uma chave account. |
| 404 | Endpoint, evento ou participante não encontrado. | Valide identificadores e escopo. |
| 422 | Parâmetro semanticamente inválido. | Corrija data, documento, status ou ID. |
| 429 | Limite excedido. | Aguarde o valor de Retry-After. |
| 500 | Erro interno de processamento. | Registre request_id e tente novamente com cautela. |
| 503 | API temporariamente indisponível. | Aplique retry exponencial e alerte após repetição. |
Códigos de erro possíveis
| Categoria | Códigos |
|---|---|
| Autenticação | missing_api_key, invalid_api_key, revoked_api_key, expired_api_key |
| Evento | event_required, event_not_found, event_not_allowed, events_query_failed |
| Participante | participant_not_found, invalid_participant_id, invalid_ticket_code, participants_query_failed |
| Filtros | invalid_document_type, invalid_document, invalid_updated_since, invalid_updated_until, invalid_payment_status |
| Infraestrutura | rate_limit_exceeded, rate_limiter_unavailable, internal_error, endpoint_not_found |
Exemplos de integração
Os exemplos abaixo devem ser executados no backend do sistema integrador.
PHP 8 — requisição autenticada
<?php
$apiKey = getenv('EVENTSPRO_API_KEY');
$url = 'https://www.eventspro.com.br/api/v1/events?per_page=50&after_id=0';
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Authorization: Bearer ' . $apiKey,
],
]);
$body = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
if ($body === false) {
throw new RuntimeException(curl_error($curl));
}
curl_close($curl);
$payload = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if ($status >= 400) {
$requestId = $payload['meta']['request_id'] ?? 'unknown';
$errorCode = $payload['error']['code'] ?? 'unknown_error';
throw new RuntimeException("EventsPro {$errorCode}; request_id={$requestId}");
}
$events = $payload['data']['events'] ?? [];
JavaScript — Node.js 18+
const apiKey = process.env.EVENTSPRO_API_KEY;
const url = new URL('https://www.eventspro.com.br/api/v1/events/125/participants');
url.search = new URLSearchParams({
per_page: '50',
after_id: '0',
payment_status: 'valid',
include_custom_fields: 'false'
});
const response = await fetch(url, {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${apiKey}`
}
});
const payload = await response.json();
if (!response.ok) {
throw new Error(
`EventsPro ${payload.error?.code}; request_id=${payload.meta?.request_id}`
);
}
console.log(payload.data.participants);
JavaScript — percorrer todas as páginas
async function listAllParticipants(eventId, apiKey) {
const participants = [];
let afterId = 0;
let hasMore = true;
while (hasMore) {
const url = new URL(
`https://www.eventspro.com.br/api/v1/events/${encodeURIComponent(eventId)}/participants`
);
url.search = new URLSearchParams({
per_page: '200',
after_id: String(afterId),
payment_status: 'valid'
});
const response = await fetch(url, {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${apiKey}`
}
});
const payload = await response.json();
if (response.status === 429) {
const retryAfter = Number(response.headers.get('Retry-After') || 1);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
if (!response.ok) {
throw new Error(payload.error?.code || `HTTP ${response.status}`);
}
participants.push(...payload.data.participants);
hasMore = payload.meta.pagination.has_more;
afterId = payload.meta.pagination.next_after_id;
}
return participants;
}
Segurança, privacidade e LGPD
Dados de participantes podem conter informações pessoais. O organizador e o sistema integrador devem aplicar controles compatíveis com a finalidade autorizada e com a legislação aplicável.
- Use sempre HTTPS e valide o certificado do domínio.
- Conceda o menor escopo necessário; prefira event para fornecedores de um único evento.
- Restrinja o acesso à chave e aos dados sincronizados por função e necessidade.
- Não registre chaves, documentos, e-mails ou payloads completos em logs de erro.
- Defina prazo de retenção e descarte seguro dos dados importados.
- Use criptografia em repouso quando o destino armazenar dados pessoais.
- Revogue imediatamente chaves de integrações encerradas ou potencialmente comprometidas.
- Consulte apenas os campos necessários à finalidade informada ao participante.
Rotação de chave sem interrupção
- Crie uma nova chave com o mesmo escopo.
- Atualize o segredo no sistema integrador.
- Valide uma chamada autenticada com a nova chave.
- Revogue a chave anterior no painel.
Checklist de produção
Antes de liberar a integração, confirme os pontos abaixo.
- A chave foi criada para a integração e possui o menor escopo necessário.
- O segredo está em variável de ambiente ou cofre de segredos.
- O health check responde 200 e o primeiro evento foi localizado.
- A rotina percorre next_after_id até has_more ser falso.
- A sincronização mantém updated_until fixo durante todas as páginas.
- O checkpoint só é salvo depois da janela completa.
- Respostas 429 e 503 possuem política de retry limitada.
- request_id e código HTTP são registrados sem armazenar a chave.
- Exclusões e mudanças de pagamento são reconciliadas quando aplicável.
- Os dados pessoais possuem controle de acesso, retenção e descarte definidos.
Nenhum resultado encontrado
Tente buscar por endpoint, autenticação, participante, paginação ou erro.