API: fan, conversazioni e messaggi
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 #
| Method | Path | Description | Permission | Status |
|---|---|---|---|---|
| GET | /fans | Elenca i fan (creator_id=, status=, list_id=, q=, spent_min=) | can_fan_read | Planned |
| GET | /fans/{id} | Un fan: lingue, spesa, stato, liste, note | can_fan_read | Planned |
| PATCH | /fans/{id} | Modifica alias, lingua di risposta o note del fan | can_chat | Planned |
| GET | /fans/{id}/sales | Gli acquisti del fan | can_sales_read | Planned |
| POST | /fans/import | Importa fan e messaggi passati (non invia mai nulla) | can_fan_import | Planned |
| GET | /fan-lists | Liste (VIP, win back…) | can_fan_read | Planned |
| POST | /fan-lists | Crea una lista | can_chat | Planned |
| POST | /fan-lists/{id}/members | Aggiungi fan a una lista | can_chat | Planned |
| DELETE | /fan-lists/{id}/members | Rimuovi fan da una lista | can_chat | Planned |
| GET | /conversations | Elenca conversazioni (creator_id=, account_id=, state=, unread=true) | can_fan_read | Planned |
| GET | /conversations/{id} | Una conversazione e chi sta rispondendo | can_fan_read | Planned |
| GET | /conversations/{id}/messages | Messaggi, dal più recente (translate=en aggiunge una traduzione) | can_fan_read | Planned |
| POST | /conversations/{id}/messages | Invia un messaggio come la creator (testo, media, offerta) | can_chat | Planned |
| POST | /conversations/{id}/reactions | Aggiungi o rimuovi una reazione a un messaggio del fan | can_chat | Planned |
| POST | /conversations/{id}/takeover | Una persona prende il controllo: l'AI smette di rispondere a questo fan | can_chat | Planned |
| POST | /conversations/{id}/release | Restituisci la conversazione all'AI | can_chat | Planned |
| POST | /conversations/{id}/script | Esegui uno script su questa conversazione | can_chat | Planned |
| POST | /conversations/{id}/read | Segna la conversazione come letta | can_chat | Planned |
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"]
}
| Field | Type | Description |
|---|---|---|
id | string | Inizia con fan_ |
display_name | string | Il nome del fan su Telegram |
username | string or null | L'@username Telegram del fan, senza la @ |
creator_id | string | La creator a cui ha scritto questo fan |
purchases | number | Acquisti verificati finora |
spent | object | Totale speso: stars e net_cents in centesimi di dollaro USA dopo la quota Telegram e rimborsi |
lists | array of strings | Id 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"
}
| Field | Type | Description |
|---|---|---|
id | string | Inizia con conv_ |
fan_id, creator_id, account_id | string | Chi parla con chi, su quale account Telegram |
state | string | Chi risponde: ai, human (presa in carico), script (sta girando uno script) oppure off |
status | object | tag (i tag di stato della pagina Fans) e il reason se presente |
unread | number | Messaggi del fan ancora non letti |
last_message_at | string | ISO 8601, UTC |
spent | object | Quanto ha speso il fan in questa conversazione: stars e net_cents |
source_link_id | string or null | Il 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"
}
| Field | Type | Description |
|---|---|---|
id | string | Inizia con msg_ |
from | string | creator o fan |
sent_by | string | Per i messaggi della creator: ai, human o script |
member_id | string | Il membro del team che l'ha inviato, se sent_by è human dalla Console |
token_id | string | Il token di accesso che l'ha inviato, se arriva dall'API |
text | string | Il testo del messaggio |
media | array | Media inviati: id, locked (a pagamento e non ancora acquistato) e prezzo in stars |
reactions | array | Reazioni su un messaggio del fan |
status | string | Per i messaggi inviati: queued, sent, read o failed |
at | string | ISO 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"
}
| Field | Type | Description |
|---|---|---|
sale_id | string | Inizia con sale_ |
fan_id, creator_id, account_id, conversation_id | string | Chi ha acquistato, da chi, dove |
stars | number | Prezzo pagato in Telegram Stars |
net_cents | number | Valore netto in centesimi di dollaro USA (una Star vale $0.013) |
sent_by | string | ai, human o script: chi ha inviato l'offerta, determina la commissione |
kind | string | Cosa è stato acquistato, ad esempio offer |
Lo stesso oggetto arriva tramite webhook, evento sale.completed.
Fans #
List fans #
GET /fans · can_fan_read
| Parameter | Type | Required | Description |
|---|---|---|---|
creator_id | string | No | Solo i fan di questa creator |
status | string | No | Un tag di stato della pagina Fans, ad esempio converted |
list_id | string | No | Solo i fan di questa lista |
q | string | No | Parte del nome o username del fan |
spent_min | number | No | Solo i fan che hanno speso almeno questo numero di Stars |
limit, cursor | number, string | No | Paginazione |
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
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Il 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
| Parameter | Type | Required | Description |
|---|---|---|---|
fan_ids | array of strings | Yes | I 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
| Parameter | Type | Required | Description |
|---|---|---|---|
creator_id | string | No | Solo questa creator |
account_id | string | No | Solo questo account Telegram |
state | string | No | ai, human, script o off |
unread | boolean | No | true: solo conversazioni con messaggi del fan non letti |
limit, cursor | number, string | No | Paginazione |
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
| Parameter | Type | Required | Description |
|---|---|---|---|
translate | string | No | Un codice lingua, ad esempio en: ogni messaggio riceve anche una traduzione |
limit, cursor | number, string | No | Paginazione, 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
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes, o media | Il testo, come la creator |
media | array | No | Media da Vault: id e stars per venderlo bloccato a quel prezzo |
send_at | string or null | No | Orario 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. statuspassa daqueued, asent, poiread;failedriporta il motivo Telegram (ad esempio flood wait).send_atprogramma il messaggio (fino a 7 giorni dopo).
React to a message #
POST /conversations/{id}/reactions · can_chat
| Parameter | Type | Required | Description |
|---|---|---|---|
message_id | string | Yes | Il messaggio del fan |
emoji | string | Yes | La reazione |
on | boolean | Yes | true 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
| Parameter | Type | Required | Description |
|---|---|---|---|
script_id | string | Yes | Uno 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.