Referência da API
Consulta as rotas e os payloads retornados pelo SSO.
Os Dois Hosts
Antes de mais, a distinção que causa mais problemas de integração:
| Host | Serve |
|---|---|
id.{dominio} | SSO / OAuth: /oauth/authorize, /oauth/token |
api.{dominio} | API REST: tudo o que está nesta página, sob /v1 |
Os dois não são intermutáveis para a API. O /oauth/token responde em qualquer host, por ser rota global do Passport — a API não. Chamar id.{dominio}/api/v1/... devolve 404.
Endpoint do Utilizador (User Profile)
Após obteres um Token de Acesso válido, podes consultar os detalhes do utilizador autenticado e o seu cargo no teu sistema satélite através deste endpoint. Repara que este endpoint vive no subdomínio api., não no domínio principal de login.
GET https://api.{dominio}/v1/user
Headers Requeridos
Authorization: Bearer {access_token}
Accept: application/json
Resposta de Exemplo (200 OK)
{
"status": "success",
"data": {
"id": 1,
"name": "João Silva",
"email": "[email protected]",
"avatar": "https://id.acapadev.com/storage/avatars/joao.png",
"is_premium": false,
"is_verified_identity": true,
"app_context": {
"app_id": 2,
"role": "admin",
"roles": ["admin", "auditor"]
}
}
}
O campo role (singular) traz apenas o primeiro cargo e existe por compatibilidade com integrações antigas. Em código novo usa roles, que traz a lista completa — um utilizador pode ter mais do que um cargo na mesma aplicação.
A resposta vem sempre envolvida num invólucro { status, data }. O app_context contém apenas os cargos que o utilizador possui na tua aplicação satélite (identificada pelo Token OAuth usado) — é null se o utilizador não tiver nenhum cargo atribuído nessa app. Não é uma lista de todos os cargos do utilizador noutros sistemas, por motivos de segurança e privacidade.
Endpoints Máquina-a-Máquina (M2M)
Os endpoints seguintes respondem a tokens de máquina (client_credentials), emitidos para uma Connected App. Não representam um utilizador com sessão iniciada — representam a tua aplicação a perguntar sobre um utilizador.
TOKEN=$(curl -s -X POST https://id.{dominio}/oauth/token \
-H "Content-Type: application/json" \
-d '{"grant_type":"client_credentials","client_id":"...","client_secret":"...","scope":"*"}' \
| jq -r .access_token)
GET https://api.{dominio}/v1/users/{id}/roles
Cargos do utilizador na app que está a perguntar.
O {id} é o ID do utilizador no Acapadev ID, não a chave primária local da tua aplicação. Se as duas não coincidirem, guarda o ID central (por exemplo numa coluna acapadev_id) no momento do login. Enviar o ID local é a causa mais comum de receberes listas vazias.
Resposta de Exemplo (200 OK)
{
"status": "success",
"user_id": 3,
"app_id": 21,
"data": ["auditor", "gestor"]
}
Garantias do campo data:
- É sempre uma lista de nomes em texto, mesmo com zero ou um cargo.
[]significa «este utilizador não tem cargos nesta app». É uma resposta legítima, não um erro.- Pode conter vários elementos — não assumas
data[0]. - A ordem é alfabética e estável entre chamadas iguais.
GET https://api.{dominio}/v1/users/{id}/status
Se a conta do utilizador está ativa.
{
"status": "success",
"user_id": 3,
"active": true
}
active é true apenas quando o estado da conta é Ativo. Contas suspensas, bloqueadas ou por confirmar devolvem false.
Códigos de Estado
| Código | Significado | O que fazer |
|---|---|---|
200 | Leitura feita | Usar data, mesmo que vazio |
401 | Token ausente, inválido, expirado ou revogado | Renovar o token de cliente |
403 | O client_id não corresponde a nenhuma Connected App ativa | Confirmar credenciais e estado da app |
404 | Não existe utilizador com esse ID | Confirmar que envias o ID do Acapadev ID |
Não trates um erro como «sem cargos»
Quando a leitura falha, assumir «sem cargos» é a decisão prudente — nega acesso em vez de o conceder por engano. O que não deve acontecer é essa decisão ficar indistinguível de uma resposta legítima. Regista sempre o código de estado antes de assumir a lista vazia. Se usas o SDK oficial (v1.2.1+), isso já é feito por ti.