LanaChat

API: fan, conversazioni e messaggi

7 min di letturaAggiornato Markdown

Un fan è un utente Telegram che ha scritto a una delle tue creator. Una conversation è la chat tra quel fan e un account Telegram. I messaggi possono essere inviati dall'AI, da un membro del team o da uno script. Questi endpoint corrispondono a Live Convs e Fans nella Console.

Endpoints #

MethodPathDescriptionPermissionStatus
GET/fansElenca i fan (creator_id=, status=, list_id=, q=, spent_min=)can_fan_readPlanned
GET/fans/{id}Un fan: lingue, spesa, stato, liste, notecan_fan_readPlanned
PATCH/fans/{id}Modifica alias, lingua di risposta o note del fancan_chatPlanned
GET/fans/{id}/salesGli acquisti del fancan_sales_readPlanned
POST/fans/importImporta fan e messaggi passati (non invia mai nulla)can_fan_importPlanned
GET/fan-listsListe (VIP, win back…)can_fan_readPlanned
POST/fan-listsCrea una listacan_chatPlanned
POST/fan-lists/{id}/membersAggiungi fan a una listacan_chatPlanned
DELETE/fan-lists/{id}/membersRimuovi fan da una listacan_chatPlanned
GET/conversationsElenca conversazioni (creator_id=, account_id=, state=, unread=true)can_fan_readPlanned
GET/conversations/{id}Una conversazione e chi sta rispondendocan_fan_readPlanned
GET/conversations/{id}/messagesMessaggi, dal più recente (translate=en aggiunge una traduzione)can_fan_readPlanned
POST/conversations/{id}/messagesInvia un messaggio come la creator (testo, media, offerta)can_chatPlanned
POST/conversations/{id}/reactionsAggiungi o rimuovi una reazione a un messaggio del fancan_chatPlanned
POST/conversations/{id}/takeoverUna persona prende il controllo: l'AI smette di rispondere a questo fancan_chatPlanned
POST/conversations/{id}/releaseRestituisci la conversazione all'AIcan_chatPlanned
POST/conversations/{id}/scriptEsegui uno script su questa conversazionecan_chatPlanned
POST/conversations/{id}/readSegna la conversazione come lettacan_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
idstringInizia con fan_
display_namestringIl nome del fan su Telegram
usernamestring or nullL'@username Telegram del fan, senza la @
creator_idstringLa creator a cui ha scritto questo fan
purchasesnumberAcquisti verificati finora
spentobjectTotale speso: stars e net_cents in centesimi di dollaro USA dopo la quota Telegram e rimborsi
listsarray of stringsId delle liste fan in cui si trova questo fan

Un fan include anche le lingue in cui scrive, il tag di stato, le note del team, un alias e una lingua di risposta, come nella pagina 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
idstringInizia con conv_
fan_id, creator_id, account_idstringChi parla con chi, su quale account Telegram
statestringChi risponde: ai, human (presa in carico), script (sta girando uno script) oppure off
statusobjecttag (i tag di stato della pagina Fans) e il reason se presente
unreadnumberMessaggi del fan ancora non letti
last_message_atstringISO 8601, UTC
spentobjectQuanto ha speso il fan in questa conversazione: stars e net_cents
source_link_idstring or nullIl link di tracciamento da cui è arrivato il fan

status.tag corrisponde ai tag di stato della pagina Fans (review, safety_hold, converted, lost, underage…). Una conversazione off per motivi di sicurezza non può essere restituita all'AI (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
idstringInizia con msg_
fromstringcreator o fan
sent_bystringPer i messaggi della creator: ai, human o script
member_idstringIl membro del team che l'ha inviato, se sent_by è human dalla Console
token_idstringIl token di accesso che l'ha inviato, se arriva dall'API
textstringIl testo del messaggio
mediaarrayMedia inviati: id, locked (a pagamento e non ancora acquistato) e prezzo in stars
reactionsarrayReazioni su un messaggio del fan
statusstringPer i messaggi inviati: queued, sent, read o failed
atstringISO 8601, UTC

sent_by determina la percentuale di commissione di una vendita, quindi viene impostato dal server e mai dalla tua richiesta.

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_idstringInizia con sale_
fan_id, creator_id, account_id, conversation_idstringChi ha acquistato, da chi, dove
starsnumberPrezzo pagato in Telegram Stars
net_centsnumberValore netto in centesimi di dollaro USA (una Star vale $0.013)
sent_bystringai, human o script: chi ha inviato l'offerta, determina la commissione
kindstringCosa è stato acquistato, ad esempio offer

Lo stesso oggetto arriva tramite webhook, evento sale.completed.

Fans #

List fans #

GET /fans · can_fan_read

ParameterTypeRequiredDescription
creator_idstringNoSolo i fan di questa creator
statusstringNoUn tag di stato della pagina Fans, ad esempio converted
list_idstringNoSolo i fan di questa lista
qstringNoParte del nome o username del fan
spent_minnumberNoSolo i fan che hanno speso almeno questo numero di Stars
limit, cursornumber, stringNoPaginazione
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"

La risposta è il fan object. Un id sconosciuto restituisce 404.

Update a fan #

PATCH /fans/{id} · can_chat

Invia solo ciò che cambia: alias, lingua di risposta o note del fan. La risposta è il fan aggiornato.

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
}

Una lista paginata di sale objects. Per totali per giorno, link o sorgente, usa stats.

Import fan history #

POST /fans/import · can_fan_import

Aggiunge fan passati e i loro messaggi ai tuoi dati, ad esempio da un altro strumento. Non invia mai messaggi ai fan e non conferma mai un acquisto.

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
namestringYesIl nome mostrato nella pagina 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"}'

La risposta è la nuova lista (201).

Add or remove fans #

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

ParameterTypeRequiredDescription
fan_idsarray of stringsYesI fan da aggiungere o rimuovere
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 lo stesso body. Una lista o un fan sconosciuto risponde 404.

Conversations #

List conversations #

GET /conversations · can_fan_read

ParameterTypeRequiredDescription
creator_idstringNoSolo questa creator
account_idstringNoSolo questo account Telegram
statestringNoai, human, script o off
unreadbooleanNotrue: solo conversazioni con messaggi del fan non letti
limit, cursornumber, stringNoPaginazione
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"

La risposta è il conversation object; state indica chi sta rispondendo.

Read messages #

GET /conversations/{id}/messages · can_fan_read

ParameterTypeRequiredDescription
translatestringNoUn codice lingua, ad esempio en: ogni messaggio riceve anche una traduzione
limit, cursornumber, stringNoPaginazione, dal più recente
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"
}

sent_by può essere ai, human (con member_id) o script.

Send a message #

POST /conversations/{id}/messages · can_chat

ParameterTypeRequiredDescription
textstringYes, o mediaIl testo, come la creator
mediaarrayNoMedia da Vault: id e stars per venderlo bloccato a quel prezzo
send_atstring or nullNoOrario ISO 8601 per programmarlo, fino a 7 giorni dopo; null invia subito
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" }
  • Un messaggio inviato tramite API conta come inviato da una persona (sent_by: "human", con il token che lo ha inviato) e prende il controllo della conversazione (state: "human") finché non la restituisci.
  • status passa da queued, a sent, poi read; failed riporta il motivo Telegram (ad esempio flood wait).
  • send_at programma il messaggio (fino a 7 giorni dopo).

React to a message #

POST /conversations/{id}/reactions · can_chat

ParameterTypeRequiredDescription
message_idstringYesIl messaggio del fan
emojistringYesLa reazione
onbooleanYestrue la aggiunge, false la rimuove
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" }

L'AI smette di rispondere a questo fan finché non restituisci la conversazione.

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)"

La risposta è la conversazione con state: "ai". Una conversazione off per motivi di sicurezza non può essere restituita (409).

Run a script #

POST /conversations/{id}/script · can_chat

ParameterTypeRequiredDescription
script_idstringYesUno script della stessa creator, vedi 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"}'

Durante l'esecuzione, lo state della conversazione è 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)"

Lo unread della conversazione torna a 0.

Le ultime novità su Lana su Telegram

Novità e inviti alla beta, prima di tutto nel canale.