API do Énóis
Construa clientes, ferramentas e integrações para o Énóis. Esta é a documentação oficial.
Filosofia
A API existe para ampliar o acesso à informação e automatizar processos — nunca para fabricar interação social. Publicar conteúdo automaticamente (IA, bots, integrações) é proibido; criar e agendar posts pela funcionalidade oficial, com você no controle, é permitido.
Começando
Todas as rotas ficam sob https://enois.ia.br/api Respostas JSON. Timestamps em UTC (ISO-8601). Identificadores são estáveis (prefixados por tipo).
Tudo sob a mesma base da API. As rotas de leitura pública não pedem credencial; as demais usam a sessão do Énóis no header X-Session-Token — o mesmo token que o app usa, obtido no login.
# 1. Autentique-se (o mesmo token que o app usa)
curl -X POST https://enois.ia.br/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"ada@exemplo.com","password":"senha-forte-1"}'
# 2. Autentique cada chamada com a sessao
curl https://enois.ia.br/api/me -H "X-Session-Token: <token>"Sem sessão você já consegue: ler post público e comentários, listar comunidades e o feed delas, vagas (com a origem), eventos, mentores, ranking, busca e estatísticas. Escrever (postar, comentar, reagir, denunciar…) pede a sessão de uma conta real.
Paginação
Listas paginam por cursor (não por offset). Use o nextCursor da resposta anterior:
GET https://enois.ia.br/api/feed/posts/$POST_ID/comments?limit=20
GET ...?cursor=<nextCursor>&limit=20Erros
Erros têm código e mensagem estáveis, e o HTTP status correspondente:
{"code":"UNAUTHENTICATED","message":"Sessao invalida ou expirada.",
"timestamp":"2026-10-17T14:20:39Z"}| HTTP | código | quando |
|---|---|---|
| 400 | BAD_REQUEST | corpo inválido (e Idempotency-Key ausente onde é exigida) |
| 401 | UNAUTHENTICATED | sem sessão, sessão expirada ou token forjado |
| 403 | FORBIDDEN / ACCOUNT_RESTRICTED / ACCOUNT_BANNED | sem permissão; conta restrita ou banida |
| 404 | NOT_FOUND | recurso inexistente (ou de outra pessoa) |
| 409 | CONFLICT / ALREADY_REPORTED / APPEAL_ALREADY_PENDING | estado atual não permite a operação |
| 422 | INVALID_COMMENT | regra de conteúdo violada |
| 429 | RATE_LIMITED | limite de requisições excedido |
Há limites de tamanho e de taxa por operação. Operações de escrita aceitam Idempotency-Key para você repetir com segurança sem duplicar. Operações de escrita aceitam Idempotency-Key: repita a chamada com a mesma chave e a operação não duplica. Em algumas rotas de escrita a chave é obrigatória.
Autenticação e conta
A sessão do Énóis é o mesmo token que o app usa. Cadastro nasce pendente de confirmação de e-mail; login responde o token que autentica todas as outras rotas pelo header X-Session-Token. Contas com segundo fator respondem um desafio (202) em vez do token.
/auth/signuppúblicoCria a conta (18+, termos aceitos). O cadastro não emite sessão: envia e-mail de confirmação.
requisição
curl -X POST https://enois.ia.br/api/auth/signup \
-H "Content-Type: application/json" \
-H "Idempotency-Key: signup-1" \
-d '{"name":"Ada","email":"ada@exemplo.com","password":"senha-forte-1","acceptedTerms":true}'resposta
201 Created
{"id":"user_…","email":"ada@exemplo.com","emailVerified":false}/auth/email/verifypúblicoConfirma o e-mail com o token do link recebido. Depois disso o login funciona.
requisição
curl -X POST https://enois.ia.br/api/auth/email/verify \
-H "Content-Type: application/json" \
-d '{"token":"<token-do-email>"}'/auth/loginpúblicoAutentica com e-mail e senha e devolve a sessão. Com 2FA ativo, devolve 202 + desafio (conclua em /auth/2fa/verify).
requisição
curl -X POST https://enois.ia.br/api/auth/login \
-H "Content-Type: application/json" \
-H "Idempotency-Key: login-1" \
-d '{"email":"ada@exemplo.com","password":"senha-forte-1"}'resposta
200 OK
{"token":"sess_…","refreshToken":"…","user":{"id":"user_…","name":"Ada","username":"ada"}}/auth/2fa/verifypúblicoConclui o login com o código do segundo fator (app autenticador ou e-mail).
resposta
200 OK
{"token":"sess_…","refreshToken":"…"}/auth/logoutcom sessãoEncerra a sessão atual.
/mecom sessãoPerfil próprio: dados completos, reputação, estado de verificação e preferências.
Feed e publicações
Leitura de publicação e comentários é pública (links compartilhados abrem sem conta). Escrever exige sessão. Posts podem ter mídia (mediaIds) e página em HTML (type PAGE, pageHtml) — a página renderiza em quadro isolado, sem script.
/feedcom sessãoFeed pessoal por aba: FOR_YOU (comunidades que você participa + posts fora de comunidade), FOLLOWING, ALL, DISCUSSIONS, RECENT, PROJECTS. Pagina por cursor.
requisição
curl "https://enois.ia.br/api/feed?tab=FOR_YOU&limit=20" \
-H "X-Session-Token: $TOKEN"resposta
200 OK
{"items":[{"id":"post_…","type":"INSIGHT","content":"…","counters":{"reactions":26,"comments":23,"saves":3,"shares":4},"createdAt":"2026-10-15T02:16:48Z"}],"nextCursor":"2026-10-15T02:16:48Z"}/feed/posts/{postId}públicoPublicação completa: autor, contadores, mídia, comunidade (quando houver).
requisição
curl https://enois.ia.br/api/feed/posts/post_396a12bc2bc54ad3966829c751acb021resposta
200 OK
{"id":"post_396a12bc…","authorId":"user_…","authorUsername":"aminadojava",
"type":"INSIGHT","content":"Pessoal. Post pra coletar ideias…","tags":[],"mediaIds":[],
"createdAt":"2026-10-15T02:16:48Z",
"counters":{"reactions":26,"comments":23,"saves":3,"shares":4},
"currentUserReaction":null,"communityId":null,"community":null}/users/{username}/postspúblicoPublicações de uma pessoa (perfil público).
requisição
curl "https://enois.ia.br/api/users/aminadojava/posts?limit=10"/feed/postscom sessãoPublica. type: INSIGHT | QUESTION | PROJECT | PAGE. Média vai por mediaIds (ver Mídia); PAGE leva pageHtml. Em comunidades, mande communityId.
requisição
curl -X POST https://enois.ia.br/api/feed/posts \
-H "X-Session-Token: $TOKEN" -H "Idempotency-Key: post-1" \
-H "Content-Type: application/json" \
-d '{"type":"INSIGHT","content":"Texto do post","tags":["java"],"mediaIds":[],"mentionedUserIds":[]}'resposta
201 Created
{"id":"post_…","content":"Texto do post","createdAt":"…"}/feed/posts/{postId}com sessãoEdita o próprio post (marca como editado).
/feed/posts/{postId}com sessãoExclui o próprio post (soft delete). POST /feed/posts/{postId}/restore desfaz; bulk-delete para vários.
/feed/posts/{postId}/commentscom sessãoComenta. Para responder, mande parentCommentId. Aceita até 4 mídias (mediaIds) — comentário pode ser só de mídia.
requisição
curl -X POST https://enois.ia.br/api/feed/posts/$POST_ID/comments \
-H "X-Session-Token: $TOKEN" -H "Idempotency-Key: c-1" \
-H "Content-Type: application/json" \
-d '{"content":"Concordo!","parentCommentId":null,"mediaIds":[],"mentionedUserIds":[]}'resposta
201 Created
{"id":"comment_…","postId":"post_…","content":"Concordo!","mediaIds":[],"createdAt":"…"}/feed/posts/{postId}/commentspúblicoComentários (mais recentes primeiro), com respostas aninhadas por parentCommentId.
requisição
curl "https://enois.ia.br/api/feed/posts/$POST_ID/comments?limit=20"resposta
200 OK
{"items":[{"id":"comment_…","authorUsername":"sergio-de-souza-tomas",
"content":"Opa eu notei que agora dá pra editar…","mediaIds":[],"createdAt":"2026-10-15T22:03:52Z"}],
"nextCursor":"2026-10-15T22:03:52Z"}/feed/posts/{postId}/reactionscom sessãoReage ao post. Tipos: LIKE, LOVE, LAUGH, ROFL, WOW, SAD, ANGRY, DISGUST, SKEPTICAL, CELEBRATE, SUPPORT, INSIGHTFUL. Reagir de novo troca o tipo; DELETE remove. Mesmos verbos em …/comments/{commentId}/reactions.
requisição
curl -X POST https://enois.ia.br/api/feed/posts/$POST_ID/reactions \
-H "X-Session-Token: $TOKEN" -H "Idempotency-Key: r-1" \
-H "Content-Type: application/json" -d '{"type":"INSIGHTFUL"}'/feed/posts/{postId}/reactionspúblicoTotais por tipo de reação.
/feed/posts/{postId}/savescom sessãoSalva o post (DELETE remove). Lista em GET /feed/saved.
/feed/posts/{postId}/sharescom sessãoRegistra compartilhamento (contador).
Busca
Busca unificada por pessoas, publicações, comunidades e vagas.
/searchpúblicoBusca por termo livre. Cada item tem type (users, posts, communities, jobs) e pode ser filtrado/roteado pelo cliente.
requisição
curl "https://enois.ia.br/api/search?q=java&limit=10"resposta
200 OK
{"items":[{"id":"user_…","type":"users","title":"JavaScript-chan","subtitle":"…","image":"…"}],
"nextCursor":null}Perfis e ranking
Perfis públicos com experiência, formação, certificações e emblema. O ranking é calculado pela plataforma (reputação/atividade) e é público.
/users/{username}públicoPerfil público: headline, empresa, skills, experiências, emblema, capa em HTML (bannerHtml).
requisição
curl https://enois.ia.br/api/users/aminadojavaresposta
200 OK
{"id":"user_…","username":"aminadojava","name":"melissa monfre dos santos",
"headline":"…","company":"…","skills":[…],"bioHtml":null,"bannerHtml":null,"openToWork":false}/users/by-id/{userId}públicoPerfil por id.
/profile/rankingpúblicoRanking de perfis mais relevantes da rede.
requisição
curl https://enois.ia.br/api/profile/rankingresposta
200 OK
[{"id":"user_…","username":"lucas-matheus-florentino","name":"Lucas Matheus Florentino","skills":[…]}]/me/profilecom sessãoEdita o próprio perfil (nome, headline, skills, bio, bioHtml, bannerHtml, emblema…). Experiências, educação e certificações têm CRUD próprio em /me/experiences, /me/education, /me/certifications.
Comunidades
Listagem, detalhe e feed de comunidade são públicos; entrar, publicar e administrar pedem sessão. A capa pode ser foto (cover) ou HTML/CSS (bannerHtml) — mesma tubulação da capa de perfil.
/communitiespúblicoLista comunidades (topic para filtrar, cursor para paginar). Com sessão, joined reflete participação.
requisição
curl "https://enois.ia.br/api/communities?limit=10"resposta
200 OK
{"items":[{"id":"community_…","name":"Muita IA pouco $","description":"…","members":1,
"topic":"TECNOLOGIA","cover":null,"bannerHtml":null,"joined":false}],"nextCursor":null}/communities/{communityId}públicoDetalhe da comunidade.
/communities/{communityId}/feedpúblicoFeed de publicações da comunidade (mesma forma do feed).
/communities/{communityId}/memberspúblicoMembros e papéis (ADMIN).
/communities/{communityId}/memberscom sessãoEntra na comunidade (DELETE sai). Publicar nela: POST /feed/posts com communityId.
/communitiescom sessãoCria comunidade (o criador vira ADMIN). PATCH edita; /transfer passa a administração; /favorite + /favorites para favoritas.
Vagas
Vagas internas (criadas na plataforma) e externas convivem na mesma listagem. Externas têm id com prefixo ext_, selo de plataforma (sourcePlatform) e URL da origem (sourceUrl) — o redirecionamento é sempre para quem publicou a vaga. Busca booleana: AND, OR, NOT, "frase exata" e parênteses no parâmetro query.
/jobspúblicoLista vagas. query (busca booleana no título), type, level, location e skills filtram só as internas (estruturais); sem filtros estruturais, externas entram junto.
requisição
curl "https://enois.ia.br/api/jobs?query=java%20AND%20remoto&limit=20"resposta
200 OK
{"items":[{"id":"ext_Remotive_2091144","title":"Content Reviewer - United States","company":"TELUS Digital",
"location":"USA","postedAt":"2026-10-17T04:00:49Z","sourcePlatform":"Remotive",
"sourceUrl":"https://remotive.com/remote-jobs/…"}],"nextCursor":null}/jobs/{jobId}públicoDetalhe da vaga (interna ou externa).
/jobscom sessãoPublica vaga (reputação >= 150). PATCH edita, /close encerra, DELETE exclui. Candidaturas: POST /jobs/{id}/applications; status em PATCH /jobs/{id}/applications/{applicationId}; minhas candidaturas em GET /jobs/applications.
/jobs/applicationscom sessãoCandidaturas do próprio usuário (e as recebidas em GET /jobs/{jobId}/applications, para quem publicou).
Eventos
Vitrine de eventos profissionais. Eventos passados saem da vitrine e recusam RSVP; presença vira número agregado após 24h.
/eventspúblicoLista eventos (vitrine).
resposta
200 OK
{"items":[{"id":"event_…","title":"…","date":"2029-12-31","time":"23:59","format":"ONLINE","attendees":2}]}/events/{eventId}públicoDetalhe do evento.
/eventscom sessãoCria evento.
/events/{eventId}/attendeescom sessãoConfirma presença (DELETE cancela).
Mentoria
Mentores publicam horários livres; quem quer aprender pede sessão em um slot.
/mentorspúblicoMentores e expertises.
resposta
200 OK
{"items":[{"id":"mentor_…","expertise":["Pentest","RedTeam","Certificações"]}]}/mentors/{mentorId}/slotspúblicoHorários livres do mentor.
/mentorscom sessãoTorna-se mentor; POST /mentors/{id}/slots publica horários; /sessions pede/agenda sessão.
Estatísticas
Números públicos e agregados da rede — sem dado pessoal.
/stats/communitypúblicoUsuários ativos (janela de 30 dias) e total da rede.
requisição
curl https://enois.ia.br/api/stats/communityresposta
200 OK
{"activeUsers":1031,"totalUsers":1370,"windowDays":30,"computedAt":"2026-10-17T14:20:39Z"}Rede (conexões e bloqueios)
Conexões bidirecionais com aceite; bloqueio é permanente e esconde os dois lados do feed, comentários, busca e sugestões.
/network/summarycom sessãoResumo da sua rede (conexões, pendentes).
/network/suggestionscom sessãoSugestões por afinidade (não por volume).
/network/requestscom sessãoPedidos de conexão recebidos.
/network/connections/{targetUserId}com sessãoPedir conexão (PUT …/accept aceita; GET …/status consulta; DELETE desfaz).
/network/blocks/{targetUserId}com sessãoBloqueia (DELETE desbloqueia; GET /network/blocks lista).
Mensagens
Conversas diretas e de comunidade. Tudo aqui pede sessão — nada de mensagens é público.
/conversationscom sessãoSuas conversas (GET /conversations/search busca dentro delas).
/conversations/{id}/messagescom sessãoMensagens da conversa.
/conversations/{id}/messagescom sessãoEnvia mensagem (reações em …/messages/{messageId}/reactions).
/conversations/directcom sessãoAbre (ou recupera) a conversa direta com alguém.
/conversations/{id}/readcom sessãoMarca como lida; /hide apaga para você (o outro lado mantém).
Notificações e push
Notificações no app e no celular (Web Push). Cada notificação traz href de destino no formato /api/….
/notificationscom sessãoNotificações do usuário (cursor).
/push/configpúblicoChaves públicas para assinar Web Push.
/push/subscriptionscom sessãoRegistra a assinatura push do navegador (DELETE remove).
Mídia
Upload em três passos: (1) pede a assinatura; (2) sobe o arquivo no endereço que a resposta indicar (S3 = PUT direto na signedUrl com os headers dados; ImageKit = multipart); (3) usa o mediaId no post/comentário/perfil. Ninguém precisa de chave de terceiros — a plataforma assina.
/media/uploadscom sessãoPasso 1. purpose: POST_IMAGE | POST_VIDEO | AVATAR | BANNER | COVER. Teto de 500MB por arquivo (URL assinada vale 60 minutos).
requisição
curl -X POST https://enois.ia.br/api/media/uploads \
-H "X-Session-Token: $TOKEN" -H "Idempotency-Key: up-1" \
-H "Content-Type: application/json" \
-d '{"fileName":"media/abc/foto.png","mimeType":"image/png","size":10240,"purpose":"POST_IMAGE"}'resposta
201 Created
{"id":"media_…","cdnUrl":"https://…","uploadUrl":"https://…(assinada)","provider":"S3","uploadHeaders":{…}}/media/{mediaId}públicoPasso 3 (leitura): metadados + cdnUrl para renderizar.
/media/{mediaId}com sessãoRemove a mídia do dono.
Denúncias, moderação e recursos
Qualquer pessoa autenticada pode denunciar conteúdo; cada denúncia avisa o suporte por e-mail. Um sistema automático pré-tri por IA e, só em violação grave e inequívoca, restringe o autor — que pode recorrer. A decisão final é sempre humana: recurso aceito remove a restrição; negado converte em banimento.
/reportscom sessãoDenuncia. targetType: POST | COMMENT | USER | JOB; reason: AI_GENERATED, FAKE_CONTENT, SCAM, DISCRIMINATION, PREJUDICE, HARASSMENT, SPAM, VIOLENCE, COPYRIGHT, OTHER.
requisição
curl -X POST https://enois.ia.br/api/reports \
-H "X-Session-Token: $TOKEN" -H "Idempotency-Key: rep-1" \
-H "Content-Type: application/json" \
-d '{"targetType":"POST","targetId":"post_…","reason":"SCAM","description":"Parece golpe de investimento"}'resposta
201 Created
{"id":"report_…","targetType":"POST","reason":"SCAM","status":"PENDING","createdAt":"…"}/reports/minecom sessãoDenúncias que VOCÊ fez (acompanhamento; sem dados de terceiros).
/me/sanctionscom sessãoPenalidades da sua conta e o estado dos seus recursos.
resposta
200 OK
{"sanctions":[{"id":"sanc_…","type":"RESTRICTION","status":"ACTIVE","reason":"…","createdAt":"…"}],
"appeals":[{"id":"appl_…","status":"PENDING","message":"…"}]}/me/sanctions/appealscom sessãoRecorre da restrição ativa (um recurso pendente por vez; humano decide).
requisição
curl -X POST https://enois.ia.br/api/me/sanctions/appeals \
-H "X-Session-Token: $TOKEN" -H "Content-Type: application/json" \
-d '{"message":"Foi discussão técnica, não discriminação."}'/admin/reportsadminFila de denúncias (approve aplica penalidade e remove conteúdo; dismiss arquiva).
/admin/appealsadminFila de recursos. POST /admin/appeals/{id}/approve libera; /deny converte em banimento (sessões revogadas).
Suporte e conta
Canal de suporte responde por e-mail e fica no painel admin; exclusão de conta anonimiza o conteúdo (nada de dado pessoal órfão).
/support/configpúblicoSe o canal de suporte está aberto (e o e-mail público, quando houver).
/support/requestscom sessãoAbre pedido de suporte (vai por e-mail ao time + fila /admin/support).
/me/themecom sessãoPreferências de tema que acompanham a conta entre dispositivos.
Temas (galeria da comunidade)
Pacotes de TOKENS validados por schema e com gate de contraste (>= 4.5:1) — sem CSS livre. O pacote é JSON; a instalação aplica na hora e a conta guarda o tema como preferência.
/temas/galeria?limit=60públicoLista os temas publicados (mais recentes primeiro).
resposta
[{"id":"tema_…","name":"Bruma Silenciosa","description":"…","packageJson":"{"palette":…}","modeDefault":"light","installs":12,"createdAt":"2026-10-17T18:20:11Z"}]/temas/galeria/{themeId}públicoUm tema específico com o pacote completo.
/temas/galeriacom sessãoPublica um tema (o gate de contraste recusa pacote ilegível com THEME_CONTRAST_LOW). Exige Idempotency-Key.
requisição
{"name":"Meu Tema","description":"Cores da minha comunidade","modeDefault":"light",
"packageJson":"{"palette":{"background":"#f5e6c8",…}}"}resposta
{"id":"tema_…","status":"PUBLISHED"}/temas/galeria/minecom sessãoOs seus temas, em qualquer estado.
/temas/galeria/{themeId}/installcom sessãoInstala na conta (conta a métrica de installs).
/temas/galeria/{themeId}/reportcom sessãoDenuncia o tema para moderação.
/temas/galeria/{themeId}/hidecom sessãoO autor esconde o próprio tema.
Faísca (carteira e cotação)
A moeda interna é FRACIONADA: o ledger inteiro conta milésimos — 1 faísca = 1.000 mf (como os centavos do real). A cotação de REFERÊNCIA em BRL é publicada pela plataforma e financia a remuneração de criadores; não é câmbio — comprar faísca com dinheiro não existe. Transferências são estilo Pix: por username, instantâneas e irreversíveis, com Idempotency-Key obrigatória.
/coin/cotacaopúblicoA cotação de referência vigente + histórico (alimenta a mini bolsa). O total em circulação não é público.
resposta
{"brlCents":1,"escala":1000,"atualizadaEm":"2026-10-18T10:00:00Z",
"historico":[{"brlCents":1,"em":"2026-10-18T10:00:00Z"}]}/coin/cotacaoadminPublica nova cotação de referência (em centavos por 1 faísca).
requisição
{"brlCents":2,"note":"reajuste de referência"}resposta
{"brlCents":2,"em":"2026-10-18T10:05:00Z"}/carteiracom sessãoSaldo, chave (username) e extrato. A primeira abertura executa o genesis idempotente (100 faíscas) e marca a presença do dia.
resposta
{"balance":105000,"escala":1000,"cotacaoBrlCents":1,"chave":"ada-silva",
"entries":[{"amount":5000,"kind":"REWARD","message":"Presença diária","createdAt":"2026-10-18T10:00:00Z"},
{"amount":100000,"kind":"AIRDROP","message":"Distribuição inicial","createdAt":"2026-10-18T09:59:59Z"}]}/carteira/transferenciascom sessãoEnvia faíscas por username (amount em milésimos). Idempotency-Key obrigatória: o replay com a MESMA chave não duplica; com payload diferente, conflita.
requisição
{"toUsername":"joao-silva","amount":1500,"message":"pelo mockup lindo"}resposta
{"status":"SENT","amount":1500,"toUsername":"joao-silva"}Jogos (agregador)
O Énóis NÃO hospeda jogos: o criador envia o LINK de onde o jogo já está publicado (itch.io, site próprio), a moderação revisa, e o jogo roda EMBUTIDO num quadro isolado no app. A página do criador é pública em /games/{username}.
/games?limit=60públicoCatálogo de jogos publicados.
resposta
[{"id":"game_…","userId":"user_…","username":"ada-silva","slug":"kawaii-survivors","title":"Kawaii Survivors",
"description":"Survivor fofo com pixel art.","url":"https://ada.itch.io/kawaii","tags":"arcade,pixel","status":"PUBLISHED",
"submittedAt":"2026-10-18T10:00:00Z"}]/games/{username}públicoOs jogos publicados de um criador.
/games/{username}/{gameSlug}públicoUm jogo específico (a rota que o app embute).
/me/gamescom sessãoOs seus envios, em qualquer estado (dono vê o próprio não-publicado).
/gamescom sessãoEnvia um jogo para moderação — url obrigatoriamente https; slug único por criador.
requisição
{"slug":"kawaii-survivors","title":"Kawaii Survivors","url":"https://ada.itch.io/kawaii",
"description":"…","tags":"arcade,pixel"}resposta
{"id":"game_…","slug":"kawaii-survivors","status":"SUBMITTED"}/games/{gameId}/resubmitcom sessãoReenvia um jogo rejeitado para nova rodada.
/games/{gameId}/compartilharcom sessãoG-share: publica a conquista no feed com a tag do jogo (texto ≤ 600; teto de 12/dia por pessoa). O texto/mídia vêm do JOGO por postMessage e o APP publica com o clique do jogador — a sessão nunca atravessa o iframe.
requisição
{"texto":"Peguei nível 10 na fazendinha!","mediaIds":["media_…"]}resposta
{"postId":"post_…","status":"SHARED"}/admin/games?limit=30adminFila de revisão.
/admin/games/{gameId}/approveadminAprova e publica.
requisição
{"note":"carrega e roda"}resposta
{"id":"game_…","status":"PUBLISHED"}/admin/games/{gameId}/rejectadminRecusa — o motivo é obrigatório e o criador lê.
requisição
{"note":"o jogo não carrega"}resposta
{"id":"game_…","status":"REJECTED"}Marketplace (temas por faíscas, com escrow)
O criador lista um tema próprio por um preço em faíscas; a compra fica em ESCROW — as faíscas ficam retidas até o comprador confirmar (7 dias; liberação automática depois), e o criador recebe o preço menos 10% de taxa. Reembolso devolve 100%. Valores em milésimos de faísca.
/marketplace?limit=60públicoItens à venda.
resposta
[{"id":"mkt_…","sellerId":"user_…","itemKind":"THEME","itemId":"tema_…","title":"Tema à Venda",
"price":40000,"status":"ACTIVE","createdAt":"2026-10-18T10:00:00Z"}]/marketplace/minecom sessãoAs suas listagens.
/marketplace/comprascom sessãoAs suas compras (o painel do escrow: confirmar ou reembolso).
/marketplace/vendascom sessãoAs suas vendas (acompanhar liberações).
/marketplacecom sessãoLista um tema seu (só o autor pode; o tema precisa estar publicado na galeria).
requisição
{"itemId":"tema_…","title":"Tema à Venda","price":40000}resposta
{"id":"mkt_…","status":"ACTIVE"}/marketplace/{listingId}/buycom sessãoCompra: as faíscas saem da carteira e ficam retidas.
resposta
{"purchaseId":"mcmp_…","state":"HELD","price":40000}/marketplace/purchases/{purchaseId}/confirmcom sessãoConfirmou que está tudo certo: libera 90% ao criador (10% de taxa à plataforma).
resposta
{"purchaseId":"mcmp_…","state":"RELEASED"}/marketplace/purchases/{purchaseId}/refundcom sessãoReembolso dentro de 7 dias: devolve 100%.
resposta
{"purchaseId":"mcmp_…","state":"REFUNDED"}Serviços freelance (com escrow)
Duas faces: OFERTAR (o profissional publica o que faz, modelo Fiverr — teto de 5 abertas por conta) e PEDIR (a demanda publica o que precisa, com orçamento em faixa e entregáveis OBRIGATÓRIOS — a lição dos microprojetos). O contrato nasce HELD: entrega → aceite libera 90%; reembolso devolve 100%.
/servicospúblicoCatálogo: ofertas ativas e pedidos abertos.
resposta
{"ofertas":[{"id":"sl_…","category":"design","title":"Logo simples","price":30000,"deliveryDays":5,
"deliverables":"SVG + PNG","status":"ACTIVE"}],
"pedidos":[{"id":"sr_…","category":"código","title":"Página institucional","budgetMin":40000,"budgetMax":80000,
"deliverables":"HTML + CSS publicados","status":"OPEN"}]}/servicos/minhascom sessãoMinhas ofertas e meus contratos (como comprador e como vendedor).
/servicos/ofertascom sessãoPublica uma oferta.
requisição
{"category":"design","title":"Logo simples para o seu time","description":"Duas rodadas de ajuste…",
"deliverables":"SVG + PNG em três tamanhos","price":30000,"deliveryDays":5}resposta
{"id":"sl_…","status":"ACTIVE"}/servicos/ofertas/{listingId}/contratarcom sessãoContrata: as faíscas vão para o escrow.
resposta
{"contractId":"sc_…","state":"HELD"}/servicos/pedidoscom sessãoPublica um pedido (entregáveis obrigatórios; faixa válida).
requisição
{"category":"código","title":"Página institucional","description":"…","deliverables":"HTML + CSS publicados",
"budgetMin":40000,"budgetMax":80000}resposta
{"id":"sr_…","status":"OPEN"}/servicos/pedidos/{requestId}/propostascom sessãoManda proposta — o preço precisa estar DENTRO da faixa.
requisição
{"message":"Entrego em uma semana, com revisão.","price":50000}resposta
{"id":"sp_…","status":"SENT"}/servicos/pedidos/{requestId}/propostascom sessãoAs propostas do pedido (só quem pediu vê).
/servicos/pedidos/{requestId}/escolhercom sessãoEscolhe uma proposta: escrow retido e o pedido fecha.
requisição
{"proposalId":"sp_…"}resposta
{"contractId":"sc_…","state":"HELD"}/servicos/contratos/{contractId}/entregarcom sessãoO vendedor entrega (nota do que foi feito).
requisição
{"note":"SVG e PNG entregues no link X"}resposta
{"contractId":"sc_…","state":"HELD"}/servicos/contratos/{contractId}/aceitarcom sessãoO comprador aceita: libera 90% ao profissional.
resposta
{"contractId":"sc_…","state":"RELEASED"}/servicos/contratos/{contractId}/reembolsocom sessãoO comprador recusa: devolve 100%.
resposta
{"contractId":"sc_…","state":"REFUNDED"}Blogs
Um blog por pessoa, em /blog/{username}. Os posts do blog ficam fora do feed principal; quem assina o blog recebe os posts novos por e-mail (se optou por isso).
/blogs/{slug}públicoLê o blog e os posts publicados pelo slug do blog.
requisição
curl https://enois.ia.br/api/blogs/adaresposta
200 OK
{"slug":"ada","username":"ada","title":"Blog da Ada","posts":[…]}/blogs/mecom sessãoO blog de quem está autenticado (cria um em branco se não existir).
/blogs/mecom sessãoCria ou atualiza o próprio blog (título, descrição, tema).
/blogs/me/postscom sessãoPublica um post no próprio blog (markdown ou HTML sanitizado).
/blogs/me/posts/{postId}com sessãoEdita um post próprio do blog.
/blogs/me/posts/{postId}com sessãoRemove um post próprio do blog.
Grupos
Espaços privados com feed, tópicos e moderação próprios, independentes das comunidades. Entrada aberta entra na hora; entrada por pedido gera um pendente que os administradores aprovam ou recusam.
/groups/{slug}públicoPágina pública do grupo (quem não é membro vê o que o grupo expõe).
/groups/{groupId}/joincom sessãoEntra no grupo ou envia pedido (quando a entrada é por aprovação).
/groups/{groupId}/memberscom sessãoLista de membros do grupo.
/groups/{groupId}/topicscom sessãoCria um tópico dentro do grupo (os administradores do grupo fazem isso).
/groups/{groupId}/postscom sessãoFeed do grupo: só o conteúdo marcado com os tópicos dele.
/groups/{groupId}/postscom sessãoPublica no feed do grupo (membros).
/groups/{groupId}/requests/{requestId}/approvecom sessãoAprova um pedido de entrada (administradores). Reject faz o simétrico.
Serviços
Ofertas de serviço entre pessoas da rede, com orçamento, contrato e entrega. O fluxo vai de pedido aberto a proposta, escolha, entrega e aceite (ou reembolso integral).
/services/servicospúblicoCatálogo de serviços publicados.
/services/servicos/ofertascom sessãoPublica uma oferta de serviço (sujeita à moderação).
/services/servicos/pedidoscom sessãoAbre um pedido de serviço.
/services/servicos/pedidos/{requestId}/propostascom sessãoEnvia uma proposta para um pedido aberto.
/services/servicos/pedidos/{requestId}/escolhercom sessãoEscolhe a proposta e fecha o contrato (o valor fica em custódia).
/services/contratos/{contractId}/entregarcom sessãoEntrega o trabalho realizado (o cliente tem X dias para responder).
/services/contratos/{contractId}/aceitarcom sessãoAceita a entrega e libera o pagamento ao prestador.
/services/contratos/{contractId}/reembolsocom sessãoReembolso integral: devolve 100% ao cliente.
Jogos diários
Três jogos que trocam a todo dia (Blocos, Palavras e Labirinto), com ranking geral e prêmios em faíscas.
/daily-games/blocks/todaypúblicoO estado do jogo de Blocos de hoje (com sessão, inclui o progresso do jogador).
/daily-games/blocks/today/startcom sessãoInicia a partida de hoje.
/daily-games/blocks/today/actionscom sessãoExecuta uma ação na partida em andamento.
/daily-games/blocks/leaderboardpúblicoRanking do dia (e histórico).
/daily-games/words/todaypúblicoEstado do jogo de Palavras de hoje.
/daily-games/rewards/prizespúblicoFaixas de prêmio em faíscas por desempenho.
Casos de uso
Receitas de ponta a ponta com as chamadas reais — os exemplos de resposta abaixo são capturados da produção, não inventados.
Mostrar uma publicação do Énóis em outro site
Um post público serve qualquer widget: leitura sem credencial, contadores e comentários inclusos. Roteiro de três chamadas, sem autenticação.
11. Busque o post (autor, contadores, mídia):
curl https://enois.ia.br/api/feed/posts/post_396a12bc2bc54ad3966829c751acb02122. Busque a primeira página de comentários:
curl "https://enois.ia.br/api/feed/posts/post_396a12bc2bc54ad3966829c751acb021/comments?limit=20"33. Pagina enquanto houver nextCursor (mande o valor de volta em ?cursor=):
curl "https://enois.ia.br/api/feed/posts/post_396a12bc2bc54ad3966829c751acb021/comments?cursor=<nextCursor>&limit=20"4Imagens de perfil e mídia vêm com caminho relativo — prefixe com https://enois.ia.br para renderizar.
Mural de vagas com link para a origem
A listagem junta vagas internas e agregadores públicos (Remotive, Jobicy, RemoteOK, Himalayas). Vagas externas têm id com prefixo ext_ e sempre uma sourceUrl — o clique vai para quem publicou a vaga.
11. Liste com busca booleana no título:
curl "https://enois.ia.br/api/jobs?query=java%20AND%20(remoto%20OR%20h%C3%ADbrido)&limit=20"22. Separe as externas pelo prefixo do id e use a origem:
# externa: id "ext_Remotive_2091144" -> sourcePlatform "Remotive" + sourceUrl para redirecionar # interna: id "job_…" -> aplicação pela própria API (requer sessão)33. Pagine com nextCursor; filtros estruturais (type/level/location/skills) limitam a vagas internas.
Feed de uma comunidade
Conteúdo de uma comunidade específica, sem credencial — útil para site do evento ou da turma.
11. Encontre a comunidade:
curl "https://enois.ia.br/api/communities?limit=20"22. Puxe o feed dela:
curl "https://enois.ia.br/api/communities/$COMMUNITY_ID/feed?limit=20"33. Detalhe de cada post e comentários: mesmos endpoints do caso do widget.
Publicar com imagem (com sessão)
Upload em três passos e depois a publicação. Funciona igual para comentário (mediaIds) e avatar.
11. Autentique-se e guarde o token:
curl -X POST https://enois.ia.br/api/auth/login -H "Content-Type: application/json" \ -d '{"email":"ada@exemplo.com","password":"senha-forte-1"}'22. Peça a assinatura do upload:
curl -X POST https://enois.ia.br/api/media/uploads -H "X-Session-Token: $TOKEN" \ -H "Content-Type: application/json" \ -d '{"fileName":"media/abc/foto.png","mimeType":"image/png","size":10240,"purpose":"POST_IMAGE"}'33. Suba o arquivo no uploadUrl que veio na resposta (PUT direto na S3 assinada, ou multipart no ImageKit).
44. Publique com o mediaId:
curl -X POST https://enois.ia.br/api/feed/posts -H "X-Session-Token: $TOKEN" \ -H "Content-Type: application/json" \ -d '{"type":"INSIGHT","content":"Olha isso","mediaIds":["media_…"]}'
Faísca: transferência estilo Pix e a cotação
A moeda interna é fracionada (1 faísca = 1.000 mf) e transferida por username, com Idempotency-Key. A cotação de referência em BRL é pública; o total em circulação não é.
11. A cotação de referência (pública, sem token):
curl https://enois.ia.br/api/coin/cotacao22. Abra a carteira (a primeira abertura executa o genesis idempotente):
curl https://enois.ia.br/api/carteira -H "X-Session-Token: $TOKEN"33. Envie 1,5 faísca (1.500 mf) para outra pessoa:
curl -X POST https://enois.ia.br/api/carteira/transferencias -H "X-Session-Token: $TOKEN" -H "Idempotency-Key: pagamento-01" -H "Content-Type: application/json" -d '{"toUsername":"joao-silva","amount":1500,"message":"pelo mockup lindo"}'4Repetir a chamada com a MESMA chave não duplica (replay do Pix). Transferência é irreversível — reversão só por moderação, com lançamento espelho no ledger.
Escrow de ponta a ponta: comprar um tema
Compra em faíscas com escrow: as faíscas ficam retidas até o comprador confirmar (7 dias) — o criador recebe 90% e a plataforma fica com 10%.
11. Veja o que está à venda:
curl https://enois.ia.br/api/marketplace22. Compre (as faíscas saem da carteira e ficam retidas):
curl -X POST https://enois.ia.br/api/marketplace/mkt_…/buy -H "X-Session-Token: $TOKEN"33. Confirme depois de instalar o tema (libera 90% ao criador):
curl -X POST https://enois.ia.br/api/marketplace/purchases/mcmp_…/confirm -H "X-Session-Token: $TOKEN"4Arrependeu dentro de 7 dias? /refund devolve 100%. Sem decisão, a liberação para o criador é automática.
Painel de saúde da rede
Números públicos, agregados, sem dado pessoal — prontos para dashboard ou relatório.
11. Atividade da rede:
curl https://enois.ia.br/api/stats/community22. Ranking de perfis:
curl https://enois.ia.br/api/profile/ranking33. Pulso por tema:
curl "https://enois.ia.br/api/search?q=ia&limit=50"
Integração de moderação (admins)
Para ferramentas do próprio time: a fila de denúncias e de recursos é acessível por sessão de administrador (REDE_ADMIN_EMAILS). O banimento só acontece por recurso negado — decisão sempre humana.
11. Veja a fila de denúncias (já com a pré-triagem da IA no campo ai_triage):
curl "https://enois.ia.br/api/admin/reports?limit=30" -H "X-Session-Token: $ADMIN_TOKEN"22. Decida uma denúncia:
curl -X POST https://enois.ia.br/api/admin/reports/$REPORT_ID/approve -H "X-Session-Token: $ADMIN_TOKEN" \ -H "Content-Type: application/json" -d '{"note":"confirmado"}'33. Julgue recursos (aprovar libera; negar ban):
curl -X POST https://enois.ia.br/api/admin/appeals/$APPEAL_ID/approve -H "X-Session-Token: $ADMIN_TOKEN"
Estado e contato
Esta é a versão inicial. Escopos de terceiros (OAuth) e o portal completo estão em construção — documentamos apenas o que já existe.
Vulnerabilidades: reporte em SECURITY.md descreve como reportar vulnerabilidades (resposta em até 90 dias, sem caça a recompensa).
O que a plataforma tolera (e o que não tolera) está nas Diretrizes da Comunidade