Conta
A conta em si, e só com sessão.
Nada aqui aceita uma chave. Uma chave que pudesse criar outra chave se daria todos os escopos de uma vez, e uma que pudesse pedir a exportação estaria a um vazamento da conta inteira. Não existe escopo que torne isso seguro, então não existe escopo: só sessão.
Uma chave que tentar responde 403 forbidden.
/api/ v1/ account/ usernameDiz se um nome está livre, antes de alguém tentar tomá-lo.
Parâmetros
| Campo | Tipo | Observações |
|---|---|---|
qobrigatório | string | O nome a verificar. Um que nem sequer tem forma de nome responde disponível: false, em vez de erro. |
/api/ v1/ account/ usernameToma um nome pela primeira vez. É separado do PATCH porque são atos diferentes com regras diferentes: quem ainda não tem nome está terminando de se cadastrar, e quem já tem está se renomeando.
Corpo
| Campo | Tipo | Observações |
|---|---|---|
usernameobrigatório | string | De 3 a 24 caracteres entre a-z, 0-9 e _, sem começar nem terminar com _. |
/api/ v1/ account/ usernameRenomeia. Há um período de espera entre uma troca e a próxima, e a resposta traz next_change_at para dizer quando acaba.
/api/ v1/ indexConteúdo público recente para indexadores. Até 1000 itens por tipo: reviews, entries, lists e screenshots. RLS define a visibilidade.
/api/ v1/ account/ bootstrapPrepara o perfil depois do login. Apenas sessão. adopt_twitch=true adota a identidade Twitch existente.
/api/ v1/ account/ stateSuspensão ativa, motivo e número de infrações da própria conta, e infraction_history: cada registro por trás desse número, do mais novo ao mais antigo, com id, reason (o tipo, guardado em português: Aviso, Suspensão ou Banimento permanente), details (as palavras da moderação, ou null), expires_at e created_at. Apenas sessão.
Exemplo
{
"data": {
"suspended": false,
"state": null,
"infractions": 1,
"infraction_history": [
{
"id": "5c1d…",
"reason": "Aviso",
"details": "Spoilers sem aviso numa avaliação.",
"expires_at": null,
"created_at": "2026-09-14T18:02:11.204+00:00"
}
],
"username": "ada"
}
}/api/ v1/ account/ birth-dateDevolve a data de nascimento guardada e como a idade foi confirmada. Só para a sessão: as colunas são revogadas de todo mundo, e a função definidora responde por quem pergunta e por mais ninguém.
/api/ v1/ account/ birth-dateGuarda a data de nascimento. A regra de idade é do banco, que recusa em vez de guardar uma data recente demais.
Corpo
| Campo | Tipo | Observações |
|---|---|---|
birth_dateobrigatório | string | Uma data como YYYY-MM-DD. |
/api/ v1/ account/ sessionsOnde a conta está entrada, e em quê.
/api/ v1/ account/ sessions/ {id}Encerra uma sessão. Inclusive a que está fazendo o pedido, que é como se sai de todos os lugares de uma vez.
/api/ v1/ account/ identitiesOs provedores com que esta conta consegue entrar.
/api/ v1/ account/ exportTudo o que a conta escreveu, num documento só. Uma sessão que ainda deve o segundo fator recebe 403 com reason mfa_required.
/api/ v1/ account/ dataJoga fora um tipo de coisa, pelo nome. A categoria é obrigatória e nunca tem padrão: um delete que adivinha o que foi mandado remover é um delete que ninguém desfaz. Pede, no corpo JSON, a prova de que é a pessoa dona da conta agora (veja password e code): uma sessão esquecida aberta bastava para esvaziar a conta. Antes de qualquer prova, uma sessão que ainda deve o segundo fator recebe 403 forbidden com reason mfa_required. Responde quantos registros saíram, e não um "pronto": dizer que os dados sumiram quando não havia nenhum é uma afirmação, não uma confirmação.
Parâmetros
| Campo | Tipo | Observações |
|---|---|---|
categoryobrigatório | string | library, reviews, sessions, journeys, lists, screenshots, comments, views ou everything. |
Corpo
| Campo | Tipo | Observações |
|---|---|---|
password | string | A senha atual. Obrigatória para uma conta que tem senha, sempre. Sem ela, 403 forbidden com reason password_required; errada, reason password_incorrect. |
code | string | Para uma conta sem senha e com verificação em duas etapas: seis dígitos do app autenticador ou um código de recuperação, no lugar de entrar de novo. Sem senha, uma sessão aberta nos últimos 15 minutos já basta; depois disso, 403 forbidden com reason reauthentication_required e second_factor dizendo se um code serve. Tentativas de senha ou code: 10 a cada 15 minutos por conta, depois 429 rate_limited com retry_after. |
/api/ v1/ account/ keysAs chaves da conta. Nunca o token: só o hash é guardado, numa coluna que nenhum papel que fala com esta API recebe.
/api/ v1/ account/ keysCria uma chave num dos seus aplicativos, com as permissões dele. O token vem uma vez, nesta resposta, e nunca mais: depois disso ninguém consegue lê-lo, nem nós.
Corpo
| Campo | Tipo | Observações |
|---|---|---|
app_idobrigatório | uuid | O aplicativo da chave. Toda chave pertence a um, feito no portal do desenvolvedor. |
nameobrigatório | string | Até 60 caracteres. |
expires_in_days | integer | Em quantos dias ela expira. null para nunca. |
/api/ v1/ account/ connections/ {service}Esquece uma conta ligada: twitch ou steam. Só o desfazer mora aqui. Ligar uma é uma ida e volta de OAuth que precisa voltar para uma página, então começa e termina no navegador; esquecer é uma escrita só, e escrita é aqui.
/api/ v1/ account/ keys/ {id}Revoga uma chave. Vale já na requisição seguinte.
/api/ v1/ account/ appsOs aplicativos da conta, os alterados por último primeiro, com quantas chaves vivas cada um tem e quando uma delas foi usada pela última vez. arcade resume, numa linha, onde o jogo do aplicativo está no Arcade, ou vem null para um aplicativo sem Arcade: slug, status, hidden_reason, notice (suspended, flagged, hidden ou null), live_release_number, listing (approved, pending, draft e rejected), releases (draft, pending, ready e rejected_latest) e data_events (pending, held, que é parte de pending, e failed). É o mesmo membro em todas as respostas de aplicativo, e o Arcade tem os detalhes em /api/v1/account/apps/{id}/arcade.
Exemplo
{
"data": [
{
"id": "...",
"name": "Orbit Runner",
"description": "",
"icon_url": null,
"scopes": [],
"created_at": "2026-10-14T18:00:00.000Z",
"updated_at": "2026-10-14T18:00:00.000Z",
"active_keys": 0,
"last_used_at": null,
"arcade": {
"slug": "orbit-runner",
"status": "listed",
"hidden_reason": null,
"notice": null,
"live_release_number": 3,
"listing": {
"approved": true,
"pending": null,
"draft": false,
"rejected": false
},
"releases": {
"draft": 1,
"pending": 0,
"ready": 0,
"rejected_latest": false
},
"data_events": { "pending": 0, "held": 0, "failed": 0 }
}
}
]
}/api/ v1/ account/ appsCria um aplicativo, sem permissões. Até 10 por conta.
Corpo
| Campo | Tipo | Observações |
|---|---|---|
nameobrigatório | string | Até 60 caracteres. |
description | string | Até 400 caracteres. |
/api/ v1/ account/ apps/ {id}Um aplicativo e as chaves dele, as vivas primeiro, com o mesmo arcade da lista (null sem Arcade).
/api/ v1/ account/ apps/ {id}Muda o nome, a descrição ou as permissões. As permissões valem também para todas as chaves vivas do aplicativo, já na requisição seguinte.
Corpo
| Campo | Tipo | Observações |
|---|---|---|
name | string | Até 60 caracteres. |
description | string | Até 400 caracteres. |
scopes | array | As permissões do aplicativo, por inteiro: as que ficarem de fora são retiradas. |
/api/ v1/ account/ apps/ {id}Exclui o aplicativo e todas as chaves dele, que param de funcionar na requisição seguinte. Um aplicativo com um jogo no Arcade não sai antes de o jogo ser removido do Arcade: 409 conflict com reason remove_from_arcade_first.
/api/ v1/ account/ apps/ {id}/ keysAs chaves de um aplicativo. Nunca o token.
/api/ v1/ account/ apps/ {id}/ keysCria uma chave para o aplicativo, com as permissões dele. O token vem uma vez, nesta resposta.
Corpo
| Campo | Tipo | Observações |
|---|---|---|
nameobrigatório | string | Até 60 caracteres. |
expires_in_days | integer | Em quantos dias ela expira, de 1 a 3650. null para nunca. |
/api/ v1/ account/ apps/ {id}/ iconTroca o ícone: a imagem em multipart/form-data, no campo image (JPEG, PNG, WebP, GIF ou AVIF, até 15 MB). Ela é tratada como um avatar: reduzida para caber em 512x512 (o portal a mostra recortada em quadrado), com no máximo 500 KB parada ou 4 MB e 15 segundos animada, e passa pela mesma verificação de conteúdo. Responde id e icon_url. Um arquivo de outro tipo ou acima de 15 MB, ou uma imagem que a verificação de conteúdo recusa, é 400 invalid_request; uma imagem que não pôde ser processada também, e então com reason: invalid_image (não deu para ler), invalid_format (o conteúdo não é do tipo enviado), too_many_frames (mais de 300 quadros), too_many_pixels (mais de 40 milhões de pixels, somando os quadros), animation_too_long (mais de 15 segundos), unsupported_animation (um PNG ou AVIF animado, ou uma animação sem a duração de cada quadro) ou too_heavy (continua acima de 500 KB, ou de 4 MB animada, mesmo depois de otimizada). 404 quando o aplicativo não é seu.
/api/ v1/ account/ apps/ {id}/ iconTira o ícone; o aplicativo volta a mostrar as iniciais.
Provar que é você
Limpar dados (DELETE /api/v1/account/data) não tem volta, então uma sessão
sozinha não basta: quem encontra um notebook esquecido com a conta aberta tem
uma sessão. O pedido leva um corpo JSON com a prova de que é a pessoa dona da
conta quem está pedindo agora:
- Uma conta com senha manda a senha em
password, toda vez. - Uma conta sem senha (entra com Google, Discord, Twitch ou uma chave de
acesso) não precisa de mais nada se a sessão começou nos últimos 15
minutos. Depois disso, entra de novo ou, com a verificação em duas etapas
ligada, manda
code: seis dígitos do app autenticador ou um código de recuperação.
Uma recusa é 403 forbidden com um reason para agir:
{
"error": {
"code": "forbidden",
"message": "Sign in again to do this: the session has to have started in the last 15 minutes.",
"reason": "reauthentication_required",
"second_factor": true
}
}reason é um de password_required, password_incorrect,
reauthentication_required (com second_factor, se um code serviria) e
code_incorrect. Cada conta tem 10 tentativas de senha ou código a cada 15
minutos; passando disso, a resposta é 429 rate_limited com reason
too_many_attempts e retry_after em segundos.
Antes de tudo isso, uma sessão que ainda deve o segundo fator (a conta tem a
verificação em duas etapas ligada e o código não foi digitado ao entrar)
recebe 403 forbidden com reason mfa_required, seja qual for o corpo. O
caminho é concluir a verificação em duas etapas do login; um code no corpo
não substitui esse passo.
Uma sessão antiga também não consegue se renovar para passar por aqui. Numa
conta sem senha, os endpoints de login que dariam a ela uma sessão nova, um
segundo fator ou uma chave de acesso (ligar ou desligar a verificação em duas
etapas, concluir a configuração dela, ler o segredo do app autenticador, gerar
códigos de recuperação, registrar uma chave de acesso) recusam quando a sessão
passou desses 15 minutos, e o caminho é o mesmo: entrar de novo. Eles ficam em
/api/auth, o serviço de login do site, e respondem 403 no formato dele:
{
"code": "RECENT_SIGN_IN_REQUIRED",
"message": "Sign in again to do this: the session has to have started in the last 15 minutes."
}Criar a primeira senha (POST /api/account/password, a rota do site para
isso) segue a mesma regra, porque uma senha também é uma prova que dura mais
que a sessão: passados os 15 minutos, a resposta é 403 com
{ "error": "reauthentication_required", "second_factor": false }.
Uma conta com senha não muda: a prova dela é a senha, e nenhuma sessão nova toma o lugar dela.