API: fani, konwersacje i wiadomości
Fan to użytkownik Telegrama, który napisał do jednej z Twoich twórczyń. Konwersacja to czat między tym fanem a jednym kontem Telegram. Wiadomości wysyła AI, członek zespołu lub skrypt. Te endpointy odpowiadają zakładkom Live Convs i Fans w Console.
Endpoints #
| Method | Path | Description | Permission | Status |
|---|---|---|---|---|
| GET | /fans | Lista fanów (creator_id=, status=, list_id=, q=, spent_min=) | can_fan_read | Planned |
| GET | /fans/{id} | Jeden fan: języki, wydatki, status, listy, notatki | can_fan_read | Planned |
| PATCH | /fans/{id} | Zmień alias fana, język odpowiedzi lub notatki | can_chat | Planned |
| GET | /fans/{id}/sales | Zakupy fana | can_sales_read | Planned |
| POST | /fans/import | Importuj wcześniejszych fanów i wiadomości (nic nie wysyła) | can_fan_import | Planned |
| GET | /fan-lists | Listy (VIP, win back…) | can_fan_read | Planned |
| POST | /fan-lists | Utwórz listę | can_chat | Planned |
| POST | /fan-lists/{id}/members | Dodaj fanów do listy | can_chat | Planned |
| DELETE | /fan-lists/{id}/members | Usuń fanów z listy | can_chat | Planned |
| GET | /conversations | Lista konwersacji (creator_id=, account_id=, state=, unread=true) | can_fan_read | Planned |
| GET | /conversations/{id} | Jedna konwersacja i kto odpowiada | can_fan_read | Planned |
| GET | /conversations/{id}/messages | Wiadomości, od najnowszych (translate=en dodaje tłumaczenie) | can_fan_read | Planned |
| POST | /conversations/{id}/messages | Wyślij wiadomość jako twórczyni (tekst, media, oferta) | can_chat | Planned |
| POST | /conversations/{id}/reactions | Dodaj lub usuń reakcję na wiadomość fana | can_chat | Planned |
| POST | /conversations/{id}/takeover | Przejmuje osoba: AI przestaje odpowiadać temu fanowi | can_chat | Planned |
| POST | /conversations/{id}/release | Oddaj konwersację AI | can_chat | Planned |
| POST | /conversations/{id}/script | Uruchom skrypt na tej konwersacji | can_chat | Planned |
| POST | /conversations/{id}/read | Oznacz konwersację jako przeczytaną | 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 | Zaczyna się od fan_ |
display_name | string | Imię fana na Telegramie |
username | string or null | Telegramowy @username fana, bez @ |
creator_id | string | Twórczyni, do której napisał fan |
purchases | number | Zweryfikowane zakupy do tej pory |
spent | object | Wydane łącznie: stars i net_cents w centach USD po odjęciu prowizji Telegrama i zwrotów |
lists | array of strings | Identyfikatory list fanów, do których należy |
Fan ma też języki, w których pisze, tag statusu, notatki zespołu, alias i język odpowiedzi, jak na stronie 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 | Zaczyna się od conv_ |
fan_id, creator_id, account_id | string | Kto z kim rozmawia, na którym koncie Telegram |
state | string | Kto odpowiada: ai, human (przejęte), script (działa skrypt) lub off |
status | object | tag (tagi statusu ze strony Fans) i reason, jeśli jest |
unread | number | Liczba nieprzeczytanych wiadomości od fana |
last_message_at | string | ISO 8601, UTC |
spent | object | Ile fan wydał w tej konwersacji: stars i net_cents |
source_link_id | string or null | Link śledzący, z którego przyszedł fan |
status.tag odpowiada tagom statusu ze strony Fans (review, safety_hold, converted, lost, underage…). Konwersacji w stanie off z powodu bezpieczeństwa nie można oddać 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 | Zaczyna się od msg_ |
from | string | creator lub fan |
sent_by | string | Dla wiadomości twórczyni: ai, human lub script |
member_id | string | Członek zespołu, który wysłał, gdy sent_by to human z Console |
token_id | string | Token dostępu, który wysłał, jeśli przyszło z API |
text | string | Tekst wiadomości |
media | array | Wysłane media: id, locked (płatne i niekupione) i cena w stars |
reactions | array | Reakcje na wiadomość fana |
status | string | Dla wysyłanych wiadomości: queued, sent, read lub failed |
at | string | ISO 8601, UTC |
sent_by decyduje o prowizji od sprzedaży, więc ustawia go serwer, nigdy Twoje żądanie.
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 | Zaczyna się od sale_ |
fan_id, creator_id, account_id, conversation_id | string | Kto kupił, od kogo, gdzie |
stars | number | Cena w Telegram Stars |
net_cents | number | Wartość netto w centach USD (1 Star = $0.013) |
sent_by | string | ai, human lub script: kto wysłał ofertę, decyduje o prowizji |
kind | string | Co zostało kupione, np. offer |
Ten sam obiekt przychodzi przez webhook, event sale.completed.
Fans #
List fans #
GET /fans · can_fan_read
| Parameter | Type | Required | Description |
|---|---|---|---|
creator_id | string | Nie | Tylko fani tej twórczyni |
status | string | Nie | Tag statusu ze strony Fans, np. converted |
list_id | string | Nie | Tylko fani z tej listy |
q | string | Nie | Fragment imienia lub username fana |
spent_min | number | Nie | Tylko fani, którzy wydali co najmniej tyle Stars |
limit, cursor | number, string | Nie | Paginacja |
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"
Odpowiedź to fan object. Nieznane id zwraca 404.
Update a fan #
PATCH /fans/{id} · can_chat
Wyślij tylko to, co się zmienia: alias fana, język odpowiedzi lub notatki. Odpowiedź to zaktualizowany fan.
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
}
Stronicowana lista sale objects. Po sumy dzienne, według linku lub źródła, użyj stats.
Import fan history #
POST /fans/import · can_fan_import
Dodaje wcześniejszych fanów i ich wiadomości do Twoich danych, np. z innego narzędzia. Nigdy nie wysyła wiadomości do fana i nie potwierdza zakupu.
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 | Tak | Nazwa widoczna na stronie 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"}'
Odpowiedź to nowa lista (201).
Add or remove fans #
POST /fan-lists/{id}/members i DELETE /fan-lists/{id}/members · can_chat
| Parameter | Type | Required | Description |
|---|---|---|---|
fan_ids | array of strings | Tak | Fani do dodania lub usunięcia |
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 przyjmuje to samo body. Nieznana lista lub fan zwraca 404.
Conversations #
List conversations #
GET /conversations · can_fan_read
| Parameter | Type | Required | Description |
|---|---|---|---|
creator_id | string | Nie | Tylko ta twórczyni |
account_id | string | Nie | Tylko to konto Telegram |
state | string | Nie | ai, human, script lub off |
unread | boolean | Nie | true: tylko konwersacje z nieprzeczytanymi wiadomościami fana |
limit, cursor | number, string | Nie | Paginacja |
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"
Odpowiedź to conversation object; state pokazuje kto odpowiada.
Read messages #
GET /conversations/{id}/messages · can_fan_read
| Parameter | Type | Required | Description |
|---|---|---|---|
translate | string | Nie | Kod języka, np. en: każda wiadomość dostaje tłumaczenie |
limit, cursor | number, string | Nie | Paginacja, od najnowszych |
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 to ai, human (z member_id) lub script.
Send a message #
POST /conversations/{id}/messages · can_chat
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Tak, lub media | Tekst, jako twórczyni |
media | array | Nie | Vault media: id i stars, by sprzedać zablokowane za tę cenę |
send_at | string or null | Nie | Czas ISO 8601, by zaplanować do 7 dni naprzód; null wysyła od razu |
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" }
- Wiadomość wysłana przez API liczy się jako wysłana przez osobę (
sent_by: "human", z tokenem, który ją wysłał) i przejmuje konwersację (state: "human") do czasu oddania jej AI. statusprzechodzi przezqueued,sent, potemread;failedzawiera powód z Telegrama (np. flood wait).send_atplanuje wiadomość (do 7 dni naprzód).
React to a message #
POST /conversations/{id}/reactions · can_chat
| Parameter | Type | Required | Description |
|---|---|---|---|
message_id | string | Tak | Wiadomość fana |
emoji | string | Tak | Reakcja |
on | boolean | Tak | true dodaje, false usuwa |
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" }
AI przestaje odpowiadać temu fanowi, dopóki nie oddasz konwersacji.
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)"
Odpowiedź to konwersacja z state: "ai". Konwersacji w stanie off z powodu bezpieczeństwa nie można oddać AI (409).
Run a script #
POST /conversations/{id}/script · can_chat
| Parameter | Type | Required | Description |
|---|---|---|---|
script_id | string | Tak | Skrypt tej samej twórczyni, patrz 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"}'
Podczas działania skryptu state konwersacji to 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)"
unread konwersacji wraca do 0.