Dokumentacja API Chatbota
Ta dokumentacja zawiera kompletną specyfikację API do integracji z naszym systemem chatbota. API umożliwia tworzenie niestandardowych integracji, zarządzanie sesjami czatu i przetwarzanie wiadomości. Każdy endpoint jest szczegółowo opisany, wraz z przykładami żądań i odpowiedzi, co pozwala na szybkie wdrożenie.
Spis treści
Przegląd procesu integracji
Integracja z API chatbota to proces składający się z kilku kluczowych etapów, które pozwolą na płynne połączenie Twojej aplikacji z naszym systemem.
- Konfiguracja i uwierzytelnienie - przygotowanie chatbota w panelu ChatbotAssistant i uzyskanie klucza API.
- Zrozumienie przepływu pracy - zapoznanie się z asynchronicznym modelem komunikacji opartym na webhookach.
- Implementacja endpointów - wykorzystanie API do tworzenia sesji i wysyłania wiadomości.
- Obsługa odpowiedzi - stworzenie endpointu webhook do odbierania i weryfikowania odpowiedzi od chatbota.
- Zastosowanie dobrych praktyk - wdrożenie zaleceń dotyczących bezpieczeństwa, wydajności i obsługi błędów.
Uwierzytelnianie
Wszystkie zapytania API wymagają uwierzytelnienia za pomocą klucza API. Klucz można znaleźć i wygenerować w ustawieniach API.
Nagłówek uwierzytelniający
Klucz API należy przekazać w nagłówku HTTP X-API-Key:
X-API-Key: twój-klucz-api
Zarządzanie kluczami API
Możesz zarządzać swoimi kluczami API w panelu administracyjnym:
- Generowanie nowych kluczy API
- Cofanie dostępu dla skompromitowanych kluczy
Konfiguracja chatbota
W tej sekcji dowiesz się jak utworzyć i skonfigurować nowego chatbota na platformie ChatbotAssistant opartego o nasze API.
Kroki konfiguracji:
- Na menu bocznym znajdź i kliknij sekcję Stwórz Chatbota lub przejdź do sekcji Dashboard, a następnie wybierz Utwórz nowego chatbota
- W panelu tworzenia chatbota, w sekcji Wybierz funkcjonalności chatbota zaznacz opcję API Integration
- Możesz również zaznaczyć funkcję Widget na stronę podczas konfiguracji API Integration
- Wypełnij formularz tworzenia chatbota, wprowadzając następujące dane:
- Nazwa chatbota - wprowadź nazwę chatbota, którą będą widzieli użytkownicy np. Obsługa Klienta
- Opis (opcjonalne) - pomoże Ci odnaleźć właściwego chatbota
- Informacje o firmie - wprowadź szczegółowe informacje o Twojej firmie, produktach, usługach, cenach, godzinach otwarcia itp. Im więcej informacji podasz, tym lepiej chatbot będzie odpowiadał na pytania klientów.
- Dozwolone domeny (dla opcji z widgetem na stronę) - podaj domenę twojej strony internetowej np. example.com (bez https://). W przypadku posiadania więcej niż jednej domeny bądź subdomen, wprowadź wszystkie oddzielając je przecinkiem. (NIEZALECANE) Pozostaw puste pole, aby zezwolić na wszystkie domeny.
- Na dole formularza zobaczysz sekcję o nazwie Konfiguracja API, w której musisz podać adres URL Webhooka Twojej strony. Jest to adres, na który będą wysyłane odpowiedzi chatbota w trybie API
- Po wypełnieniu wszystkich niezbędnych do działania chatbota pól, kliknij przycisk Utwórz chatbota
- Teraz możliwe będzie pozyskanie Sekretu Webhooka. Aby odnaleźć sekret, przejdź do sekcji Dashboard i znajdź utworzonego w poprzednich krokach chatbota
- Sekret webhooka znajdziesz w sekcji Opcje, a następnie Ustawienia webhook lub klikając przycisk Edytuj i przechodząc na dół strony
Generowanie nowego sekretu webhooka:
W każdej chwili możesz wygenerować nowy sekret webhooka. Wystarczy, że:
- Przejdziesz do sekcji Dashboard, znajdziesz konkretnego chatbota, klikniesz Opcje, a następnie Ustawienia webhook.
- Pod sekcją Sekret Webhooka zaznacz pole Wygeneruj nowy sekret webhooka i zatwierdź operację przyciskiem Zapisz zmiany.
- Po zapisaniu zmian, nowy sekret webhooka zostanie automatycznie wygenerowany i będzie widoczny w panelu ustawień webhooka.
Konfiguracja webhooka
URL webhooka musi spełniać następujące wymagania:
- Musi używać protokołu HTTPS
- Musi być dostępny z internetu (nie może to być adres prywatny)
- Musi odpowiadać kodem 200 OK na żądania POST
- Powinien obsługiwać nagłówki podpisu dla weryfikacji
Przepływ pracy API
API umożliwia integrację chatbota z Twoją aplikacją lub systemem. Typowy przepływ pracy wygląda następująco:
- Uwierzytelnianie - użycie klucza API w nagłówku żądania
- Utworzenie sesji czatu - zainicjowanie nowej konwersacji z chatbotem
- Wysłanie wiadomości użytkownika - przekazanie treści wiadomości do chatbota
- Otrzymanie odpowiedzi chatbota przez webhook - przetworzenie asynchronicznej odpowiedzi
Wszystkie zapytania i odpowiedzi używają formatu JSON.
Diagram przepływu danych
Endpointy API
API chatbota udostępnia następujące główne endpointy:
| Endpoint | Metoda | Opis |
|---|---|---|
/api/chatbot/{chatbot_id}/session |
POST | Utworzenie nowej sesji czatu |
/api/chatbot/{chatbot_id}/send |
POST | Wysłanie wiadomości użytkownika do chatbota |
Poniżej znajdziesz szczegółowe specyfikacje każdego endpointu, wraz z przykładami żądań i odpowiedzi.
Utworzenie sesji czatu
/api/chatbot/{chatbot_id}/session
Ten endpoint tworzy nową sesję czatu dla określonego chatbota. Sesja jest wymagana do wysyłania wiadomości i musi być przechowywana po stronie klienta.
Parametry ścieżki
| Parametr | Typ | Opis | Wymagany |
|---|---|---|---|
chatbot_id | String | Identyfikator chatbota | Tak |
Nagłówki żądania
| Nagłówek | Wartość | Opis | Wymagany |
|---|---|---|---|
X-API-Key | String | Twój klucz API do uwierzytelnienia | Tak |
Content-Type | application/json | Format danych żądania | Tak |
Parametry żądania (body)
| Parametr | Typ | Opis | Wymagany |
|---|---|---|---|
webhook_data | Object | Dowolne dane JSON, które zostaną przekazane z powrotem w webhooku | Nie |
client_id | String | Identyfikator klienta do śledzenia | Nie |
Przykładowe żądanie
{
"webhook_data": {
"conversation_id": "conv-456",
"department": "sales",
"custom_field": "wartość"
},
"client_id": "user_12345"
}Odpowiedzi
{
"success": true,
"session": {
"token": "abc123def456"
},
"webhook": {
"url": "https://twoj-backend.pl/webhooks/chatbot",
"secret": "secret123"
}
}{
"success": false,
"error": "Invalid request parameters"
}{
"success": false,
"error": "Invalid API key"
}{
"success": false,
"error": "Chatbot not found"
}Wypróbuj to
Wysłanie wiadomości
/api/chatbot/{chatbot_id}/sendTen endpoint wysyła wiadomość od użytkownika do chatbota. Odpowiedź chatbota będzie dostarczona asynchronicznie przez webhook skonfigurowany wcześniej.
Parametry ścieżki
| Parametr | Typ | Opis | Wymagany |
|---|---|---|---|
chatbot_id | String | Identyfikator chatbota | Tak |
Nagłówki żądania
| Nagłówek | Wartość | Opis | Wymagany |
|---|---|---|---|
X-API-Key | String | Twój klucz API do uwierzytelnienia | Tak |
Content-Type | application/json | Format danych żądania | Tak |
Parametry żądania (body)
| Parametr | Typ | Opis | Wymagany |
|---|---|---|---|
session | String | Token sesji zwrócony podczas jej utworzenia | Tak |
message | String | Treść wiadomości od użytkownika | Tak |
webhook_data | Object | Dowolne dane JSON, które zostaną przekazane z powrotem w webhooku | Nie |
Przykładowe żądanie
{
"session": "abc123def456",
"message": "Dzień dobry, mam pytanie.",
"webhook_data": {
"message_reference": "msg-789",
"context": "homepage"
}
}Odpowiedzi
{
"success": true,
"message_id": 456
}{
"success": false,
"error": "Missing required parameter: message"
}{
"success": false,
"error": "Invalid session token"
}{
"success": false,
"error": "Rate limit exceeded",
"retry_after": 60
}Wypróbuj to
Odbieranie odpowiedzi przez webhook
Po przetworzeniu wiadomości przez chatbota, odpowiedź zostanie wysłana na skonfigurowany URL webhooka. Webhook otrzyma następujący format danych:
Format danych webhooka
{
"id": 457,
"role": "assistant",
"content": "Dzień dobry! Jak mogę pomóc?",
"timestamp": "2025-04-10T15:23:45.123456",
"session_token": "abc123def456",
"chatbot_id": 123,
"webhook_data": {
"conversation_id": "conv-456",
"department": "sales",
"message_reference": "msg-789",
"context": "homepage",
"custom_field": "wartość"
}
}Struktura odpowiedzi webhook:
| Pole | Typ | Opis |
|---|---|---|
id | Integer | Identyfikator wiadomości |
role | String | Rola autora wiadomości ("assistant") |
content | String | Treść odpowiedzi asystenta |
timestamp | String | Znacznik czasu w formacie ISO |
session_token | String | Token sesji |
chatbot_id | Integer | Identyfikator chatbota |
webhook_data | Object | Dane przekazane przy tworzeniu sesji lub wysyłaniu wiadomości |
is_error | Boolean | Obecne tylko jeśli wystąpił błąd podczas przetwarzania |
Nagłówki webhooka
Webhook zawiera następujące nagłówki, które można wykorzystać do weryfikacji źródła:
| Nagłówek | Opis |
|---|---|
X-Signature-Timestamp | Timestamp w formacie Unix |
X-Signature-Hash | Podpis HMAC-SHA256 |
Content-Type | application/json |
User-Agent | ChatbotAssistant-Webhook/1.0 |
Przykładowa implementacja obsługi webhooka
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const app = express();
const PORT = 3000;
const WEBHOOK_SECRET = 'secret123'; // z panelu administracyjnego
// Middleware do parsowania JSON
app.use(bodyParser.json());
// Endpoint webhooka
app.post('/webhooks/chatbot', (req, res) => {
const timestamp = req.headers['x-signature-timestamp'];
const signature = req.headers['x-signature-hash'];
const payload = JSON.stringify(req.body);
// Weryfikacja podpisu
const expectedSignature = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(`${timestamp}.${payload}`)
.digest('hex');
if (signature !== expectedSignature) {
console.error('Invalid webhook signature');
return res.status(401).json({ error: 'Invalid signature' });
}
// Przetwarzanie wiadomości
const { id, role, content, session_token, webhook_data } = req.body;
console.log(`Otrzymano wiadomość od chatbota: ${content}`);
console.log(`Dane webhook:`, webhook_data);
// Tutaj przetwarzanie wiadomości...
// Potwierdzenie odebrania
res.status(200).json({ success: true });
});
app.listen(PORT, () => {
console.log(`Webhook server running on port ${PORT}`);
});from flask import Flask, request, jsonify
import hmac
import hashlib
import json
app = Flask(__name__)
WEBHOOK_SECRET = 'secret123' # z panelu administracyjnego
@app.route('/webhooks/chatbot', methods=['POST'])
def chatbot_webhook():
# Pobierz dane i nagłówki
timestamp = request.headers.get('X-Signature-Timestamp')
signature = request.headers.get('X-Signature-Hash')
payload = request.data.decode('utf-8')
# Weryfikacja podpisu
expected_signature = hmac.new(
WEBHOOK_SECRET.encode(),
f"{timestamp}.{payload}".encode(),
hashlib.sha256
).hexdigest()
# Sprawdź podpis
if not hmac.compare_digest(expected_signature, signature):
return jsonify({'error': 'Invalid signature'}), 401
# Przetwarzanie danych
data = request.json
message_id = data.get('id')
content = data.get('content')
session_token = data.get('session_token')
webhook_data = data.get('webhook_data', {})
print(f"Otrzymano wiadomość od chatbota: {content}")
print(f"Dane webhook: {webhook_data}")
# Tutaj przetwarzanie wiadomości...
# Potwierdzenie odebrania
return jsonify({'success': True})
if __name__ == '__main__':
app.run(port=5000, debug=True)<?php
// Pobierz dane z żądania
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);
// Pobierz nagłówki
$timestamp = $_SERVER['HTTP_X_SIGNATURE_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_SIGNATURE_HASH'] ?? '';
// Sekret webhooka z panelu administracyjnego
$webhookSecret = 'secret123';
// Weryfikacja podpisu
$expectedSignature = hash_hmac('sha256', $timestamp . '.' . $payload, $webhookSecret);
if (!hash_equals($expectedSignature, $signature)) {
header('HTTP/1.1 401 Unauthorized');
echo json_encode(['error' => 'Invalid signature']);
exit;
}
// Przetwarzanie danych
$messageId = $data['id'] ?? null;
$content = $data['content'] ?? '';
$sessionToken = $data['session_token'] ?? '';
$webhookData = $data['webhook_data'] ?? [];
// Logowanie
error_log("Otrzymano wiadomość od chatbota: " . $content);
error_log("Dane webhook: " . json_encode($webhookData));
// Tutaj przetwarzanie wiadomości...
// Potwierdzenie odebrania
header('Content-Type: application/json');
echo json_encode(['success' => true]);
?>Weryfikacja webhooków
Aby zapewnić bezpieczeństwo i zweryfikować, że webhook pochodzi z naszego systemu, zalecamy sprawdzanie nagłówków podpisu:
X-Signature-Timestamp- timestamp w formacie UnixX-Signature-Hash- podpis HMAC-SHA256
Algorytm weryfikacji
Algorytm weryfikacji podpisu składa się z następujących kroków:
- Pobierz nagłówki
X-Signature-TimestampiX-Signature-Hashz żądania - Pobierz treść żądania jako surowy ciąg znaków (payload)
- Połącz timestamp i payload, oddzielając je kropką:
{timestamp}.{payload} - Oblicz HMAC-SHA256 z połączonego ciągu, używając sekretu webhooka jako klucza
- Porównaj obliczony HMAC z nagłówkiem
X-Signature-Hash, używając bezpiecznego porównania ciągów
Przykład kodu weryfikacji podpisu (Python)
import hmac
import hashlib
def verify_webhook(request, webhook_secret):
timestamp = request.headers.get('X-Signature-Timestamp')
signature = request.headers.get('X-Signature-Hash')
payload = request.body # Jako string JSON
expected_signature = hmac.new(
webhook_secret.encode(),
f"{timestamp}.{payload}".encode(),
digestmod=hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected_signature, signature)Przykład kodu weryfikacji podpisu (Node.js)
const crypto = require('crypto');
function verifyWebhook(req, webhookSecret) {
const timestamp = req.headers['x-signature-timestamp'];
const signature = req.headers['x-signature-hash'];
const payload = JSON.stringify(req.body);
const expectedSignature = crypto
.createHmac('sha256', webhookSecret)
.update(`${timestamp}.${payload}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(signature, 'hex')
);
}hmac.compare_digest() w Python lub crypto.timingSafeEqual() w Node.js.Uzyskanie sekretu webhooka
Sekret webhooka używany do weryfikacji podpisów można uzyskać na dwa sposoby:
- Jest zwracany podczas tworzenia sesji w odpowiedzi JSON w polu
webhook.secret - Można go znaleźć w panelu administracyjnym w ustawieniach chatbota
Dane webhook
Możesz przekazać dowolne dane w parametrze webhook_data, które zostaną zwrócone w odpowiedzi webhook. Jest to przydatne do:
- Identyfikacji, której rozmowy dotyczy odpowiedź
- Śledzenia kontekstu biznesowego (np. dział, kategoria produktu)
- Kierowania odpowiedzi do odpowiednich systemów lub użytkowników
- Przekazywania dodatkowych metadanych do Twojej aplikacji
Sposób działania
Dane webhook można przekazać zarówno podczas tworzenia sesji, jak i przy każdym wysłaniu wiadomości:
- Dane przekazane podczas tworzenia sesji - zostaną dołączone do wszystkich odpowiedzi webhook dla tej sesji
- Dane przekazane podczas wysyłania wiadomości - zastąpią dane sesji tylko dla odpowiedzi na tę konkretną wiadomość
Przykłady zastosowań
1. Śledzenie źródła rozmowy
{
"webhook_data": {
"source": "landing_page",
"campaign": "spring_sale_2025",
"referrer": "google"
}
}2. Przekazywanie danych użytkownika
{
"webhook_data": {
"user_id": "u-123456",
"user_type": "registered",
"account_level": "premium"
}
}3. Integracja z systemami CRM
{
"webhook_data": {
"crm_ticket_id": "T-78901",
"customer_segment": "enterprise",
"priority": "high"
}
}Kody błędów
API może zwrócić następujące kody błędów HTTP:
| Kod | Nazwa | Opis |
|---|---|---|
| 400 | Bad Request | Nieprawidłowe parametry żądania |
| 401 | Unauthorized | Brak uwierzytelnienia |
| 403 | Forbidden | Brak dostępu do zasobu (np. nieprawidłowy klucz API) |
| 404 | Not Found | Zasób nie istnieje (np. nieprawidłowy identyfikator chatbota) |
| 429 | Too Many Requests | Przekroczenie limitu zapytań |
| 500 | Internal Server Error | Błąd serwera |
Format odpowiedzi błędu
W przypadku błędu, API zwróci odpowiedź JSON z następującą strukturą:
{
"success": false,
"error": "Opis błędu",
"code": "ERROR_CODE" // Opcjonalny kod błędu
}Szczegółowe kody błędów
| Kod błędu | HTTP | Opis |
|---|---|---|
INVALID_API_KEY | 401 | Nieprawidłowy klucz API |
MISSING_PARAMETER | 400 | Brak wymaganego parametru |
INVALID_SESSION | 401 | Nieprawidłowy lub wygasły token sesji |
CHATBOT_NOT_FOUND | 404 | Chatbot o podanym identyfikatorze nie istnieje |
RATE_LIMIT_EXCEEDED | 429 | Przekroczono limit żądań |
WEBHOOK_ERROR | 500 | Błąd związany z webhookiem |
SERVER_ERROR | 500 | Wewnętrzny błąd serwera |
Retry-After lub pole retry_after w odpowiedzi wskazuje liczbę sekund, po których można ponowić żądanie.Dobre praktyki
Przy integracji z API chatbota warto stosować się do następujących dobrych praktyk:
Bezpieczeństwo
- Weryfikuj identyfikatory sesji
Przechowuj identyfikatory sesji w bezpiecznym miejscu i weryfikuj, czy należą do odpowiedniego użytkownika.
- Zawsze weryfikuj podpisy webhooków
Podpisy webhooków zapewniają, że dane pochodzą z naszego systemu i nie zostały zmodyfikowane.
- Używaj HTTPS
Wszystkie komunikacje z API powinny odbywać się przez HTTPS, aby zapewnić szyfrowanie danych.
- Regularnie rotuj klucze API
Zalecamy okresową zmianę kluczy API, aby zminimalizować ryzyko nieautoryzowanego dostępu.
Wydajność i niezawodność
- Monitoruj użycie API
Śledź wykorzystanie API, aby uniknąć przekroczenia limitów i identyfikować wzorce użycia.
- Optymalizuj webhooki
Upewnij się, że Twój serwer webhook odpowiada szybko, aby uniknąć timeoutów. Zalecamy delegowanie ciężkich operacji do zadań asynchronicznych.
Zarządzanie sesjami
- Używaj unikalnych identyfikatorów klienta
Parametr
client_idpomaga w śledzeniu sesji i rozwiązywaniu problemów. - Przechowuj kontekst rozmowy
W razie potrzeby zapisuj historię konwersacji po swojej stronie, aby zachować kontekst, nawet jeśli sesja wygaśnie.
Integracja
- Używaj
webhook_dataParametr
webhook_datapozwala na przekazywanie kontekstu biznesowego i ułatwia integrację odpowiedzi z Twoim systemem. - Testuj w środowisku developerskim
Zawsze testuj integrację w środowisku developerskim przed przejściem na produkcję.
Rate Limiting
Rate limiting to mechanizm ograniczający liczbę żądań API, które może wykonać jeden użytkownik w określonym czasie. Chroni to system przed nadmiernym obciążeniem i zapewnia sprawiedliwe wykorzystanie zasobów dla wszystkich użytkowników API.
Jak działa Rate Limiting:
- Limit per użytkownik: Każdy użytkownik ma swój własny limit (nie dzielony z innymi)
- Okno czasowe: 60 sekund
- Reset automatyczny: Licznik resetuje się co minutę
- Konfigurowalny limit: Każdy użytkownik może mieć różny limit ustawiony przez administratora
Co to oznacza dla zapytań API:
Gdy użytkownik osiągnie swój limit żądań w ciągu minuty, API zwróci błąd 429 Too Many Requests. W odpowiedzi na błąd 429 będzie zawarta informacja o czasie, po którym można ponowić żądanie.
Przykład odpowiedzi przy przekroczeniu limitu:
{
"success": false,
"error": "Rate limit exceeded",
"code": "RATE_LIMIT_EXCEEDED",
"retry_after": 45
}Pole retry_after wskazuje liczbę sekund, po których można ponowić żądanie.
Obsługa Rate Limitingu w kodzie:
Zalecamy implementację mechanizmu ponownych prób (retry) w przypadku otrzymania błędu 429:
async function apiRequestWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(url, options);
if (response.status === 429) {
const data = await response.json();
const retryAfter = data.retry_after || 60;
if (attempt < maxRetries) {
console.log(`Rate limit hit, retrying after ${retryAfter} seconds...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
throw new Error('Rate limit exceeded, max retries reached');
}
return response;
} catch (error) {
if (attempt === maxRetries) throw error;
}
}
}import time
import requests
from requests.exceptions import RequestException
def api_request_with_retry(url, headers, data, max_retries=3):
for attempt in range(max_retries + 1):
try:
response = requests.post(url, headers=headers, json=data)
if response.status_code == 429:
retry_after = response.json().get('retry_after', 60)
if attempt < max_retries:
print(f"Rate limit hit, retrying after {retry_after} seconds...")
time.sleep(retry_after)
continue
raise Exception('Rate limit exceeded, max retries reached')
return response
except RequestException as e:
if attempt == max_retries:
raise e<?php
function apiRequestWithRetry($url, $headers, $data, $maxRetries = 3) {
for ($attempt = 0; $attempt <= $maxRetries; $attempt++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 429) {
$responseData = json_decode($response, true);
$retryAfter = $responseData['retry_after'] ?? 60;
if ($attempt < $maxRetries) {
error_log("Rate limit hit, retrying after {$retryAfter} seconds...");
sleep($retryAfter);
continue;
}
throw new Exception('Rate limit exceeded, max retries reached');
}
return $response;
}
}
?>Zwiększenie limitów rate limitingu:
Jeśli standardowe limity rate limitingu nie są wystarczające dla Twojego przypadku użycia (np. w przypadku integracji o bardzo wysokim ruchu lub specjalistycznych zastosowań), możesz poprosić o ich zwiększenie.
- Implementuj mechanizm ponownych prób z odpowiednim opóźnieniem
- Monitoruj kod odpowiedzi 429 w Twojej aplikacji
- Przestrzegaj wartości
retry_afterzwracanej przez API - Rozważ użycie kolejek lub buforowania dla aplikacji o wysokim ruchu