Wiadomości i konwersacje
Interfejs Messages API umożliwia wysyłanie wiadomości do dowolnego kontaktu, odczytywanie konwersacji, poprawianie lub usuwanie już wysłanej wiadomości, reagowanie na nią, pobieranie pełnego wątku czatu, eksportowanie transkrypcji oraz oznaczanie czatów jako przeczytane lub nieprzeczytane — wszystko to bez otwierania skrzynki odbiorczej.
Wszystkie ścieżki na tej stronie są względne względem podstawowego adresu URL https://api.youraiconnector.com/v1. Każde żądanie wymaga Twojego klucza API — zobacz Uwierzytelnianie, aby uzyskać pełną listę sposobów jego przesyłania. Poniższe przykłady wykorzystują nagłówek X-API-Key, a jeden z przykładów cURL pokazuje również formularz zapytania ?apiKey=.
Jak działa dostarczanie: Wysłanie wiadomości nie czeka na jej dotarcie do odbiorcy. API przyjmuje wiadomość, natychmiast zwraca identyfikator wiadomości, a następnie dostarcza ją w tle kanałem kontaktu (WhatsApp, SMS, Instagram itd.). Aby śledzić, czy wiadomość została faktycznie dostarczona lub odczytana, nasłuchuj aktualizacji statusu za pomocą Webhooków — nie używaj odpytywania (polling). Odpowiedź wysyłki potwierdza jedynie, że wiadomość została przyjęta.
Wyślij wiadomość
Istnieją dwa sposoby wysyłania. Wybierz ten, który pasuje do sposobu, w jaki identyfikujesz kontakt:
- Wysyłka według identyfikatora kontaktu — znasz już identyfikator kontaktu (na przykład utworzyłeś kontakt przez API lub otrzymałeś go z webhooka). Użyj
POST /contacts/{contactId}/send-message. - Wysyłka według tożsamości kontaktu — znasz numer telefonu kontaktu, identyfikator Instagrama itp., ale nie znasz jego wewnętrznego identyfikatora. Użyj
POST /contacts/sendi pozwól platformie znaleźć odpowiedni kontakt.
Obie metody ustawiają wiadomość w kolejce w ten sam sposób i dostarczają ją kanałem, z którego korzysta dany kontakt. Nie wybierasz transportu — platforma kieruje kontakty WhatsApp przez WhatsApp, kontakty SMS przez SMS i tak dalej.
Obie metody znajdują tylko kontakty, które już istnieją. Żadne z wywołań nie tworzy nowego kontaktu: jeśli identyfikator lub tożsamość nie pasują do niczego, zwracane jest 404, a nie nowy kontakt. Jeśli więc piszesz do kogoś po raz pierwszy, najpierw utwórz kontakt za pomocą POST /contacts lub w WhatsApp Web użyj poniższej opcji Wyślij bezpośrednio na numer w WhatsApp Web, która tworzy kontakt w ramach tego samego wywołania.
Wyślij według identyfikatora kontaktu
POST /contacts/{contactId}/send-message
| Pole | Wymagane | Opis |
|---|---|---|
body |
Tak | Treść wiadomości do wysłania, do 65 536 znaków. Treść dłuższa niż pozwala na to kanał w jednej wiadomości (1500 w WhatsApp Business API i SMS, 1000 na Instagramie, 2000 na Messengerze, 4096 na Telegramie i LinkedInie, 5000 w LINE, 6000 na TikToku, 7000 w Viberze, 65 536 w WhatsApp Web; brak limitu w e-mailu, widżecie czatu i kanałach niestandardowych) jest dostarczana jako kilka wiadomości w kolejności, dzielonych w miejscach akapitów lub zdań. Odpowiedź zawiera wtedy messageIds dla każdej części oraz autoSplit: true. |
mediaUrl |
Nie | URL pliku multimedialnego (obraz, audio, wideo, dokument) do załączenia. |
mediaContentType |
Nie | Typ MIME załączonego pliku, np. image/jpeg. Jeśli zostanie pominięty, jest określany na podstawie rozszerzenia pliku w adresie URL (.mp3 → audio/mpeg, .pdf → application/pdf); ustaw go dla adresu URL bez rozszerzenia. |
sendAsVoiceNote |
Nie | Tylko WhatsApp Web, tylko audio: dostarcz audio jako notatkę głosową (dymek odtwarzania). Audio, które nie jest w formacie OGG/Opus, jest konwertowane w momencie wysyłania. Domyślnie false. |
pauseBot |
Nie | true wstrzymuje AI dla tego kontaktu w momencie wysłania wiadomości — w celu przejęcia rozmowy przez człowieka. Zobacz Wstrzymywanie lub wznawianie AI. |
clearIncompleteReply |
Nie | true odrzuca niedokończoną odpowiedź bota, aby nie została wznowiona po Twojej wiadomości. |
human_reply |
Nie | true oznacza wiadomość jako napisaną przez osobę z Twojego zespołu, a nie przez integrację. AI traktuje ją wtedy jako odpowiedź członka zespołu w konwersacji, a odpowiedź, którą AI przygotowało dla ostatniej wiadomości kontaktu, zostaje anulowana, aby kontakt nie otrzymał dwóch odpowiedzi. Nie wstrzymuje to AI; użyj do tego pauseBot. Domyślnie false. |
W serwisie LinkedIn wiadomość wysłana w ten sposób lub ze skrzynki odbiorczej jest dostarczana nawet wtedy, gdy dana osoba obsługuje wątek po stronie LinkedIn. Własne odpowiedzi sztucznej inteligencji oraz jej działania następcze są wstrzymywane w takim wątku. Wstrzymana odpowiedź jest usuwana z czatu, zamiast być wyświetlana jako nieudana, ponieważ nic nie zostało wysłane i nie wykorzystano żadnego kredytu. Ostatnia odpowiedź sztucznej inteligencji przed przekazaniem wątku osobie jest nadal dostarczana.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."
}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/send-message",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
body: "Hi! Your appointment is confirmed for tomorrow at 10:00.",
}),
}
);
const data = await res.json();
console.log(data.messageId);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/send-message",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."},
)
print(res.json()["messageId"])
Odpowiedź (200 OK):
{
"success": true,
"messageId": "aB3dE5fG7hI9jK1lM2nO",
"contactId": "contact123",
"channel": "whatsapp",
"message": "Message created successfully. Delivery is being processed."
}
Wyślij według tożsamości kontaktu
POST /contacts/send
Użyj tej metody, gdy nie masz wewnętrznego identyfikatora kontaktu. Podaj treść wiadomości body oraz albo contact_id, albo channel wraz z polem tożsamości pasującym do danego kanału.
| Pole | Wymagane | Opis |
|---|---|---|
body |
Tak | Treść wiadomości do wysłania, do 65 536 znaków. Treść dłuższa niż pozwala na to kanał w jednej wiadomości (1500 w WhatsApp Business API i SMS, 1000 na Instagramie, 2000 na Messengerze, 4096 na Telegramie i LinkedInie, 5000 w LINE, 6000 na TikToku, 7000 w Viberze, 65 536 w WhatsApp Web; brak limitu w e-mailu, widżecie czatu i kanałach niestandardowych) jest dostarczana jako kilka wiadomości w kolejności, podzielonych w miejscach akapitów lub zdań. Odpowiedź zawiera wtedy messageIds dla każdej części oraz autoSplit: true. |
contact_id |
Nie | ID istniejącego kontaktu. Gdy jest ustawione, poniższe pola tożsamości nie są potrzebne. |
channel |
Nie | Kanał, przez który wysłać wiadomość. Wymagane, gdy nie podano contact_id. Jeden z 14 kanałów obsługujących wysyłkę wychodzącą: whatsapp, whatsapp_web, sms, instagram, instagram_private, messenger, telegram, chat-widget, custom, email, line, imessage, linkedin, viber. |
phone_number |
Nie | Numer telefonu kontaktu w formacie międzynarodowym. Używane z whatsapp, whatsapp_web i sms. |
instagram_id |
Nie | ID użytkownika Instagrama kontaktu. Używane z instagram. |
messenger_id |
Nie | ID użytkownika Messengera kontaktu. Używane z messenger. |
telegram_user_id |
Nie | ID użytkownika Telegrama kontaktu. Używane z telegram. |
media_url |
Nie | URL pliku multimedialnego do załączenia. |
media_content_type |
Nie | Typ MIME załączonych mediów, np. image/jpeg. |
Które kanały można rozpoznać na podstawie tożsamości. Tylko sześć z 14 akceptuje pole tożsamości zamiast contact_id: whatsapp, whatsapp_web oraz sms są wyszukiwane przez phone_number, instagram przez instagram_id, messenger przez messenger_id, a telegram przez telegram_user_id. Pozostałe osiem — instagram_private, chat-widget, custom, email, line, imessage, linkedin oraz viber — nie posiada publicznej tożsamości, którą można wyszukać, więc wysyłanie przez te kanały wymaga contact_id; przekazanie samego channel spowoduje zwrócenie 400 z informacją, że wymagane jest contact_id.
cURL (używając formularza zapytania ?apiKey=)
curl -X POST "https://api.youraiconnector.com/v1/contacts/send?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"phone_number": "+31612345678",
"body": "Hi! Your appointment is confirmed."
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/contacts/send", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
channel: "whatsapp",
phone_number: "+31612345678",
body: "Hi! Your appointment is confirmed.",
}),
});
const data = await res.json();
console.log(data.message_id, data.channel);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/send",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"channel": "whatsapp",
"phone_number": "+31612345678",
"body": "Hi! Your appointment is confirmed.",
},
)
data = res.json()
print(data["message_id"], data["channel"])
Odpowiedź (201 Created):
{
"success": true,
"message_id": "aB3dE5fG7hI9jK1lM2nO",
"contact_id": "contact123",
"channel": "whatsapp"
}
Dlaczego wiadomość może zostać odrzucona: Kontakt z włączonym trybem „nie przeszkadzać” lub trybem prywatnym nie może otrzymywać wiadomości wychodzących — żądanie kończy się niepowodzeniem z błędem
422. Jeśli żaden kontakt nie pasuje do podanego ID lub tożsamości, otrzymasz404.
Wysyłanie przez WhatsApp Web: warianty i ochrona przed spamem
W przypadku kontaktu korzystającego z WhatsApp Web mają zastosowanie dwie kwestie dotyczące body.
Nawiasy spintax są rozwijane przy każdej wysyłce. body o treści {Hi|Hello|Hey} there, quick question zostanie wysłany jako jedno z trzech powitań, wybranych dla danej wysyłki — nawiasy nigdy nie dotrą do kontaktu. Użyj tego, aby każdemu kontaktowi wysłać inne powitanie z tego samego kodu integracji. Tekst bez nawiasów jest wysyłany dokładnie w takiej formie, w jakiej został napisany.
Serie identycznych wiadomości powitalnych są odrzucane. Jeśli w ciągu godziny z jednego numeru WhatsApp Web zostanie wysłanych dziesięć niemal identycznych wiadomości powitalnych do kontaktów, które nigdy do Ciebie nie pisały, kolejne wiadomości nie zostaną dostarczone: wysyłka zostanie zaakceptowana jak zwykle (nadal otrzymasz messageId), a wiadomość pozostanie ze statusem status: "failed" oraz error_code: "opener_burst", wraz z czytelnym dla klienta powodem. Ponawianie wysyłki tego samego tekstu nie pomoże — zmień treść, odczekaj godzinę i wyślij ponownie. Odpowiedzi w ramach istniejących konwersacji nigdy nie są objęte tym ograniczeniem. Uzasadnienie znajduje się w sekcji Identyczne wiadomości powitalne prowadzą do ograniczeń numeru.
Wyślij bezpośrednio na numer w WhatsApp Web
POST /whatsapp-web/send
Wyślij wiadomość na numer telefonu w WhatsApp Web bez wcześniejszego wyszukiwania kontaktu. Jeśli numer nie jest jeszcze kontaktem, zostanie on utworzony w ramach tego samego wywołania z wyłączoną sztuczną inteligencją (off), dzięki czemu wiadomość wygląda jak wysłana ręcznie, a żaden asystent nie przejmuje później konwersacji. Istniejący kontakt jest używany w swojej obecnej formie.
| Pole | Wymagane | Opis |
|---|---|---|
phoneNumber |
Tak | Numer, na który ma zostać wysłana wiadomość, w formacie międzynarodowym (+31612345678). |
message |
Nie | Tekst do wysłania. Musi być obecne message lub mediaUrl. |
mediaUrl |
Nie | Publiczny adres URL pliku do wysłania. Musi być obecne message lub mediaUrl. |
mediaContentType |
Nie | Typ MIME pliku, na przykład image/jpeg. Jeśli pominiesz to pole, zostanie określony na podstawie adresu URL. |
sendAsVoiceNote |
Nie | true wysyła plik audio jako notatkę głosową, a nie jako załącznik. |
fromPhoneNumber |
Nie | Z którego z Twoich połączonych numerów WhatsApp Web wysłać wiadomość, w formacie międzynarodowym. Domyślnie jest to numer, do którego kontakt już należy. |
campaignId |
Nie | Pobierz godziny aktywności od tego Agenta zamiast domyślnych ustawień konta. Musi to być Agent na tym samym koncie. |
ignoreActiveHours |
Nie | true wysyła natychmiast, niezależnie od godzin aktywności. |
sub_account_id |
Nie | Dla agencji: wyślij w imieniu jednego ze swoich kont klienckich. |
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-web/send?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+31612345678",
"message": "Hi Alex, your quote is ready."
}'
Pomyślne wywołanie zwraca 202:
{ "success": true, "queued": true, "contactId": "abc123" }
202 oznacza przyjęcie, ale wiadomość nie została jeszcze dostarczona. Poza godzinami aktywności wysyłka jest wstrzymywana i następuje w następnym dozwolonym oknie czasowym, chyba że przekazano ignoreActiveHours. Sprawdź status wiadomości za pomocą Listy wiadomości kontaktu, używając contactId otrzymanego w tym miejscu.
Gdy wysyłka się nie powiedzie:
| Status | Kod | Co się stało |
|---|---|---|
400 |
INVALID_PHONE_FORMAT |
Numer nie jest w formacie międzynarodowym, brakuje phoneNumber lub brakuje zarówno message, jak i mediaUrl. |
400 |
CONTACT_DND |
Kontakt ma włączony tryb „Nie przeszkadzać”, więc żadne wiadomości wychodzące nie są do niego wysyłane. |
400 |
CONTACT_PRIVATE |
Kontakt jest oznaczony jako prywatny. |
404 |
CAMPAIGN_NOT_FOUND |
Żaden Agent nie pasuje do przekazanego campaignId. |
403 |
CAMPAIGN_FORBIDDEN |
Ten Agent należy do innego konta. |
402 |
Konto nie ma już kredytów lub nie połączono żadnego numeru WhatsApp Web. |
Drugie wywołanie dla tego samego kontaktu, gdy wstrzymana wysyłka wciąż oczekuje, zwraca 409, dzięki czemu kolejka nigdy nie gromadzi się dla jednej osoby.
Dodaj notatkę do konwersacji
POST /contacts/notes
Dodaje wiersz do konwersacji z kontaktem bez wysyłania go. Użyj tego do przekazania kontekstu, który powinien znać Twój zespół i sztuczna inteligencja, ale którego kontakt nigdy nie powinien otrzymać: podsumowanie rozmowy telefonicznej, którą właśnie przeprowadził Twój asystent głosowy, uwaga z CRM lub notatka od współpracownika. Działa to na każdym kanale (WhatsApp, SMS, Instagram, Messenger, Telegram, widżet czatu, kanały niestandardowe itd.).
Co dzieje się z notatką:
- Pojawia się na czacie w skrzynce odbiorczej jako żółta karta Notatka, wraz z autorem, jeśli został podany.
- Sztuczna inteligencja odczytuje ją jako część historii konwersacji, oznaczoną jako notatka wewnętrzna, dzięki czemu uwzględnia ją w swojej następnej odpowiedzi.
- Nigdy nie jest wysyłana do kontaktu, nie zużywa kredytów na wiadomości i niczego nie wyzwala: brak odpowiedzi AI, brak automatyzacji, brak webhooka, brak powiadomienia, brak odznaki nieprzeczytanej wiadomości. Nie wstrzymuje pracy AI i nie liczy się jako odpowiedź Twojego zespołu.
Znajdź kontakt w ten sam sposób, co w Wyślij według identyfikatora kontaktu: za pomocą jego ID lub channel wraz z pasującym identyfikatorem. Notatka trafia tylko do kontaktu, który już istnieje; brak dopasowania to 404.
| Pole | Wymagane | Opis |
|---|---|---|
contact_id |
Jedno z dwóch | Identyfikator kontaktu. |
channel + identifier |
Jedno z dwóch | channel plus phone_number (WhatsApp, WhatsApp Web, SMS), instagram_id, messenger_id lub telegram_user_id, jak w Wysyłanie według tożsamości kontaktu. |
body |
Tak | Treść notatki, do 4000 znaków. Znaki nowej linii są zachowywane. |
author |
Nie | Kto lub co ją napisało, do 80 znaków, na przykład Voice agent lub Sarah (sales). Wyświetlane na karcie oraz dla AI. |
timestamp |
Nie | Kiedy to miało miejsce, w milisekundach epoki. Domyślnie teraz. Użyj czasu zakończenia połączenia, aby notatka znalazła się we właściwym miejscu w wątku. Nie może to być więcej niż 5 minut w przyszłości; późniejszy czas zostanie odrzucony z błędem 400. |
external_id |
Nie | Twój własny identyfikator dla tej notatki, do 200 znaków, na przykład identyfikator połączenia. Ponowne wysłanie tego samego external_id dla tego samego kontaktu nie dodaje drugiej notatki; odpowiedź zawiera wtedy duplicate: true. Użyj tego, aby ponowiony webhook nie mógł zarejestrować tego samego połączenia dwukrotnie. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/notes" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"phone_number": "+31612345678",
"author": "Voice agent",
"body": "Voice call, 3:12. Asked about knee surgery waiting times, prefers a call back on Tuesday morning.",
"external_id": "call_8f2k1"
}'
Odpowiedź (201 lub 200 z duplicate: true, gdy external_id została już zarejestrowana)
{
"success": true,
"messageId": "note_4c1f0e...",
"contactId": "contact123"
}
Notatka pojawia się w Wyświetl listę wiadomości kontaktu z type: "note".
Wygeneruj szkic odpowiedzi za pomocą AI
POST /contacts/{contactId}/draft-reply
Prosi agenta AI obsługującego konwersację o napisanie kolejnej odpowiedzi i zwraca tekst. Nic nie jest wysyłane. Jest to ten sam szkic, który tworzy przycisk Wygeneruj odpowiedź w skrzynce odbiorczej: agent korzysta ze swojej konfiguracji, bazy wiedzy oraz dotychczasowej konwersacji i odpowiada w języku kontaktu. Użyj tego, aby wstawić człowieka (lub własną aplikację) pomiędzy AI a kontakt: pobierz szkic, pokaż go do zatwierdzenia, a następnie wyślij za pomocą Wyślij według ID kontaktu, po zmianach lub w oryginalnej formie.
- Szkic jest tworzony przez agenta przypisanego do kontaktu. Kontakt, który nie ma jeszcze przypisanego agenta, otrzyma agenta, który odpowiedziałby na jego następną wiadomość.
- Podczas tworzenia szkicu agent nie uruchamia żadnych narzędzi ani funkcji, więc nie dochodzi do rezerwacji, tagowania, przekazania ani innych działań.
- Nic nie jest zapisywane w konwersacji, a kontakt niczego nie widzi.
- Szkic kosztuje tyle samo kredytów, co jedna odpowiedź AI od tego agenta w tej konwersacji, a w przypadku podłączenia własnego klucza AI – nic.
- Konwersacja musi zawierać co najmniej jedną wiadomość.
Wszystkie pola w treści są opcjonalne; pusta treść (lub brak treści) powoduje przygotowanie szkicu kolejnej odpowiedzi.
| Pole | Wymagane | Opis |
|---|---|---|
instruction |
Nie | Jednorazowa instrukcja dla tego szkicu, do 2000 znaków, taka sama jak przy długim naciśnięciu przycisku Wygeneruj odpowiedź w skrzynce odbiorczej. Na przykład Offer Tuesday at 3pm lub Ask for their email address. |
campaign_id |
Nie | Przygotuj szkic w ramach tej kampanii zamiast agenta kontaktu. |
purpose |
Nie | chat_reply (domyślnie) pisze wiadomość do kontaktu. faq_answer pisze krótką odpowiedź na pytanie kontaktu, która działa samodzielnie, na potrzeby FAQ bazy wiedzy. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/draft-reply" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "instruction": "Offer Tuesday at 3pm for the consultation" }'
Odpowiedź (200)
{
"success": true,
"contact_id": "contact123",
"draft": "Hi Sara, Tuesday at 3pm works for the consultation. Shall I put you down for it?"
}
Błąd 400 oznacza, że konwersacja nie zawiera jeszcze żadnych wiadomości, skończyły się Twoje kredyty lub kontakt nie ma agenta ani kampanii, z której można by przygotować szkic (w error podano szczegóły). Błąd 404 oznacza, że kontakt nie istnieje lub klucz członka zespołu jest ograniczony do kontaktów, których nie może on widzieć. Klucz lub członek zespołu musi mieć uprawnienia do edycji wiadomości.
Używasz klienta AI przez MCP? Ta sama akcja jest dostępna jako narzędzie
generate_reply_draft.
Wyświetl wiadomości kontaktu
GET /contacts/{contactId}/messages
Zwraca wiadomości kontaktu, od najnowszych, z paginacją opartą na kursorze.
| Parametr zapytania | Wymagane | Opis |
|---|---|---|
limit |
Nie | Rozmiar strony. Domyślnie 50, maksymalnie 100. |
cursor |
Nie | Wartość next_cursor z poprzedniej odpowiedzi. Zwraca wiadomości starsze niż kursor. |
filter |
Nie | Filtruj według typu zawartości: all (domyślnie), text, media lub tool_use. |
direction |
Nie | Filtruj według kierunku: all (domyślnie), inbound (otrzymane od kontaktu) lub outbound (wysłane przez Ciebie). |
Uwaga dotycząca filtrowania i paginacji: Filtry
filteridirectionsą stosowane do każdej strony po jej odczytaniu, więc przefiltrowana strona może zawierać mniej elementów niżlimit. Wartośćnext_cursornadal przesuwa się przez pełną konwersację, więc kontynuuj stronicowanie, ażnext_cursorbędzienull.
cURL
curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&direction=inbound" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const params = new URLSearchParams({ limit: "50", direction: "inbound" });
const res = await fetch(
`https://api.youraiconnector.com/v1/contacts/contact123/messages?${params}`,
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.messages, data.next_cursor);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/contacts/contact123/messages",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"limit": 50, "direction": "inbound"},
)
data = res.json()
print(data["messages"], data["next_cursor"])
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"messages": [
{
"id": "aB3dE5fG7hI9jK1lM2nO",
"body": "Hi! Thanks for reaching out.",
"direction": "inbound",
"channel": "whatsapp",
"status": "delivered",
"type": null,
"timestamp": "2026-06-01T10:00:00.000Z",
"media_url": null,
"media_content_type": null,
"bot_reply": false
}
],
"next_cursor": "cD4eF6gH8iJ0kL2mN3oP"
}
Pola wiadomości
| Pole | Opis |
|---|---|
id |
Unikalny identyfikator wiadomości. |
body |
Treść tekstowa wiadomości. W przypadku wiadomości z załącznikiem body zaczyna się od notatki w nawiasie o tym, co dotarło, a następnie następuje podpis, na przykład [THE CONTACT UPLOADED AN IMAGE] Here is my CV lub [THE CONTACT UPLOADED A VOICE NOTE] - [TRANSCRIPTION: ...]. Notatki głosowe i wideo zawierają transkrypcję. |
direction |
inbound (odebrane od kontaktu) lub outbound (wysłane przez Twoje konto). |
channel |
Kanał, przez który wiadomość została wysłana lub odebrana (np. whatsapp, sms, instagram). |
status |
Bieżący status dostarczenia, np. Created, sent, delivered, read, failed. |
type |
Typ wiadomości. Wiadomości tekstowe mają typ null; aktywność narzędzi zautomatyzowanego asystenta jest oznaczona jako tool_use. |
timestamp |
Czas utworzenia wiadomości w formacie ISO 8601. |
media_url |
URL załączonego pliku multimedialnego, jeśli istnieje. Ten link przestaje działać 7 dni po dotarciu wiadomości, na każdym kanale (WhatsApp Business API, WhatsApp Web, Instagram, Messenger, Telegram, widżet czatu i inne). Pobierz nowy za pomocą Pobierz załącznik wiadomości. |
media_content_type |
Typ MIME załączonych mediów, jeśli istnieją. |
bot_reply |
true, gdy wiadomość została wygenerowana przez asystenta AI. |
score |
Twoja ocena wiadomości: 1 kciuk w górę, -1 kciuk w dół, 0 gdy nie została oceniona. Zobacz Oceń lub oznacz wiadomość gwiazdką. |
is_important |
true, gdy wiadomość została oznaczona gwiazdką. |
is_deleted |
true, gdy wiadomość została usunięta. Usunięte wiadomości pozostają na liście, ale ich body i media_url są puste. |
reactions |
Reakcje emoji na wiadomość, z obu stron. Zawsze tablica — pusta, gdy nie ma żadnych reakcji. Każdy wpis ma emoji, from_phone_number, from_me (true, gdy reakcja jest Twoja) oraz reacted_at. |
faq_ids_used |
Identyfikatory FAQ z bazy wiedzy, które AI miała przed sobą, pisząc tę odpowiedź: te wybrane dla ostatniej wiadomości oraz te zachowane z wcześniejszej części konwersacji. Ta sama lista znajduje się przy każdej części odpowiedzi wysłanej w kilku fragmentach. Zawsze tablica, pusta dla wiadomości przychodzących, wiadomości wysłanych przez ludzi, automatycznych przypomnień i odpowiedzi AI wysłanych przed 25 września 2026 r. |
faqs_used |
Te same FAQ wraz z pytaniem: każdy wpis ma id oraz question. question to null, gdy FAQ zostało w międzyczasie usunięte. |
Pobierz załącznik wiadomości
POST /chat-exports/media/download-url
Generuje nowy link do pobrania pliku załączonego do wiadomości: obrazu, notatki głosowej, wideo lub dokumentu. Link jest ważny przez 1 godzinę. Użyj go, gdy chcesz zapisać załączniki w innym miejscu (na przykład archiwizując CV lub notatki głosowe wysłane przez kontakt) lub gdy media_url w wiadomości albo webhook Nowej Wiadomości przestaje działać.
Aby znaleźć wiadomości z załącznikami, wyświetl listę wiadomości kontaktu za pomocą filter=media. id każdej wiadomości oraz identyfikator kontaktu tworzą messagePath.
| Pole treści | Wymagane | Opis |
|---|---|---|
messagePath |
Tak | Która wiadomość, w formacie contacts/{contactId}/messages/{messageId}. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/chat-exports/media/download-url" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/chat-exports/media/download-url", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ messagePath: "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO" }),
});
const { data } = await res.json();
console.log(data.url); // download the file within the hour
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/chat-exports/media/download-url",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"},
)
file_url = res.json()["data"]["url"]
Odpowiedź (200 OK):
{
"success": true,
"data": {
"url": "https://storage.googleapis.com/...",
"expiresInMs": 3600000
}
}
| Pole | Opis |
|---|---|
data.url |
Link do pobrania. Pobierz plik bezpośrednio z niego, klucz API nie jest potrzebny. |
data.expiresInMs |
Jak długo link działa, w milisekundach (3600000 = 1 godzina). Wywołaj punkt końcowy ponownie, aby uzyskać nowy link. |
| Status | Kiedy |
|---|---|
400 |
messagePath brakuje lub nie jest w formacie contacts/{contactId}/messages/{messageId}, albo wiadomość nie zawiera załącznika, który można pobrać w ten sposób. Niektóre starsze załączniki są przechowywane u dostawcy kanału i nie można ich ponownie wygenerować, a udostępniony post lub rolka na Instagramie to link do Instagrama, a nie plik. |
403 |
Kontakt nie należy do Twojego konta. |
404 |
Wiadomość o tym identyfikatorze nie istnieje dla tego kontaktu. |
Używasz klienta AI przez MCP? Ta sama akcja jest dostępna jako narzędzie
get_chat_media_download_url.
Lista sesji czatu
Sesja czatu to jedno okno rozmowy z kontaktem. Otwiera się przy pierwszej przychodzącej wiadomości, gdy żadna sesja nie jest aktywna, i zamyka się automatycznie 48 godzin po ostatniej wiadomości przychodzącej od kontaktu (każda nowa wiadomość przychodząca przesuwa czas zamknięcia o kolejne 48 godzin). Zakończenie czatu przez AI nie zamyka sesji; wywołuje jedynie webhook Chat Concluded. Sesje pozwalają na dzielenie długiej historii na czytelne rozmowy zamiast jednej niekończącej się listy.
Ostatnie sesje wszystkich kontaktów
GET /chat-sessions/recent
Zwraca sesje, które rozpoczęły się w ciągu ostatnich X godzin, od najnowszych, dla wszystkich kontaktów na koncie.
| Parametr zapytania | Wymagany | Opis |
|---|---|---|
hours |
Tak | Ile godzin wstecz sprawdzić. Musi być liczbą całkowitą dodatnią. |
status |
Nie | Zwróć tylko sesje o tym statusie: ChatSessionOpened lub ChatSessionClosed. |
limit |
Nie | Maksymalna liczba sesji do zwrócenia. Domyślnie 100, maksymalnie 100. |
includeMessages |
Nie | true dodaje tablicę messages do każdej sesji. Domyślnie wyłączone, ponieważ znacznie zwiększa rozmiar odpowiedzi. |
cURL
curl "https://api.youraiconnector.com/v1/chat-sessions/recent?hours=24&status=ChatSessionClosed" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const params = new URLSearchParams({ hours: "24", status: "ChatSessionClosed" });
const res = await fetch(`https://api.youraiconnector.com/v1/chat-sessions/recent?${params}`, {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data.total_sessions, data.data.sessions);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/chat-sessions/recent",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"hours": 24, "status": "ChatSessionClosed"},
)
data = res.json()["data"]
print(data["total_sessions"], data["sessions"])
Odpowiedź (200 OK):
{
"success": true,
"data": {
"hours_ago": 24,
"total_sessions": 2,
"sessions": [
{
"session_id": "session456",
"contact_id": "contact123",
"contact_name": "Jane Doe",
"contact_phone": "+31612345678",
"contact_email": "jane@example.com",
"start_date_time": "2026-06-01T09:55:00.000Z",
"end_date_time": "2026-06-01T10:20:00.000Z",
"status": "ChatSessionClosed",
"tag": "Booking enquiry"
}
]
}
}
Wszystkie sesje dla jednego kontaktu
GET /chat-sessions/{contactId}
Zwraca każdą sesję czatu dla pojedynczego kontaktu. Te same parametry status, limit i includeMessages co powyżej — hours nie ma tutaj zastosowania.
cURL
curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
-H "X-API-Key: YOUR_API_KEY"
Odpowiedź (200 OK):
{
"success": true,
"data": {
"contact_id": "contact123",
"contact_name": "Jane Doe",
"total_sessions": 2,
"sessions": [
{
"id": "session456",
"start_date_time": "2026-06-01T09:55:00.000Z",
"end_date_time": "2026-06-01T10:20:00.000Z",
"status": "ChatSessionClosed",
"tag": "Booking enquiry"
}
]
}
}
Nazwy pól identyfikatora sesji różnią się między tymi dwoma punktami końcowymi. Lista ostatnich sesji nazywa go
session_id(zawiera również szczegóły kontaktu, ponieważ sesje pochodzą od wielu kontaktów); lista dla kontaktu nazywa goid. Obie wartości są tym, co przekazujesz jako{sessionId}podczas pobierania pełnego wątku poniżej.
Gdy includeMessages=true, każda sesja zyskuje tablicę messages, której wpisy zawierają id, body, direction, timestamp, type, channel oraz status.
Pobierz wątek sesji czatu
GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Sesja czatu grupuje wiadomości kontaktu w jednym oknie konwersacji. Ten punkt końcowy zwraca pełny wątek pojedynczej sesji, od najstarszej wiadomości, wraz z metadanymi sesji. Identyfikatory sesji dla danego kontaktu można znaleźć za pomocą punktów końcowych sesji czatu.
cURL
curl "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.session, data.messages);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["session"], data["messages"])
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"session": {
"id": "session456",
"status": "ChatSessionClosed",
"start_date_time": "2026-06-01T09:55:00.000Z",
"end_date_time": "2026-06-01T10:20:00.000Z",
"tag": "Booking enquiry"
},
"messages": [
{
"id": "aB3dE5fG7hI9jK1lM2nO",
"body": "Hi! Thanks for reaching out.",
"direction": "inbound",
"channel": "whatsapp",
"status": "delivered",
"type": null,
"timestamp": "2026-06-01T09:55:00.000Z",
"media_url": null,
"media_content_type": null,
"bot_reply": false
}
]
}
Obiekt session zawiera status (ChatSessionOpened gdy jest aktywna, ChatSessionClosed po zakończeniu), start_date_time, end_date_time oraz czytelny dla człowieka tag. Tablica messages wykorzystuje te same pola wiadomości, co punkt końcowy listy.
Edytowanie, usuwanie i reagowanie na wiadomości
Te punkty końcowe zmieniają wiadomość po jej wysłaniu. Dwa z nich komunikują się zarówno z kanałem kontaktu, jak i Twoją kopią, więc przeczytaj wstęp do sekcji przed ich użyciem — to, co jest możliwe, zależy całkowicie od kanału, na którym odbywa się konwersacja.
Co umożliwia każdy kanał
| Akcja | Kanały, w których można zmienić kopię kontaktu | Limit czasu |
|---|---|---|
| Edytuj wysłaną wiadomość | Widżet czatu, WhatsApp Web (tylko wiadomości tekstowe), Telegram, LinkedIn | Brak w widżecie czatu, 15 minut w WhatsApp Web, 48 godzin w Telegramie, 60 minut na LinkedIn |
| Usuń dla wszystkich | Widżet czatu, WhatsApp Web, Telegram, LinkedIn | 60 minut na LinkedIn; pozostałe nie mają opublikowanego limitu |
| Zareaguj emoji | WhatsApp Web, Telegram | Brak |
W przypadku wszystkich innych kanałów — WhatsApp Business API, SMS, Instagram, Messenger, e-mail, LINE, kanały niestandardowe — usunięcie nadal usuwa wiadomość z Twojej skrzynki odbiorczej, ale kontakt zachowuje swoją kopię, a edycja lub reagowanie nie są w ogóle możliwe.
Edytuj wiadomość
POST /contacts/{contactId}/messages/{messageId}/edit
Nadpisuje wiadomość, którą już wysłałeś, zarówno na urządzeniu kontaktu, jak i w Twojej kopii.
| Pole | Wymagane | Opis |
|---|---|---|
body |
Tak | Nowa treść wiadomości. Nie może być pusta i nie może być dłuższa niż pozwala na to kanał w jednej wiadomości (te same limity dla kanałów co w Wysyłanie według ID kontaktu; 4096, gdy wiadomość nie ma kanału). |
W przeciwieństwie do usuwania, ta operacja kończy się wyraźnym błędem, gdy kanał odmawia wykonania akcji: otrzymasz 409, a Twoja kopia pozostanie dokładnie w takiej formie, w jakiej ma ją kontakt, ponieważ wyświetlenie edycji, której nigdy nie otrzymał, spowodowałoby rozbieżność między stronami. Pole edit_reason informuje o przyczynie — okno edycji kanału zostało zamknięte, kanał jest rozłączony, wiadomość zawiera załącznik, którego kanał nie może edytować (media_not_editable: w WhatsApp Web można edytować tylko wiadomości tekstowe, a nie tekst pod zdjęciem, filmem lub plikiem) lub wystąpił inny problem.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "Sorry - I meant Thursday at 3pm." }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ body: "Sorry - I meant Thursday at 3pm." }),
}
);
const data = await res.json();
console.log(data.edited, data.edit_reason);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"body": "Sorry - I meant Thursday at 3pm."},
)
data = res.json()
print(data.get("edited"), data.get("edit_reason"))
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"edited": true,
"edit_reason": "edit_dispatched"
}
Jeśli kanał nie zaakceptuje edycji, otrzymasz zamiast tego 409 i nic nie zostanie zmienione:
{
"success": false,
"error": "The message could not be edited",
"edit_reason": "channel_disconnected"
}
Wiadomość, która została już usunięta, kanał, który w ogóle nie obsługuje edycji, oraz wiadomość, która jest zbyt stara dla danego kanału, zwracają 400 — żądanie nigdy nie dociera do kanału.
Usuń jedną wiadomość
DELETE /contacts/{contactId}/messages/{messageId}
Usuwa wiadomość z Twojej konwersacji i, tam gdzie kanał na to pozwala, wycofuje również kopię kontaktu. Brak treści żądania.
To zawsze zwraca 200, gdy wiadomość istniała, nawet jeśli kopia kontaktu nie mogła zostać wycofana — Twoja kopia została usunięta, więc błąd byłby mylący. Przeczytaj trzy pola w odpowiedzi, aby poinformować użytkownika, co faktycznie się stało:
| Pole | Opis |
|---|---|
revoke_supported |
Czy ten kanał w ogóle może wycofywać wiadomości. |
revoked |
Czy kopia na urządzeniu kontaktu została usunięta. |
revoke_reason |
Dlaczego nie została usunięta, gdy revoked ma wartość false — na przykład revoke_window_closed lub already_deleted. |
cURL
curl -X DELETE "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
{ method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.revoked, data.revoke_reason);
Python
import requests
res = requests.delete(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["revoked"], data["revoke_reason"])
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"revoke_supported": true,
"revoked": true,
"revoke_reason": "revoke_dispatched"
}
Usunięte wiadomości nie są usuwane z historii konwersacji. Pozostają w
GET /contacts/{contactId}/messageszis_deleted: trueoraz pustymbodyimedia_url.
Usuwanie kilku wiadomości jednocześnie
POST /contacts/{contactId}/messages/bulk-delete
Czyści partię wiadomości tylko po Twojej stronie. Treści i załączniki są usuwane, ale nic nie jest wycofywane na urządzeniu kontaktu — aby również wycofać wiadomość, usuń ją pojedynczo za pomocą powyższego punktu końcowego dla pojedynczej wiadomości.
| Pole | Wymagane | Opis |
|---|---|---|
message_ids |
Tak | Niepusta tablica identyfikatorów wiadomości, do 500 na żądanie. messageIds jest akceptowane jako alias. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "message_ids": ["msg_1", "msg_2"] }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ message_ids: ["msg_1", "msg_2"] }),
}
);
console.log((await res.json()).deleted);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"message_ids": ["msg_1", "msg_2"]},
)
print(res.json()["deleted"])
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"deleted": 2
}
Reagowanie na wiadomość
POST /contacts/{contactId}/messages/{messageId}/react
Dodaje Twoją własną reakcję emoji do wiadomości lub cofa ją poprzez wysłanie pustego ciągu znaków. Reakcje kontaktu nigdy nie są zmieniane.
| Pole | Wymagane | Opis |
|---|---|---|
emoji |
Tak | Emoji, którym chcesz zareagować, lub "", aby usunąć swoją reakcję. Musi to być pojedynczy ciąg znaków bez spacji, maksymalnie 16 znaków. |
Podobnie jak w przypadku edycji, operacja ta kończy się niepowodzeniem zamiast wyświetlania reakcji, której kontakt nigdy nie otrzymał, a informacja o błędzie wskazuje, czy warto ponowić próbę:
422— wiadomość nigdy nie może zostać dostarczona w tej konwersacji: kanał nie obsługuje reakcji, wiadomość nie ma identyfikatora po stronie kanału lub emoji znajduje się poza zestawem dozwolonym przez dany kanał.409— kanał był chwilowo nieosiągalny. Ponowna próba może zadziałać.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "emoji": "👍" }'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ emoji: "👍" }),
}
);
const data = await res.json();
console.log(data.reactions);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"emoji": "👍"},
)
print(res.json()["reactions"])
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"reaction_supported": true,
"reaction_reason": "reaction_dispatched",
"reactions": [
{
"emoji": "👍",
"from_phone_number": "+31612345678",
"from_me": true,
"reacted_at": "2026-06-01T10:05:00.000Z"
}
]
}
Tablica reactions to pełny zestaw reakcji znajdujących się obecnie na wiadomości, zarówno Twoich, jak i kontaktu. W przypadku 409 lub 422 jest ona zwracana bez zmian, więc klient renderujący bezpośrednio na jej podstawie nigdy nie wyświetli reakcji, która nie została dostarczona.
Ocenianie lub oznaczanie wiadomości gwiazdką
PATCH /contacts/{contactId}/messages/{messageId}
Ocenia wiadomość kciukiem w górę lub w dół i/lub oznacza ją gwiazdką jako ważną. Jest to tylko ewidencja po Twojej stronie — nic nie jest wysyłane do kontaktu.
| Pole | Wymagane | Opis |
|---|---|---|
score |
Nie | 1 łapka w górę, -1 łapka w dół, 0 usuwa ocenę. |
is_important |
Nie | true oznacza wiadomość gwiazdką, false usuwa gwiazdkę. Musi być wartością logiczną, a nie ciągiem znaków "true". |
Wyślij przynajmniej jedno z tych dwóch, w przeciwnym razie otrzymasz 400. Zapisywane jest tylko to, co wyślesz, więc oznaczenie wiadomości gwiazdką nigdy nie usuwa jej oceny i odwrotnie — a odpowiedź odzwierciedla tylko te pola, które zostały wysłane.
cURL
curl -X PATCH "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "score": 1, "is_important": true }'
JavaScript
await fetch("https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1", {
method: "PATCH",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ score: 1, is_important: true }),
});
Python
import requests
requests.patch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"score": 1, "is_important": True},
)
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"score": 1,
"is_important": true
}
Oznaczanie wiadomości jako przeczytane
Możesz wyczyścić stan nieprzeczytanych wiadomości dla konkretnych wiadomości lub dla całej konwersacji.
Oznaczanie konkretnych wiadomości jako przeczytane
POST /contacts/{contactId}/messages/mark-read
Przekaż identyfikatory wiadomości, które mają zostać oznaczone jako przeczytane.
| Pole | Wymagane | Opis |
|---|---|---|
message_ids |
Tak | Niepusta tablica identyfikatorów wiadomości (do 500 na żądanie). |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]
}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
message_ids: ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"],
}),
}
);
const data = await res.json();
console.log(data.marked_read);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]},
)
print(res.json()["marked_read"])
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123",
"marked_read": 2
}
Oznaczanie całego czatu jako przeczytanego
POST /contacts/{contactId}/mark-read
Czyści wskaźnik nieprzeczytanych wiadomości dla całej konwersacji kontaktu w skrzynce odbiorczej. Treść żądania nie jest wymagana.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-read" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
{ method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123"
}
Oznacz cały czat jako nieprzeczytany
POST /contacts/{contactId}/mark-unread
Przywraca plakietkę nieprzeczytanej wiadomości w konwersacji — przydatne, gdy ktoś z Twojego zespołu otworzył czat, ale przekazuje go z powrotem. Treść żądania nie jest wymagana.
Jest to flaga dotycząca tylko skrzynki odbiorczej: nie zmienia ona czasu ostatniego odczytania konwersacji, więc potwierdzenie odczytania nie jest wysyłane do kontaktu w kanałach, które je obsługują.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
-H "X-API-Key: YOUR_API_KEY"
Odpowiedź (200 OK):
{
"success": true,
"contact_id": "contact123"
}
Eksportuj konwersację
Eksporty zapewniają całą konwersację w formie czytelnego zapisu, zamiast przeglądania wiadomości strona po stronie. Każdy punkt końcowy eksportu akceptuje filter o wartości all (domyślnie), text, media lub tool_use, dopasowując się do filtra na liście wiadomości.
Eksportuj czat jednego kontaktu
GET /chat-exports/{contactId}
| Parametr zapytania | Wymagane | Opis |
|---|---|---|
format |
Nie | txt (domyślnie) zwraca link do pobrania zapisu w formacie zwykłego tekstu. json zwraca wiadomości jako ustrukturyzowane dane w odpowiedzi. |
filter |
Nie | all (domyślnie), text, media lub tool_use. |
cURL
curl "https://api.youraiconnector.com/v1/chat-exports/contact123?format=json" \
-H "X-API-Key: YOUR_API_KEY"
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/chat-exports/contact123",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"format": "json"},
)
print(res.json()["data"]["messages"])
Odpowiedź z format=json (200 OK):
{
"success": true,
"data": {
"contact": {
"id": "contact123",
"name": "Jane Doe",
"phone": "+31612345678",
"email": "jane@example.com"
},
"messages": [
{
"body": "Hi! I have a question about my order.",
"direction": "inbound",
"timestamp": "2026-06-01T09:55:00.000Z",
"type": "text",
"media_url": null,
"media_content_type": null,
"name": null,
"args": null
}
]
}
}
Przy format=txt (wartość domyślna), data jest zamiast tego linkiem do pobrania wygenerowanego pliku zapisu:
{
"success": true,
"data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}
Link do pobrania jest krótkotrwały. Pobierz plik zaraz po otrzymaniu linku, zamiast go przechowywać — poproś o nowy eksport, gdy ponownie będziesz potrzebować zapisu.
Eksportuj wszystkie ostatnie konwersacje
GET /chat-exports/recent
Eksportuje konwersacje wszystkich kontaktów, które były aktywne w ciągu ostatnich X godzin, za pomocą jednego wywołania.
| Parametr zapytania | Wymagany | Opis |
|---|---|---|
hours |
Tak | Liczba godzin aktywności, które mają zostać uwzględnione. Musi być dodatnią liczbą całkowitą. |
format |
Nie | json (domyślnie) zwraca jeden wpis na kontakt. txt zwraca pojedynczy plik tekstowy do pobrania zawierający wszystkie konwersacje. |
limit |
Nie | Maksymalna liczba kontaktów do wyeksportowania. Domyślnie 50, maksymalnie 100. |
filter |
Nie | all (domyślnie), text, media lub tool_use. |
cURL
curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
-H "X-API-Key: YOUR_API_KEY"
Odpowiedź (200 OK):
{
"success": true,
"data": {
"hours_ago": 24,
"total_contacts": 2,
"exports": [
{
"contactId": "contact123",
"contactName": "Jane Doe",
"phoneNumber": "+31612345678",
"email": "jane@example.com",
"messageCount": 12,
"chatExport": "Acme Export - Jane Doe\nPhone: +31612345678\n..."
}
]
}
}
W przypadku format=txt odpowiedzią jest sam plik tekstowy, wysyłany jako plik do pobrania zamiast JSON.
To wywołanie pobiera pełną historię każdego pasującego kontaktu, więc należy zachować umiar w wartościach
hoursilimitw przypadku bardzo aktywnych kont.
Wyślij transkrypcję do kontaktu e-mailem
POST /chat-exports/{contactId}/email
Wysyła kontaktowi jego własną transkrypcję konwersacji drogą mailową — jest to przepływ „wyślij mi ten czat na e-mail”, obsługiwany z poziomu Twojego własnego systemu.
| Pole | Wymagane | Opis |
|---|---|---|
recipient_email |
Nie | Adres, na który wysłać wiadomość. Domyślnie jest to adres e-mail zapisany w danych kontaktu. |
via |
Nie | auto (domyślnie) wybiera najlepszą ścieżkę, transactional wysyła wiadomość jako e-mail systemowy, email_channel wysyła wiadomość z Twojego połączonego kanału e-mail. |
note |
Nie | Krótka wiadomość od Ciebie wyświetlana nad transkrypcją. Maksymalnie 1000 znaków. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/chat-exports/contact123/email" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "note": "Here is a copy of our chat, as promised." }'
Odpowiedź (200 OK):
{
"success": true,
"data": {
"via": "transactional",
"recipientEmail": "jane@example.com",
"messageCount": 42,
"omittedCount": 0
}
}
omittedCount informuje, ile najstarszych wiadomości zostało pominiętych, aby zachować odpowiednią długość wiadomości e-mail. Wartość 200 oznacza, że transkrypcja została utworzona i dodana do kolejki wysyłania, a nie że dotarła już do skrzynki odbiorczej.
Wstrzymywanie lub wznawianie działania AI dla jednego kontaktu
PUT /contacts/{contactId}
Ustaw is_bot_active na false, aby zatrzymać odpowiadanie AI jednemu kontaktowi, i z powrotem na true, aby przekazać mu konwersację. Jest to przełącznik przejęcia, którego potrzebujesz, gdy człowiek włącza się do rozmowy: wiadomości wychodzące wysyłane przez API są nadal dostarczane, gdy bot jest wstrzymany.
cURL
curl -X PUT "https://api.youraiconnector.com/v1/contacts/contact123" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_bot_active": false }'
JavaScript
await fetch("https://api.youraiconnector.com/v1/contacts/contact123", {
method: "PUT",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ is_bot_active: false }),
});
Python
import requests
requests.put(
"https://api.youraiconnector.com/v1/contacts/contact123",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"is_bot_active": False},
)
Odpowiedź
{
"success": true,
"contact_id": "contact123"
}
Wstrzymywanie jako część odpowiedzi
Jeśli człowiek przejmuje rozmowę, wysyłając odpowiedź, możesz wstrzymać bota w tym samym żądaniu, zamiast wykonywać drugie wywołanie. POST /contacts/{contactId}/send-message akceptuje następujące opcjonalne flagi:
| Pole | Opis |
|---|---|
pauseBot |
true wstrzymuje AI dla tego kontaktu w momencie wysłania wiadomości. |
clearIncompleteReply |
true odrzuca niedokończoną odpowiedź bota, aby nie została wznowiona później. |
human_reply |
true oznacza wiadomość jako odpowiedź członka zespołu i anuluje odpowiedź, którą AI przygotowało w kolejce. Do wstrzymania nadal wymagane jest pauseBot. |
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Hi, Sarah here - taking over from the assistant.",
"pauseBot": true,
"clearIncompleteReply": true,
"human_reply": true
}'
Odpowiedź zawiera "botPaused": true, gdy wstrzymanie zostało zastosowane.
Oznaczenie kontaktu jako prywatnego za pomocą
POST /contacts/bulk-flagrównież wstrzymuje dla niego bota. Zobacz Kontakty, aby uzyskać pełną listę pól.
Budowanie własnej skrzynki odbiorczej
Wszystko, czego potrzebuje skrzynka odbiorcza, znajduje się na tej stronie oraz w Kontaktach:
| Co chcesz zrobić | Punkt końcowy |
|---|---|
| Wyświetl listę konwersacji | GET /contacts |
| Odczytaj konwersację | GET /contacts/{contactId}/messages |
| Wyświetl listę sesji czatu kontaktu | GET /chat-sessions/{contactId} |
| Zobacz, co wpłynęło ostatnio | GET /chat-sessions/recent |
| Odczytaj jedną sesję czatu | GET /contacts/{contactId}/chat-sessions/{sessionId}/messages |
| Wyślij ręczną odpowiedź | POST /contacts/{contactId}/send-message |
| Popraw wysłaną przed chwilą odpowiedź | POST /contacts/{contactId}/messages/{messageId}/edit |
| Usuń wiadomość | DELETE /contacts/{contactId}/messages/{messageId} |
| Wyczyść kilka wiadomości | POST /contacts/{contactId}/messages/bulk-delete |
| Zareaguj za pomocą emoji | POST /contacts/{contactId}/messages/{messageId}/react |
| Oceń lub oznacz wiadomość gwiazdką | PATCH /contacts/{contactId}/messages/{messageId} |
| Oznacz jako przeczytane | POST /contacts/{contactId}/mark-read |
| Przekaż czat z powrotem do zespołu | POST /contacts/{contactId}/mark-unread |
| Eksportuj transkrypcję | GET /chat-exports/{contactId} |
| Wstrzymaj lub wznów działanie AI | PUT /contacts/{contactId} za pomocą is_bot_active |
Aby otrzymywać aktualizacje na żywo, zasubskrybuj zdarzenia New Message, Replies, Human Alerted oraz Chat Concluded za pomocą Webhooks, zamiast odpytywać to API w pętli czasowej.
Błędy API wiadomości
Punkty końcowe wiadomości zwracają standardową kopertę błędu:
{
"success": false,
"error": "Contact not found"
}
| Status | Kiedy występuje w punkcie końcowym wiadomości |
|---|---|
400 |
Brakuje wymaganego pola lub parametr jest nieprawidłowy (błędne limit, hours, filter, direction, status, pusta lub przekraczająca 500 elementów tablica message_ids, nieprawidłowe cursor, pusta lub zbyt długa edycja body, score poza -1/0/1 lub emoji ze spacjami albo dłuższe niż 16 znaków). Zwracane również, gdy wiadomości nie można w ogóle edytować — została usunięta, jej kanał nie obsługuje edycji lub minął czas na edycję w tym kanale. |
404 |
Nie znaleziono kontaktu, sesji czatu lub jednego z podanych identyfikatorów wiadomości. |
409 |
Kanał nie może obecnie przyjąć zmiany. Nic nie zostało zapisane: w przypadku edycji edit_reason wyjaśnia dlaczego; w przypadku reakcji kanał był chwilowo nieosiągalny i ponowienie próby może zadziałać. |
422 |
Kontakt nie może otrzymywać wiadomości wychodzących (tryb nie przeszkadzać, prywatny lub nieobsługiwany kanał) albo reakcja nigdy nie może zostać dostarczona w tej konwersacji (reaction_reason wskazuje przyczynę). |
Wspólne kody, które może zwrócić każdy punkt końcowy — 401, 403 (Twój plan nie obejmuje dostępu do API), 429 (limit szybkości) oraz 500 — zostały wymienione wraz ze wskazówkami dotyczącymi ponawiania prób w sekcji Błędy i stronicowanie.