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.
Wyślij według identyfikatora kontaktu
POST /contacts/{contactId}/send-message
| Pole | Wymagane | Opis |
|---|---|---|
body |
Tak | Treść wiadomości do wysłania. |
mediaUrl |
Nie | URL pliku multimedialnego (obraz, dokument itp.) do załączenia. |
mediaContentType |
Nie | Typ MIME załączonych mediów, np. image/jpeg. |
pauseBot |
Nie | true wstrzymuje AI dla tego kontaktu w momencie wysył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 wznowił jej po Twojej wiadomości. |
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. |
contact_id |
Nie | Identyfikator istniejącego kontaktu. Gdy jest ustawiony, poniższe pola tożsamości nie są potrzebne. |
channel |
Nie | Kanał, przez który ma zostać wysłana wiadomość. Wymagane, gdy nie podano contact_id. Jeden z 14 kanałów umożliwiających wysyłkę: 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żywany z whatsapp, whatsapp_web oraz sms. |
instagram_id |
Nie | Identyfikator użytkownika Instagram kontaktu. Używany z instagram. |
messenger_id |
Nie | Identyfikator użytkownika Messenger kontaktu. Używany z messenger. |
telegram_user_id |
Nie | Identyfikator użytkownika Telegram kontaktu. Używany z telegram. |
media_url |
Nie | Adres URL pliku multimedialnego do załączenia. |
media_content_type |
Nie | Typ MIME załączonego pliku multimedialnego, 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.
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. |
direction |
inbound (otrzymana od kontaktu) lub outbound (wysłana z Twojego konta). |
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ść automatycznych narzędzi asystenta jest oznaczona jako tool_use. |
timestamp |
Czas utworzenia wiadomości w formacie ISO 8601. |
media_url |
Adres URL załączonego pliku multimedialnego, jeśli istnieje. |
media_content_type |
Typ MIME załączonych multimediów, jeśli istnieją. |
bot_reply |
true, gdy wiadomość została wygenerowana przez asystenta AI. |
score |
Twoja ocena wiadomości: 1 łapka w górę, -1 łapka w dół, 0, gdy wiadomość nie została oceniona. Zobacz Oceń lub oznacz gwiazdką wiadomość. |
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 brak reakcji. Każdy wpis zawiera emoji, from_phone_number, from_me (true, gdy reakcja jest Twoja) oraz reacted_at. |
Lista sesji czatu
Sesja czatu to jedno okno konwersacji z kontaktem: otwiera się, gdy kontakt zaczyna pisać, i zamyka, gdy konwersacja zostaje zakończona. Sesje pozwalają na podział długiej historii na czytelne konwersacje 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, które mogą zmienić kopię kontaktu | Limit czasu |
|---|---|---|
| Edycja wysłanej wiadomości | Widżet czatu, WhatsApp Web, 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 |
| Reagowanie 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 | Nowy tekst wiadomości. Nie może być pusty i może mieć maksymalnie 4096 znaków. |
W przeciwieństwie do usuwania, ta operacja kończy się wyraźnym błędem, gdy kanał odmawia: otrzymujesz 409, a Twoja kopia pozostaje dokładnie taka sama, jak u kontaktu, ponieważ pokazanie edycji, której nigdy nie otrzymali, 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 lub wystąpił inny błąd.
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 dwie 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. |
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
}'
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.