Open API
Um endpoint compatível com OpenAI para os seus personagens.
A Reverie oferece um endpoint de Chat Completions compatível com OpenAI. Aponte qualquer cliente da OpenAI para ele, passe uma chave de API da Reverie e use o campo model para nomear um personagem ou cenário em vez de um LLM. A Reverie guarda a conversa, as memórias e os resumos do lado dela, então cada requisição só precisa da sua mensagem nova.
Qualquer conta com login pode usar. Não há faixa de assinatura nem lista de espera — você precisa de uma chave de API, e é só. Criar uma →
URL base e autenticação
https://www.reverie.im/api/device/v1
Authorization: Bearer rk_...Configurações → Mais → Chaves de API mostra a URL base exata no cartão API Endpoint, com um botão de copiar.
Esta é uma API de servidor. Requisições de navegador vindas de outra origem são bloqueadas, então um fetch a partir da sua própria página web vai falhar por mais certa que esteja a chave. Chame a partir de um backend e mantenha a chave fora do código do cliente.
Começando rápido
curl --no-buffer https://www.reverie.im/api/device/v1/chat/completions \
-H "Authorization: Bearer $REVERIE_API_KEY" \
-H "Content-Type: application/json" \
--data-binary '{
"model": "Luna [abc12345]",
"messages": [
{
"role": "user",
"content": "Hi"
}
],
"stream": true,
"temperature": 0.8
}'Configurações → Mais → Chaves de API também tem um construtor de requisições que gera esses três trechos com uma das suas chaves reais e um personagem real.
O campo model nomeia um personagem
Só o nome do personagem não funciona. model: "Luna" não procura um personagem chamado Luna. Não casa com nada, escorrega para o personagem padrão da chave ou para a sua conversa mais recente, e você recebe a resposta de outro personagem sem erro nenhum. Use sempre a forma Nome [idcurto] que o GET /models devolve.
Valor de model | Quem responde |
|---|---|
Luna [abc12345] | O personagem ou cenário cujo ID termina nesses 8 caracteres |
| Um ID completo de personagem ou cenário | Aquele personagem ou cenário |
Um ID de modelo da Reverie, por ex. deepseek-v4-flash | Escolhe o LLM; o personagem vem da chave ou da sua última conversa |
| Omitido | O personagem preso à chave, senão a sua conversa mais recente |
Detalhes que decidem se um ID curto resolve:
- O
[...]precisa estar no fim da string. - Um sufixo de 8 caracteres ou menos só é comparado com personagens com quem você já tem conversa, na web ou pela API. O ID curto de um personagem que você nunca abriu falha em silêncio.
- A busca de cenário só roda quando a chave está presa a um personagem. Com uma chave global, um ID curto de cenário nunca resolve.
- Mais de 8 caracteres é tratado como ID completo.
Listar com quem você pode falar
curl https://www.reverie.im/api/device/v1/models \
-H "Authorization: Bearer $REVERIE_API_KEY"Uma chave global devolve os seus personagens recentes. Uma chave presa a um personagem devolve os cenários daquele personagem, ou o próprio personagem se ele não tiver nenhum. Cada entrada se parece com isto:
{
"id": "Luna [abc12345]",
"object": "model",
"created": 1759200000,
"owned_by": "character",
"permission": [],
"root": "<full character id>",
"parent": null
}Copie o id direto para model. Os erros deste endpoint usam um formato de erro simples, não o envelope da OpenAI.
O que o corpo da requisição lê
Quatro campos são lidos. Todo o resto é aceito e descartado em silêncio.
| Campo | Tipo | Padrão | Observações |
|---|---|---|---|
messages | array | obrigatório | Veja abaixo — só parte dele é usada |
model | string | opcional | Personagem, cenário ou LLM, como acima |
stream | booleano | true | Streaming é o padrão, diferente da API da OpenAI |
temperature | número 0–2 | a configuração do personagem, senão 0.8 | Valores fora da faixa são rejeitados |
Ignorados sem aviso: max_tokens, top_p, n, stop, presence_penalty, frequency_penalty, logit_bias, seed, user, response_format, tools, tool_choice, logprobs, stream_options.
Como messages é tratado:
- Mensagens
systemsão descartadas. Personalidade e comportamento vêm dos campos do próprio personagem, não da requisição. Campos do prompt → - Não há suporte a visão. O conteúdo pode ser uma string ou um array de partes, mas só as partes
textsão lidas; partes de imagem são ignoradas. - Só a última mensagem
useré acrescentada à conversa. Mensagens de usuário anteriores são ignoradas. - Mensagens de assistente servem apenas para sincronizar o histórico (abaixo).
- Uma última mensagem de usuário vazia ou só com espaços devolve
missing_user_message.
Respostas
Uma resposta sem streaming é um objeto chat.completion comum. finish_reason é sempre stop — chamadas internas de ferramenta nunca aparecem — e os contadores de usage vêm zerados, então meça tokens pelas estatísticas de uso da página de chaves de API, não pela resposta.
Uma resposta em streaming é text/event-stream:
- Trechos de conteúdo: objetos
chat.completion.chunkcomdelta.content. Nenhum trecho inicialdelta: {"role": "assistant"}é enviado. - Um trecho de encerramento, com
finish_reasonigual astop,lengthoucontent_filter. Encerramentos por chamada de ferramenta são relatados comostop. - Um trecho de uso com o array
choicesvazio. data: [DONE].
Se a geração falhar no meio do stream, o stream emite data: {"error": {...}} e depois [DONE].
Estado da conversa
A Reverie guarda a conversa. Existe uma conversa para cada par de chave e personagem, ela aparece no app web junto das suas outras conversas, e cada turno é montado com o prompt de sistema e o cenário do personagem, o cânone dos world books, as memórias de longo prazo, os resumos que vão se acumulando, o estilo de narração do personagem, o tamanho de resposta e os ajustes NSFW, uma trava de idioma vinda do idioma da sua conta, e tanto do histórico recente quanto couber na janela de contexto do modelo. As ferramentas de memória rodam quando o modelo aceita ferramentas.
Como o servidor guarda o histórico, você não precisa mandá-lo de novo.
Enviar mensagens de assistente pode apagar histórico. Se o seu array messages contiver mensagens de assistente, a Reverie pega a última, procura entre as 20 mensagens guardadas mais recentes e, se achar, apaga em definitivo todas as mensagens criadas depois dela, junto das memórias criadas a partir daquele ponto. Se não achar nada, nada é apagado. O tamanho do seu array não importa. Para evitar isso por completo, mande só a mensagem nova do usuário.
Qual LLM responde
Quem decide é o personagem, não a requisição — a não ser que você nomeie um LLM. Precedência, da mais fraca à mais forte: o modelo de conversa padrão, depois a configuração de modelo do próprio personagem, depois um ID de modelo da Reverie passado em model, e por fim a preferência de modelo que você definiu para aquela conversa no app web, que ganha de todas. Modelos →
Erros
Os erros de /chat/completions usam o envelope da OpenAI: {"error": {"message", "type", "param": null, "code"}}.
| HTTP | code | type | Causa |
|---|---|---|---|
| 401 | invalid_api_key | invalid_request_error | Authorization faltando ou malformado, chave desconhecida, ou chave inativa |
| 401 | api_key_expired | invalid_request_error | A chave passou da validade |
| 404 | scenario_not_found | invalid_request_error | O ID de cenário resolveu, mas o cenário sumiu |
| 404 | character_not_found | invalid_request_error | O personagem não existe ou foi apagado |
| 404 | no_chat_history | invalid_request_error | Sem model, sem personagem preso e sem conversa anterior para recorrer |
| 400 | missing_user_message | invalid_request_error | Nenhuma mensagem user não vazia |
| 429 | rate_limit_exceeded | rate_limit_exceeded | Janela de modelos gratuitos esgotada. Retry-After dá os segundos de espera |
| 429 | insufficient_quota | insufficient_quota | Créditos insuficientes para a requisição |
| 502 | MODEL_EMPTY_RESPONSE | server_error | O modelo terminou direitinho, mas sem texto |
| varia | código do provedor | server_error | A geração falhou lá em cima |
Dois casos ficam fora desse envelope: os erros do GET /models e os corpos de requisição rejeitados pela validação (uma temperature fora da faixa, por exemplo) — ambos devolvem um formato de erro simples.
Limites de uso e cotas
Esta API não tem limite de requisições por chave, nem teto de concorrência, nem cota de requisições. Duas coisas limitam o seu uso:
| Limite | Valor |
|---|---|
| Saldo de créditos | Verificado antes de cada requisição; se falhar, devolve insufficient_quota |
| Janela de modelos gratuitos | 15 mensagens a cada 3 horas, por conta — ×3 no Pro (45), ×4 no Premium (60), ×5 no Ultimate (75) |
A janela de modelos gratuitos é dividida com a conversa na web, as histórias, os romances e os bots — é uma cota por conta, não uma por lugar. Modelos gratuitos →
A Reverie não manda webhooks para fora; não há nada a que se inscrever para saber quando a geração terminou.
Importar personagens
Um segundo endpoint, POST /api/v1/characters/import, cria um personagem a partir de uma ficha de personagem. Ele exige uma chave com escopo de importação, que não é o tipo de chave que a página de configurações cria. Chaves de API → e Importar personagens →
Relacionado
- Chaves de API — criar, prender, expirar e acompanhar chaves
- Modelos — IDs de modelo e multiplicadores de créditos
- Limites — os outros tetos do produto
- Créditos — como as requisições são cobradas