LanaChat

API: fãs, conversas e mensagens

Leitura de 7 minAtualizado Markdown

Um fan é um usuário do Telegram que escreveu para uma das suas criadoras. Uma conversation é o chat entre esse fã e uma conta do Telegram. As mensagens podem ser enviadas pela IA, por uma pessoa da equipe ou por um script. Esses endpoints correspondem a Live Convs e Fans no Console.

Endpoints #

MethodPathDescriptionPermissionStatus
GET/fansLista fãs (creator_id=, status=, list_id=, q=, spent_min=)can_fan_readPlanned
GET/fans/{id}Um fã: idiomas, gastos, status, listas, notascan_fan_readPlanned
PATCH/fans/{id}Altera o alias, idioma de resposta ou notas do fãcan_chatPlanned
GET/fans/{id}/salesCompras do fãcan_sales_readPlanned
POST/fans/importImporta fãs e mensagens antigas (nunca envia nada)can_fan_importPlanned
GET/fan-listsListas (VIPs, win back…)can_fan_readPlanned
POST/fan-listsCria uma listacan_chatPlanned
POST/fan-lists/{id}/membersAdiciona fãs a uma listacan_chatPlanned
DELETE/fan-lists/{id}/membersRemove fãs de uma listacan_chatPlanned
GET/conversationsLista conversas (creator_id=, account_id=, state=, unread=true)can_fan_readPlanned
GET/conversations/{id}Uma conversa e quem está respondendocan_fan_readPlanned
GET/conversations/{id}/messagesMensagens, mais recentes primeiro (translate=en adiciona tradução)can_fan_readPlanned
POST/conversations/{id}/messagesEnvia mensagem como a criadora (texto, mídia, oferta)can_chatPlanned
POST/conversations/{id}/reactionsAdiciona ou remove reação em mensagem do fãcan_chatPlanned
POST/conversations/{id}/takeoverUma pessoa assume: a IA para de responder esse fãcan_chatPlanned
POST/conversations/{id}/releaseDevolve a conversa para a IAcan_chatPlanned
POST/conversations/{id}/scriptRoda um script nessa conversacan_chatPlanned
POST/conversations/{id}/readMarca a conversa como lidacan_chatPlanned

The fan object #

{
  "id": "fan_921",
  "display_name": "Marco",
  "username": "marco_dl",
  "creator_id": "cr_lea",
  "purchases": 9,
  "spent": { "stars": 1450, "net_cents": 1885 },
  "lists": ["vip"]
}
FieldTypeDescription
idstringComeça com fan_
display_namestringNome do fã no Telegram
usernamestring or nullO @username do fã no Telegram, sem o @
creator_idstringA criadora para quem o fã escreveu
purchasesnumberCompras verificadas até agora
spentobjectTotal gasto: stars e net_cents em centavos de dólar, já descontando a taxa do Telegram e reembolsos
listsarray of stringsIds das listas em que o fã está

Um fã também traz os idiomas em que escreve, o status, as notas da equipe, um alias e o idioma de resposta, como na página Fans.

The conversation object #

{
  "id": "conv_1001_88231",
  "fan_id": "fan_921",
  "creator_id": "cr_lea",
  "account_id": "acc_1001",
  "state": "ai",
  "status": { "tag": "active", "reason": null },
  "unread": 2,
  "last_message_at": "2026-10-06T14:02:51Z",
  "spent": { "stars": 1450, "net_cents": 1885 },
  "source_link_id": "lnk_3"
}
FieldTypeDescription
idstringComeça com conv_
fan_id, creator_id, account_idstringQuem fala com quem, em qual conta do Telegram
statestringQuem responde: ai, human (assumida), script (um script está rodando) ou off
statusobjecttag (os status da página Fans) e o reason quando houver
unreadnumberMensagens do fã ainda não lidas
last_message_atstringISO 8601, UTC
spentobjectO que o fã gastou nessa conversa: stars e net_cents
source_link_idstring or nullO link de rastreio de onde veio o fã

status.tag corresponde aos status da página Fans (review, safety_hold, converted, lost, underage…). Uma conversa em off por motivo de segurança não pode ser devolvida para a IA (409).

The message object #

{
  "id": "msg_77120",
  "from": "creator",
  "sent_by": "ai",
  "text": "Made this one this morning…",
  "media": [ { "id": "med_5521", "locked": true, "stars": 300 } ],
  "at": "2026-10-06T14:02:51Z"
}
FieldTypeDescription
idstringComeça com msg_
fromstringcreator ou fan
sent_bystringPara mensagens da criadora: ai, human ou script
member_idstringO membro da equipe que enviou, quando sent_by for human pelo Console
token_idstringO token de acesso que enviou, quando veio da API
textstringTexto da mensagem
mediaarrayMídias enviadas: id, locked (paga e ainda não comprada) e preço em stars
reactionsarrayReações em mensagem do fã
statusstringPara mensagens enviadas: queued, sent, read ou failed
atstringISO 8601, UTC

O campo sent_by define a comissão da venda, então ele é definido pelo servidor e nunca pelo seu request.

The sale object #

{
  "sale_id": "sale_8812",
  "fan_id": "fan_921",
  "creator_id": "cr_lea",
  "account_id": "acc_1001",
  "conversation_id": "conv_1001_88231",
  "stars": 300,
  "net_cents": 390,
  "sent_by": "ai",
  "kind": "offer"
}
FieldTypeDescription
sale_idstringComeça com sale_
fan_id, creator_id, account_id, conversation_idstringQuem comprou, de quem, onde
starsnumberValor pago em Telegram Stars
net_centsnumberValor líquido em centavos de dólar (um Star vale $0.013)
sent_bystringai, human ou script: quem enviou a oferta, define a comissão
kindstringO que foi comprado, por exemplo offer

O mesmo objeto chega por webhook, evento sale.completed.

Fans #

List fans #

GET /fans · can_fan_read

ParameterTypeRequiredDescription
creator_idstringNoApenas fãs dessa criadora
statusstringNoUm status da página Fans, por exemplo converted
list_idstringNoApenas fãs dessa lista
qstringNoParte do nome ou username do fã
spent_minnumberNoApenas fãs que gastaram pelo menos essa quantidade de Stars
limit, cursornumber, stringNoPaginação
curl "https://api.lanachat.ai/v1/fans?creator_id=cr_lea&spent_min=1000&limit=50" \
  -H "Authorization: Bearer $LANACHAT_TOKEN"
{
  "data": [
    { "id": "fan_921", "display_name": "Marco", "username": "marco_dl", "creator_id": "cr_lea", "purchases": 9, "spent": { "stars": 1450, "net_cents": 1885 }, "lists": ["vip"] }
  ],
  "next_cursor": null
}

Get a fan #

GET /fans/{id} · can_fan_read

curl https://api.lanachat.ai/v1/fans/fan_921 \
  -H "Authorization: Bearer $LANACHAT_TOKEN"

A resposta é o fan object. Um id desconhecido retorna 404.

Update a fan #

PATCH /fans/{id} · can_chat

Envie apenas o que mudou: alias, idioma de resposta ou notas do fã. A resposta é o fã atualizado.

curl -X PATCH https://api.lanachat.ai/v1/fans/fan_921 \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"notes": "Likes beach sets, buys at night"}'

List a fan's purchases #

GET /fans/{id}/sales · can_sales_read

curl https://api.lanachat.ai/v1/fans/fan_921/sales \
  -H "Authorization: Bearer $LANACHAT_TOKEN"
{
  "data": [
    { "sale_id": "sale_8812", "fan_id": "fan_921", "creator_id": "cr_lea", "account_id": "acc_1001", "conversation_id": "conv_1001_88231", "stars": 300, "net_cents": 390, "sent_by": "ai", "kind": "offer" }
  ],
  "next_cursor": null
}

Uma lista paginada de sale objects. Para totais por dia, link ou origem, use stats.

Import fan history #

POST /fans/import · can_fan_import

Adiciona fãs antigos e suas mensagens ao seu histórico, por exemplo de outra ferramenta. Nunca envia mensagem para o fã e nunca confirma uma compra.

curl -X POST https://api.lanachat.ai/v1/fans/import \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d @fans-history.json

Fan lists #

List fan lists #

GET /fan-lists · can_fan_read

curl https://api.lanachat.ai/v1/fan-lists \
  -H "Authorization: Bearer $LANACHAT_TOKEN"
{
  "data": [ { "id": "vip", "name": "VIP" } ],
  "next_cursor": null
}

Create a list #

POST /fan-lists · can_chat

ParameterTypeRequiredDescription
namestringYesNome exibido na página Fans
curl -X POST https://api.lanachat.ai/v1/fan-lists \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name": "Win back"}'

A resposta é a nova lista (201).

Add or remove fans #

POST /fan-lists/{id}/members e DELETE /fan-lists/{id}/members · can_chat

ParameterTypeRequiredDescription
fan_idsarray of stringsYesFãs para adicionar ou remover
curl -X POST https://api.lanachat.ai/v1/fan-lists/vip/members \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"fan_ids": ["fan_921"]}'

DELETE usa o mesmo corpo. Lista ou fã desconhecido retorna 404.

Conversations #

List conversations #

GET /conversations · can_fan_read

ParameterTypeRequiredDescription
creator_idstringNoApenas essa criadora
account_idstringNoApenas essa conta do Telegram
statestringNoai, human, script ou off
unreadbooleanNotrue: só conversas com mensagens não lidas do fã
limit, cursornumber, stringNoPaginação
curl "https://api.lanachat.ai/v1/conversations?creator_id=cr_lea&unread=true" \
  -H "Authorization: Bearer $LANACHAT_TOKEN"
{
  "data": [
    { "id": "conv_1001_88231", "fan_id": "fan_921", "creator_id": "cr_lea", "account_id": "acc_1001", "state": "ai", "status": { "tag": "active", "reason": null }, "unread": 2, "last_message_at": "2026-10-06T14:02:51Z", "spent": { "stars": 1450, "net_cents": 1885 }, "source_link_id": "lnk_3" }
  ],
  "next_cursor": null
}

Get a conversation #

GET /conversations/{id} · can_fan_read

curl https://api.lanachat.ai/v1/conversations/conv_1001_88231 \
  -H "Authorization: Bearer $LANACHAT_TOKEN"

A resposta é o conversation object; state mostra quem está respondendo.

Read messages #

GET /conversations/{id}/messages · can_fan_read

ParameterTypeRequiredDescription
translatestringNoCódigo do idioma, por exemplo en: cada mensagem também recebe tradução
limit, cursornumber, stringNoPaginação, mais recentes primeiro
curl "https://api.lanachat.ai/v1/conversations/conv_1001_88231/messages?limit=2" \
  -H "Authorization: Bearer $LANACHAT_TOKEN"
{
  "data": [
    { "id": "msg_77120", "from": "creator", "sent_by": "ai", "text": "Made this one this morning…", "media": [ { "id": "med_5521", "locked": true, "stars": 300 } ], "at": "2026-10-06T14:02:51Z" },
    { "id": "msg_77119", "from": "fan", "text": "show me more 😍", "reactions": [], "at": "2026-10-06T14:02:10Z" }
  ],
  "next_cursor": "eyJpZCI6Im1zZ183NzExOCJ9"
}

O campo sent_by pode ser ai, human (com member_id) ou script.

Send a message #

POST /conversations/{id}/messages · can_chat

ParameterTypeRequiredDescription
textstringYes, ou mediaO texto, como a criadora
mediaarrayNoMídia do Vault: id e stars para vender bloqueada por esse valor
send_atstring or nullNoHorário ISO 8601 para agendar, até 7 dias; null envia agora
curl -X POST https://api.lanachat.ai/v1/conversations/conv_1001_88231/messages \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"text": "Only for you, tonight 🔥", "media": [{"id": "med_5522", "stars": 250}], "send_at": null}'
{ "id": "msg_77121", "from": "creator", "sent_by": "human", "token_id": "tok_31", "status": "queued", "at": "2026-10-06T14:03:30Z" }
  • Uma mensagem enviada pela API conta como enviada por uma pessoa (sent_by: "human", com o token que enviou) e assume a conversa (state: "human") até você devolver.
  • O campo status passa por queued, sent, depois read; failed traz o motivo do Telegram (por exemplo flood wait).
  • send_at agenda a mensagem (até 7 dias).

React to a message #

POST /conversations/{id}/reactions · can_chat

ParameterTypeRequiredDescription
message_idstringYesMensagem do fã
emojistringYesA reação
onbooleanYestrue adiciona, false remove
curl -X POST https://api.lanachat.ai/v1/conversations/conv_1001_88231/reactions \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"message_id": "msg_77119", "emoji": "❤️", "on": true}'

Take over #

POST /conversations/{id}/takeover · can_chat

curl -X POST https://api.lanachat.ai/v1/conversations/conv_1001_88231/takeover \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"
{ "id": "conv_1001_88231", "state": "human", "taken_by": "tok_31", "taken_at": "2026-10-06T14:04:00Z" }

A IA para de responder esse fã até você devolver a conversa.

Give back to the AI #

POST /conversations/{id}/release · can_chat

curl -X POST https://api.lanachat.ai/v1/conversations/conv_1001_88231/release \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"

A resposta é a conversa com state: "ai". Uma conversa em off por segurança não pode ser devolvida (409).

Run a script #

POST /conversations/{id}/script · can_chat

ParameterTypeRequiredDescription
script_idstringYesUm script da mesma criadora, veja Scripts
curl -X POST https://api.lanachat.ai/v1/conversations/conv_1001_88231/script \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"script_id": "scr_204"}'

Enquanto roda, o campo state da conversa fica script.

Mark as read #

POST /conversations/{id}/read · can_chat

curl -X POST https://api.lanachat.ai/v1/conversations/conv_1001_88231/read \
  -H "Authorization: Bearer $LANACHAT_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"

O campo unread da conversa volta para 0.

As últimas novidades da Lana no Telegram

Novidades e convites para o beta, primeiro no canal.