Visão geral
A plataforma expõe tudo o que a interface administrativa faz — usuários, cursos, matrículas, progresso, certificados, relatórios e webhooks — em uma API REST versionada, pensada para integração servidor-a-servidor com o seu RH, ERP ou sistema interno.
| Item | Valor |
|---|---|
Base URL | https://api-dev.intellicreate.online/api
/v1 |
| Formato | JSON, campos em snake_case |
| Versionamento | explícito na URL (/v1) — mudanças incompatíveis criarão /v2, nunca alterarão /v1 |
| Especificação | OpenAPI 3.1 · Swagger UI |
| Protocolos | HTTPS obrigatório (TLS 1.2+) |
| Infraestrutura | frontend na rede de borda global da Vercel; backend e PostgreSQL gerenciados na Railway, com backups automáticos — detalhes em Segurança |
Ambientes
Homologação e produção usam a mesma base URL e as mesmas regras de negócio: o que muda é a credencial. O ambiente de homologação é um espaço (tenant) dedicado com dados descartáveis — desenvolva contra ele e, ao entrar em produção, troque apenas a chave. Nenhuma outra alteração de código é necessária.
Primeiros passos
1. Crie uma API Key. No painel administrativo, acesse Integrações → API Keys, escolha um nome e marque apenas os escopos que a integração vai usar. A chave completa (ik_live_...) é exibida uma única vez — guarde-a em um cofre de segredos. Se ela se perder, gere outra e revogue a anterior.
2. Faça a primeira chamada. Toda requisição leva a chave no header Authorization:
curl "https://api-dev.intellicreate.online/api /v1/courses?limit=10" \ -H "Authorization: Bearer ik_live_xxxxxxxxxxxxxxxxxxxxxxxx"
3. Fluxo típico de uma integração de treinamento:
| Passo | Chamada | Resultado |
|---|---|---|
| Cadastrar o aluno | POST /v1/users | Usuário criado no seu espaço; senha temporária opcional |
| Matricular no curso | POST /v1/enrollments | Matrícula criada; aluno é notificado na plataforma |
| Acompanhar progresso | GET /v1/enrollments/{id} ou webhooks | Percentual, nota e status em tempo real |
| Receber a conclusão | enrollment.completed | Webhook assinado dispara no momento da conclusão |
| Obter o certificado | GET /v1/certificates | PDF oficial + código de verificação pública |
POST /v1/webhooks/{id}/test e valide a assinatura antes de escrever o restante da integração. A seção Webhooks tem o código pronto de verificação.Autenticação e escopos
API Keys
A forma principal de autenticação. Cada chave pertence a um espaço (tenant), carrega escopos explícitos e pode ser rotacionada ou revogada no painel a qualquer momento. O isolamento é automático: a credencial determina o tenant e nenhum dado de outro cliente é alcançável, em nenhuma rota.
Authorization: Bearer ik_live_xxxxxxxxxxxxxxxxxxxxxxxx
Escopos disponíveis
| Escopo | Permite |
|---|---|
users:read | Listar e consultar usuários |
users:write | Criar, atualizar, suspender e reativar usuários |
courses:read | Listar e consultar cursos e módulos |
enrollments:read | Listar e consultar matrículas, progresso e respostas por questão |
enrollments:write | Criar matrículas individuais |
enrollments:bulk | Criar matrículas em massa (até 1.000 por chamada) |
certificates:read | Listar e consultar certificados emitidos |
analytics:read | Relatórios de conclusão e exportações CSV |
webhooks:read | Listar endpoints de webhook e histórico de entregas |
webhooks:write | Criar, editar, remover e testar endpoints de webhook |
Chamadas fora do escopo da chave respondem 403 com type: authorization_error — conceda a cada integração somente o que ela usa.
OAuth 2.0 (Client Credentials)
Alternativa para equipes que padronizam integrações em OAuth. Cadastre um client no painel (Integrações → OAuth 2.0) e troque as credenciais por um token de acesso de curta duração; o token carrega os mesmos escopos e substitui a API Key no header.
curl -X POST https://api-dev.intellicreate.online/api
/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=cl_live_xxxxxxxxxxxxxxxx" \
-d "client_secret=cs_xxxxxxxxxxxxxxxxxxxxxxxx" \
-d "scope=users:read enrollments:write"
→ { "access_token": "...", "token_type": "Bearer", "expires_in": 3600, "scope": "..." }Também estão disponíveis POST /oauth/revoke (invalida um token) e POST /oauth/introspect (verifica validade e escopos), conforme as RFCs 7009 e 7662.
Convenções da API
| Convenção | Detalhe |
|---|---|
| Campos | snake_case em requisições e respostas |
| Datas | ISO 8601 em UTC — ex.: 2026-08-30T14:22:05.000Z |
| Identificadores | UUID v4 em todos os recursos |
| Corpo de resposta | envelope { "data": ... }; listagens incluem campos de paginação |
| Métodos | GET (leitura), POST (criação/ações), PATCH (atualização parcial), DELETE (remoção) |
| Sucesso sem corpo | 204 No Content em ações como suspender usuário |
Paginação por cursor
Listagens que podem crescer sem limite (usuários, matrículas de um usuário, certificados) usam paginação por cursor: peça a primeira página com limit (padrão 20, máximo 100) e repita a chamada passando cursor=next_cursor até has_more ser false. O cursor é opaco — não interprete seu conteúdo.
GET /v1/users?limit=50
→ { "data": [ ... ], "next_cursor": "MTc4ODA1MzU4MQ==", "has_more": true, "limit": 50 }
GET /v1/users?limit=50&cursor=MTc4ODA1MzU4MQ==
→ { "data": [ ... ], "next_cursor": null, "has_more": false, "limit": 50 }Filtros
Filtros são parâmetros de query documentados por recurso — por exemplo GET /v1/enrollments?user_id=...&status=completed ou GET /v1/users?email=maria@empresa.com.br. Em GET /v1/users o parâmetro fields permite reduzir a resposta às colunas desejadas.
Erros
Toda a superfície /v1 usa um envelope único de erro. O campo type classifica a falha, code dá o motivo específico (estável, próprio para switch no seu código), detail traz contexto estruturado quando existe e request_id identifica a chamada nos nossos logs — inclua-o em qualquer chamado de suporte.
HTTP/1.1 422 Unprocessable Entity
{
"error": {
"type": "business_rule",
"code": "regulatory_profile_missing",
"message": "Este curso é regulado e exige o perfil regulatório completo do aluno...",
"detail": { "missing_fields": ["cpf", "cnh"] },
"request_id": "req_Zx8kQ2mN4pTv"
}
}| type | HTTP | Quando acontece |
|---|---|---|
validation_error | 400 | Corpo ou parâmetros inválidos — detail lista [{field, message}] |
authentication_error | 401 | Chave ausente, inválida, expirada ou revogada |
authorization_error | 403 | Chave válida sem o escopo necessário |
not_found | 404 | Recurso inexistente no seu espaço — ex.: user_not_found |
conflict | 409 | Estado conflitante — ex.: email_exists, already_enrolled (a matrícula existente vem em detail.existing_enrollment) |
business_rule | 422 | Regra de negócio — ex.: regulatory_profile_missing com detail.missing_fields |
rate_limited | 429 | Limite de requisições excedido — aguarde e repita |
internal_error | 500 | Falha inesperada — repita com backoff; persiste? Abra chamado com o request_id |
Limites de requisição
Os limites protegem a estabilidade da plataforma para todos os clientes e são dimensionados com folga para operações reais — incluindo cargas de milhares de matrículas.
| Superfície | Limite em produção | Observação |
|---|---|---|
/v1/* | 1.500 requisições / 15 min por chave | headers RateLimit-* em toda resposta |
/v1/certificates/verify | 60 requisições / min por IP | endpoint público de verificação |
| Matrícula em massa | 1.000 linhas por chamada | POST /v1/enrollments/bulk — uma chamada, mil matrículas |
| Exportação CSV | 50.000 linhas por arquivo | acima disso a resposta traz o header X-Truncated — filtre por curso ou status |
Ao receber 429, honre os headers RateLimit-Reset e repita após o intervalo. Para sincronizações grandes, prefira o endpoint em massa a laços de chamadas individuais — além de mais rápido, consome uma única requisição do limite.
Usuários
/v1/usersusers:readLista usuários do seu espaço. Filtros: email, role, status; paginação por cursor; fields para resposta enxuta.
/v1/usersusers:writeCria um usuário. Sem password, uma senha temporária é gerada e devolvida uma única vez em _meta.temporary_password. E-mail repetido responde 409 email_exists.
/v1/users/{id}users:readConsulta um usuário pelo UUID.
/v1/users/{id}users:writeAtualização parcial — envie apenas os campos que mudaram, incluindo o perfil regulatório.
/v1/users/{id}/suspendusers:writeSuspende o acesso (desligamento, afastamento). Responde 204.
/v1/users/{id}/reactivateusers:writeReativa um usuário suspenso. Responde 204.
/v1/users/{id}/enrollmentsenrollments:readMatrículas do usuário, com progresso e nota, paginadas por cursor.
/v1/users/{id}/certificatescertificates:readCertificados emitidos para o usuário, paginados por cursor.
Campos de criação e atualização
| Campo | Tipo | Regras |
|---|---|---|
email | string | obrigatório na criação, único no seu espaço |
name | string | obrigatório na criação, 1–120 caracteres |
role | string | learner (padrão), gestor ou instrutor — perfis administrativos não são criáveis por API |
password | string | opcional (mín. 8); sem ele, senha temporária é gerada |
department · job_title · employee_number | string | campos organizacionais livres |
business_unit_id | uuid | vincula o usuário a uma unidade de negócio existente |
cpf | string | validado por dígitos verificadores; obrigatório para curso regulado |
phone | string | DDD + 8 ou 9 dígitos |
birth_date | date | YYYY-MM-DD, maior de 18 anos |
cnh | objeto | {numero, categoria, validade, ear} — registro de 11 dígitos, categoria válida, não vencida; obrigatória para curso regulado |
***.***.***-05). Detalhes na seção Segurança e LGPD.Cursos
/v1/coursescourses:readLista cursos do catálogo. Filtros: status (DRAFT, PUBLISHED, ARCHIVED) e tags.
/v1/courses/{id}courses:readDetalhe do curso: título, descrição, carga horária (duration_hours), dificuldade, capa e tags.
/v1/courses/{id}/modulescourses:readMódulos do curso na ordem de consumo, com tipo e duração — útil para exibir a grade no seu sistema.
/v1/courses/{id}/statsanalytics:readMétricas do curso: matrículas, conclusões, taxa de conclusão e nota média.
Cursos são criados e gerenciados pelo painel (inclusive importação de pacotes SCORM). A API é o espelho de leitura para integrações — o catálogo do seu portal interno, por exemplo, pode ser montado inteiramente a partir destes endpoints.
Matrículas e progresso
/v1/enrollmentsenrollments:readLista matrículas. Filtros: user_id, course_id, status (not_started, in_progress, completed, expired).
/v1/enrollmentsenrollments:writeCria uma matrícula (user_id + course_id, expires_at opcional). Erros específicos: 404 user_not_found / course_not_found, 409 already_enrolled, 422 regulatory_profile_missing.
/v1/enrollments/bulkenrollments:bulkAté 1.000 matrículas em uma chamada. A resposta relata linha a linha: {created, skipped, failed, errors[]} — repetidas contam como skipped, sem interromper o lote.
/v1/enrollments/{id}enrollments:readEstado atual: status, progress (0–100), score, datas de início, conclusão e expiração.
/v1/enrollments/{id}/interactionsenrollments:readRespostas por questão reportadas por curso SCORM (cmi.interactions) — detalhe na seção Cursos SCORM.
Como o progresso é medido
progress reflete o avanço real do aluno sobre o conteúdo (0–100) e score consolida a nota das avaliações. A conclusão muda status para completed, preenche completed_at e dispara o webhook enrollment.completed — em curso regulado, somente depois de todos os critérios validados no servidor. Para acompanhamento em tempo real prefira webhooks a consultas periódicas; para conciliação, o GET é a fonte da verdade.
GET /v1/enrollments/8098829c-...
→ {
"data": {
"id": "8098829c-...",
"user_id": "57e49256-...",
"course_id": "2c999245-...",
"status": "COMPLETED",
"progress": 100,
"score": 95,
"started_at": "2026-08-12T13:05:11.000Z",
"completed_at": "2026-08-19T20:41:37.000Z",
"expires_at": null
}
}Certificados
/v1/certificatescertificates:readLista certificados emitidos. Filtros: user_id, course_id.
/v1/certificates/{id}certificates:readDetalhe do certificado: código de verificação, PDF oficial (pdf_url), datas de emissão e validade.
/v1/certificates/verify/{code}Público, sem autenticação — é o link impresso no certificado e acessível por QR Code. Responde se o certificado é válido, com dados do titular mascarados.
Certificados são emitidos automaticamente na conclusão — não existe emissão manual. Cada um carrega um código único de verificação pública, o que permite a qualquer auditor confirmar a autenticidade sem credencial.
GET /v1/certificates/verify/IC-9F2K-QX7M
→ {
"verified": true,
"certificate": {
"verification_code": "IC-9F2K-QX7M",
"user_name": "Maria da Silva",
"holder_cpf": "***.***.***-05",
"course_title": "Curso de Segurança da Informação",
"issued_by": "Empresa Exemplo",
"issued_at": "2026-08-19T20:41:40.000Z",
"expires_at": null
}
}Relatórios
/v1/analytics/completionanalytics:readConsolidado de conclusão: totais de matrículas, concluídas, em andamento, não iniciadas, certificados emitidos e taxa de conclusão — geral e por curso. Filtro opcional course_id.
/v1/analytics/exports?type=csvanalytics:readExportação CSV da base de matrículas (aluno, curso, status, progresso, nota, datas). Filtros: course_id, status. Acima de 50.000 linhas o arquivo é truncado e a resposta traz o header X-Truncated.
/v1/courses/{id}/statsanalytics:readMétricas de um curso específico (atalho documentado na seção Cursos).
Estes endpoints sustentam rotinas de relatório recorrentes (diárias ou semanais) sem processar listagens paginadas: uma chamada devolve o consolidado pronto para o seu BI, e o CSV alimenta planilhas e data lakes diretamente.
Webhooks
Em vez de consultar a API em intervalos, receba os eventos no seu endpoint HTTPS no momento em que acontecem. Cada entrega é um POST JSON assinado com HMAC-SHA256 — você valida a assinatura e tem garantia de origem e integridade.
/v1/webhookswebhooks:readLista os endpoints cadastrados.
/v1/webhookswebhooks:writeCadastra um endpoint (url HTTPS + lista de events). O secret de assinatura é devolvido uma única vez.
/v1/webhooks/{id}webhooks:writeAtualiza URL, eventos, descrição ou ativa/desativa.
/v1/webhooks/{id}webhooks:writeRemove o endpoint.
/v1/webhooks/{id}/deliverieswebhooks:readHistórico de entregas com status HTTP, tentativas e corpo de resposta — sua ferramenta de depuração.
/v1/webhooks/{id}/testwebhooks:writeDispara um evento webhook.test para validar o receptor de ponta a ponta.
/v1/webhooks/{id}/deliveries/{deliveryId}/retrywebhooks:writeReenfileira uma entrega específica após corrigir o receptor.
Formato da entrega
POST https://seu-sistema.com.br/webhooks/plataforma
User-Agent: IntelliCreate-Webhooks/1.0
X-IntelliCreate-Signature: t=1788053581,v1=6d5f8a...
X-IntelliCreate-Event-Id: evt_a1b2c3d4e5f6a7b8c9d0e1f2
X-IntelliCreate-Event-Type: enrollment.completed
X-IntelliCreate-Delivery-Id: 7c3e...
{
"id": "evt_a1b2c3d4e5f6a7b8c9d0e1f2",
"type": "enrollment.completed",
"created": 1788053581,
"version": "2026-05",
"tenant_id": "0b66903f-...",
"data": {
"enrollment_id": "8098829c-...",
"user_id": "57e49256-...",
"course_id": "2c999245-...",
"progress_percent": 100,
"score": 95,
"completed_at": "2026-08-19T20:41:37.000Z"
}
}Validação da assinatura (obrigatória)
A assinatura cobre timestamp.corpo_bruto. Valide com o secret do endpoint, em comparação de tempo constante, e rejeite timestamps com mais de 5 minutos (anti-replay). O mesmo X-IntelliCreate-Event-Id pode chegar mais de uma vez em retentativas — trate as entregas de forma idempotente.
import { createHmac, timingSafeEqual } from "node:crypto";
function verificarWebhook(rawBody, sigHeader, secret) {
const partes = Object.fromEntries(sigHeader.split(",").map((p) => p.split("=")));
const t = parseInt(partes.t, 10);
if (Math.abs(Date.now() / 1000 - t) > 300) throw new Error("timestamp expirado");
const esperado = createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
if (!timingSafeEqual(Buffer.from(partes.v1), Buffer.from(esperado)))
throw new Error("assinatura inválida");
}Retentativas
Consideramos entregue qualquer resposta 2xx em até 10 segundos. Fora disso, reentregamos com backoff exponencial — 7 tentativas ao longo de ~7h30 (imediata, +5s, +30s, +2min, +10min, +1h, +6h). Após a última falha a entrega fica visível no histórico e pode ser reenfileirada manualmente pelo endpoint de retry.
Catálogo de eventos
| Grupo | Eventos |
|---|---|
| Usuários | user.created · user.updated · user.suspended · user.reactivated · user.deleted · user.role_changed |
| Cursos e trilhas | course.created · course.updated · course.archived · learning_path.assigned · learning_path.completed |
| Matrículas | enrollment.created · enrollment.started · enrollment.progress · enrollment.completed · enrollment.expired |
| Certificados | certificate.issued · certificate.revoked · certificate.expiring |
| Avaliações | assessment.attempted · assessment.passed · assessment.failed · voice_activity.completed |
| Sistema | api_key.created · api_key.rotated · api_key.revoked · webhook.test · webhook.activated · webhook.failed |
Cursos regulados
Cursos exigidos por regulamentação (trânsito, segurança do trabalho, setor financeiro) precisam de mais do que "aluno viu todas as telas". A plataforma suporta critérios de conclusão validados no servidor, por curso:
| Critério | Como é garantido |
|---|---|
| Carga horária mínima | Tempo de estudo efetivo medido por batimentos do player (aba visível), com proteção antifraude no servidor — nunca pelo relógio do dispositivo do aluno ou pelo tempo auto-declarado de um pacote SCORM |
| Aproveitamento mínimo | Nota consolidada das avaliações precisa atingir o percentual configurado |
| Módulos sequenciais | O player trava o avanço fora de ordem quando o curso exige sequência |
| Identificação do aluno | Matrícula exige perfil regulatório completo: CPF validado e CNH vigente |
O impacto na integração é objetivo: POST /v1/enrollments em curso regulado responde 422 regulatory_profile_missing enquanto faltar CPF ou CNH — complete o cadastro via PATCH /v1/users/{id} e repita. A conclusão (e o certificado) só efetivam quando todos os critérios passam, mesmo que o conteúdo esteja 100% visto; até lá a matrícula permanece in_progress com progress: 100. O certificado emitido carrega o CPF e a CNH do titular (mascarados em toda a API) e é verificável publicamente.
Cursos SCORM
Pacotes SCORM 1.2 e 2004 importados pelo painel se comportam como qualquer curso na API: mesma matrícula, mesmo progress, mesmos webhooks e o mesmo certificado automático. Pacotes com vários SCOs viram cursos com um módulo por SCO, e a conclusão consolida todos eles. Critérios regulatórios também se aplicam — o pacote se declarar concluído não basta.
Relatório por questão
Quando o pacote reporta as respostas dos quizzes ao runtime (cmi.interactions), a plataforma as armazena por aluno e questão. Sua integração lê tudo por matrícula:
GET /v1/enrollments/{id}/interactions
→ {
"data": [
{
"module_id": "d8084120-...",
"module_title": "Módulo 1",
"interaction_id": "pergunta_01",
"type": "choice",
"description": "O que é engenharia social?",
"response": "b",
"correct_response": "b",
"result": "correct",
"latency_seconds": 14,
"weighting": 1,
"updated_at": "2026-08-30T01:26:59.991Z"
}
]
}Curso sem SCORM — ou pacote que não reporta interações, comportamento comum em conteúdos sem quiz — devolve lista vazia; não é erro. O painel administrativo exibe o consolidado por questão (respondentes e taxa de acerto) sem precisar de integração.
SSO e SCIM
SSO — autenticação federada
Alunos e administradores podem entrar com a identidade corporativa via OIDC (Authorization Code + PKCE) ou SAML 2.0, com descoberta automática pelo domínio do e-mail. A configuração é feita no painel (Integrações → SSO), informando os metadados do seu IdP — Microsoft Entra ID, Google Workspace, Okta, Keycloak e equivalentes.
# Descoberta por domínio (sem autenticação)
GET https://api-dev.intellicreate.online/api
/api/sso/discover?domain=empresa.com.br
→ { "sso": true, "provider": "OIDC", "init_url": "..." }
# O navegador segue o fluxo do IdP; ao final a plataforma entrega a sessão
# por um ticket de uso único — nenhum token do IdP passa pelo frontend.SCIM 2.0 — provisionamento automático
Conecte o provisionamento do seu IdP à base https://api-dev.intellicreate.online/api
/scim/v2 com o token dedicado gerado no painel (Integrações → SCIM). Admissões criam o usuário, transferências atualizam departamento e cargo, desligamentos suspendem o acesso — sem nenhuma chamada manual. Suportamos Users com o schema enterprise (departamento, matrícula) nas operações padrão: GET, POST, PUT, PATCH e DELETE (soft delete → suspensão).
Segurança e LGPD
| Controle | Implementação |
|---|---|
| Isolamento de dados | Cada credencial pertence a um único espaço (tenant); nenhuma rota alcança dados de outro cliente |
| Transporte | HTTPS obrigatório em toda a superfície, incluindo URLs de webhook em produção |
| PII minimizada | CPF, telefone e CNH saem mascarados em todas as leituras da API — ex.: ***.***.***-05. O único artefato com dados completos é o PDF do certificado, documento oficial do titular |
| Credenciais | Chaves com escopos mínimos, rotação assistida e revogação imediata; segredos de webhook e tokens SCIM armazenados cifrados |
| Webhooks | Assinatura HMAC-SHA256 com timestamp anti-replay; destinos validados contra endereços internos (anti-SSRF) |
| Senhas | Política de senha forte na plataforma; senhas nunca aparecem em respostas da API além da temporária de criação, exibida uma única vez |
| Auditoria | Ações administrativas e de integração registradas com autoria e request_id correlacionável |
Dados pessoais são tratados conforme a LGPD, com a plataforma atuando como operadora dos dados do seu espaço. Relatórios de conformidade e acordos de tratamento de dados podem ser solicitados pelo canal comercial.
Suporte
Dúvidas técnicas de integração, solicitação de ambiente de homologação ou reporte de problemas: comercial@intellicreate.online. Ao reportar um erro, inclua o request_id da resposta e o horário da chamada — com eles localizamos a requisição exata nos logs.
A especificação viva da API está sempre em Swagger UI e OpenAPI 3.1; em caso de divergência entre esta página e o OpenAPI, o OpenAPI prevalece.