Spis treści
Co musisz mieć
Każde żądanie do API niesie adres serwera i trzy wymagane nagłówki, po których API rozpoznaje Twoją instancję i klucz. Wszystkie znajdziesz w Tillio w widoku Ustawienia > Moduły > API > Ustawienia. Wartości w lewej kolumnie są przykładowe.
https://s2.public.api.tillio.app. Wszystkie ścieżki zaczynają się od /v2/.
Moduły > API > Ustawienia
https:// i bez ścieżki.
Moduły > API > Ustawienia
erp-sync) i klucz (64 znaki), połączone dwukropkiem bez spacji. Sam klucz bez nazwy nie zadziała. Klucz zakłada administrator instancji (krok 2 poniżej).
Moduły > API > Ustawienia > Klucze API
401. Jeśli nie widzisz modułu w Ustawienia > Moduły, napisz na pomoc@tillio.pl.
Od zera do pierwszego żądania
Każdy przykład ma dwie wersje: curl i PHP z oficjalnym SDK tillio-crm/api. Przełącznik nad kodem zmienia język we wszystkich przykładach naraz.
-
Otwórz ustawienia modułu API
W Tillio przejdź do Ustawienia > Moduły > API > Ustawienia. Znajdziesz tam parametry połączenia:
- adres serwera API (dla SaaS
https://s2.public.api.tillio.app), - domenę instancji do nagłówka
X-Tenant-Domain, - identyfikator instancji do nagłówka
X-Tenant-Id.
Jeśli czegoś tam brakuje albo coś jest niejasne, napisz na pomoc@tillio.pl.
- adres serwera API (dla SaaS
-
Załóż klucz API i skopiuj go
Administrator instancji (osoba z uprawnieniami administratora systemu) otwiera Ustawienia > Moduły > API > Ustawienia > Klucze API i dodaje nowy klucz: nazwę, która jest jednocześnie loginem (np.
erp-sync, unikalna w instancji), i opis, do czego klucz służy.Po zapisie system pokazuje klucz jeden raz. Skopiuj go od razu. Później można go tylko zresetować, co unieważnia poprzedni.
Do nagłówka
X-Api-Keypotrzebujesz obu wartości: nazwy klucza i klucza, połączonych dwukropkiem bez spacji:erp-sync:3f9a1c7e…. W konfiguracji integracji najwygodniej trzymać je jako dwie osobne zmienne i sklejać przy wysyłce, jak w przykładach niżej.Każdy klucz dostaje w Tillio własnego użytkownika systemowego o nazwie „API erp-sync”. To on jest autorem rekordów zapisanych przez API i widać go w historii zmian.
Przechodzisz z API v1? Klucze z API v1 działają w API v2 bez zmian, nie musisz zakładać nowych. API v2 nie jest zgodne z v1, więc przejście wymaga zmian w kodzie skryptu albo integracji. Więcej w sekcji API v1 (wycofywane). -
Sprawdź, czy serwer odpowiada
/v2/healthnie wymaga nagłówków. Zwraca wersję API wdrożoną na serwerze.curl https://s2.public.api.tillio.app/v2/health// composer require tillio-crm/api require 'vendor/autoload.php'; use TillioCrm\Api\TillioClient; $client = new TillioClient([ // adres serwera pomijasz: SDK domyślnie łączy się z https://s2.public.api.tillio.app 'tenantDomain' => 'firma.tillio.app', 'tenantId' => 'firma-tillio-app-k3j9x2', // nazwa-klucza:klucz, sklejone z dwóch zmiennych środowiskowych 'apiKey' => getenv('TILLIO_API_KEY_NAME') . ':' . getenv('TILLIO_API_KEY'), ]); $health = $client->health(); echo $health['version']; // numer wersji API, np. "X.Y.Z"{ "status": "ok", "version": "X.Y.Z", "contract": { "openapi": "/v2/openapi.json", "docs": "/v2/docs" }, "checks": { "crmAutoload": true } } -
Sprawdź swoje dane dostępowe
/v2/whoamito najtańszy test konfiguracji: nie czyta żadnych danych biznesowych, a potwierdza domenę, identyfikator i klucz.# dwie wartości z widoku Klucze API, trzymane w zmiennych środowiskowych export TILLIO_API_KEY_NAME="erp-sync" export TILLIO_API_KEY="TWÓJ_KLUCZ" curl https://s2.public.api.tillio.app/v2/whoami \ -H "X-Tenant-Domain: firma.tillio.app" \ -H "X-Tenant-Id: firma-tillio-app-k3j9x2" \ -H "X-Api-Key: $TILLIO_API_KEY_NAME:$TILLIO_API_KEY"use TillioCrm\Api\Exception\AuthenticationException; // $client z poprzedniego kroku try { $who = $client->whoami(); echo 'Połączono kluczem ', $who['keyName'], PHP_EOL; // erp-sync } catch (AuthenticationException $e) { // 401: sprawdź nazwę klucza, klucz, domenę i identyfikator instancji }{ "authenticated": true, "tenantDomain": "firma.tillio.app", "tenantId": "firma-tillio-app-k3j9x2", "keyName": "erp-sync", "userId": 1843 }Zamiast tego
401 auth.invalidCredentials? Przejdź listę w sekcji Gdy coś nie działa. -
Pobierz pierwsze dane
Lista kontrahentów, dwa rekordy na stronę, posortowana po
id. Odpowiedź poniżej jest skrócona.curl "https://s2.public.api.tillio.app/v2/contractors?limit=2&sort=id&sortDir=asc" \ -H "X-Tenant-Domain: firma.tillio.app" \ -H "X-Tenant-Id: firma-tillio-app-k3j9x2" \ -H "X-Api-Key: $TILLIO_API_KEY_NAME:$TILLIO_API_KEY"$page = $client->contractors()->list(['limit' => 2, 'sort' => 'id', 'sortDir' => 'asc']); foreach ($page as $contractor) { echo $contractor->id, ' ', $contractor->name, ' NIP: ', $contractor->taxId, PHP_EOL; // pola niestandardowe: klucze zależą od instancji (GET /v2/contractor/custom-fields) foreach ($contractor->customField as $key => $value) { echo ' ', $key, ': ', json_encode($value), PHP_EOL; } } echo $page->total; // 5598 $page->hasNextPage(); // true // wszystkie strony po kolei; SDK sam sortuje po id, żeby nie gubić rekordów foreach ($client->contractors()->iterate() as $contractor) { // ... }{ "data": [ { "id": 121, "name": "Acme", "taxId": "5252344078", "contractorStatusId": 3, "ownerUserId": 12, "updatedAt": "2026-09-12T14:05:11+02:00", "customField": {} } ], "pagination": { "page": 1, "limit": 2, "total": 5598, "pages": 2799 } } -
Zapisz rekord bez ryzyka duplikatu
Zapis wysyłasz jako JSON. Pole
duplicateCheckkaże najpierw sprawdzić, czy taki kontrahent już istnieje (tu po NIP-ie). Jeśli tak, API nie zakłada drugiego, tylko zwraca istniejący z200i"created": false. Nowy rekord to201.curl -X POST https://s2.public.api.tillio.app/v2/contractors \ -H "X-Tenant-Domain: firma.tillio.app" \ -H "X-Tenant-Id: firma-tillio-app-k3j9x2" \ -H "X-Api-Key: $TILLIO_API_KEY_NAME:$TILLIO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "ACME Sp. z o.o.", "taxId": "5252344078", "contractorTypeId": 2, "duplicateCheck": ["taxId"] }'use TillioCrm\Api\Dto\ContractorInput; use TillioCrm\Api\Dto\WriteOptions; $result = $client->contractors()->create( new ContractorInput( name: 'ACME Sp. z o.o.', taxId: '5252344078', contractorTypeId: 2, // 2 = Klient ), new WriteOptions(duplicateCheck: ['taxId']), ); $result->created; // true = nowy rekord (201), false = znaleziony istniejący (200) $result->id; // 950201 $result->matchedBy(); // null albo 'taxId', gdy znaleziono istniejący rekord $result->warnings; // wartości niezapisane po normalizacji{ "data": { "id": 950201, "name": "ACME Sp. z o.o.", … }, "info": { "created": true, "ids": { "contractorId": 950201, "noteId": 4021 }, "duplicate": null, "warnings": {} } }contractorTypeIdto typ kontrahenta, taki sam w każdej instancji:1Partner,2Klient,3Dostawca (GET /v2/contractor/types). Pozostałe słowniki, np. statusy czy źródła, różnią się między instancjami, więc ich id zawsze bierz z odpowiedniegoGET.Pola niestandardowe dopisujesz w obiekcie
customField. Ich klucze są inne w każdej instancji, więc najpierw pobierz je zGET /v2/contractor/custom-fields.
Dokumentacja
Dokumentacja jest na serwerze API, pod tym samym adresem co samo API, i nie wymaga klucza. Generuje się z kodu wdrożonego na tym serwerze, więc zawsze opisuje dokładnie tę wersję, z którą rozmawiasz.
Na górze Swaggera jest rozszerzony opis zasad: strefy czasowe, zakresy dat, synchronizacja przyrostowa, limity. Warto go przeczytać przed pisaniem synchronizacji.
SDK PHP
Oficjalne SDK obejmuje wszystkie trasy API. Ma typowane obiekty dla każdej encji, samo ponawia żądania po chwilowych błędach, pilnuje limitu żądań i przechodzi po stronach list tak, żeby nie gubić rekordów. Dokumentacja i przykłady są po polsku.
ext-curl i ext-json. Bez innych zależności. Licencja MIT.
composer require tillio-crm/api
use TillioCrm\Api\TillioClient;
$client = new TillioClient([
// adres serwera pomijasz: SDK domyślnie łączy się z https://s2.public.api.tillio.app
'tenantDomain' => 'firma.tillio.app',
'tenantId' => 'firma-tillio-app-k3j9x2',
// nazwa-klucza:klucz, np. "erp-sync:3f9a1c7e..."
'apiKey' => getenv('TILLIO_API_KEY_NAME') . ':' . getenv('TILLIO_API_KEY'),
]);
$client->whoami(); // test konfiguracji
// pełny przebieg po wszystkich stronach, bez gubienia rekordów
foreach ($client->contractors()->iterate(['updatedAfter' => '2026-09-01T00:00:00']) as $contractor) {
echo $contractor->name, ' ', $contractor->taxId, PHP_EOL;
}
SDK gotowe do pracy z agentami AI
Oficjalne SDK jest przygotowane do budowania integracji z pomocą agentów AI, takich jak Claude Code, Codex, Cursor czy GitHub Copilot. Razem z paczką instaluje się dokumentacja napisana z myślą o agentach: wspólne wzorce pracy z API, instrukcje krok po kroku dla każdego obszaru i działające przykłady. Wystarczy, że w poleceniu wskażesz agentowi, od czego zacząć. Gotowe polecenie do skopiowania:
Budujemy integrację z Tillio API v2 przy użyciu oficjalnego SDK tillio-crm/api (composer require tillio-crm/api).
Zanim napiszesz kod:
1. Przeczytaj vendor/tillio-crm/api/README.md.
2. Przeczytaj vendor/tillio-crm/api/docs/.ai/ai_integration.md.
3. Dla każdego obszaru, którego dotyczy zadanie (np. kontrahenci, zadania, notatki), przeczytaj odpowiednią instrukcję z vendor/tillio-crm/api/docs/.ai/ oraz przykłady z vendor/tillio-crm/api/docs/examples/ i vendor/tillio-crm/api/examples/.
Zasady:
- Nie zgaduj identyfikatorów. Użytkowników, wartości słowników i klucze pól niestandardowych pobieraj przez SDK.
- Klucz API (nazwa-klucza:klucz), domenę instancji i identyfikator instancji czytaj ze zmiennych środowiskowych. Nigdy nie wpisuj ich do kodu.
- Zanim wyślesz do instancji pierwsze żądanie zapisu, pokaż mi, co zostanie zapisane.
Agent pracuje w innym języku niż PHP? Zamiast SDK wskaż mu specyfikację openapi.json. Na jej podstawie wygeneruje klienta albo będzie wołać API bezpośrednio.
Przykładowe polecenie dla innych języków
Budujemy integrację z Tillio API v2 w języku [wpisz język, np. Python]. Dla tego języka nie ma oficjalnego SDK, więc pracujemy na specyfikacji OpenAPI.
Zanim napiszesz kod:
1. Pobierz i przeczytaj specyfikację https://s2.public.api.tillio.app/v2/openapi.json. Opis na jej początku wyjaśnia autoryzację, strefę czasową, zakresy dat, stronicowanie i limity.
2. Wygeneruj klienta ze specyfikacji (np. OpenAPI Generator) albo napisz cienką warstwę HTTP tylko dla endpointów potrzebnych w zadaniu.
3. Sprawdzaj pola, filtry i kody błędów w specyfikacji, zamiast ich zgadywać.
Zasady:
- Każde żądanie poza /v2/health wysyła nagłówki X-Tenant-Domain, X-Tenant-Id i X-Api-Key (nazwa-klucza:klucz).
- Klucz API, domenę instancji i identyfikator instancji czytaj ze zmiennych środowiskowych. Nigdy nie wpisuj ich do kodu.
- Nie zgaduj identyfikatorów. Użytkowników, wartości słowników i klucze pól niestandardowych pobieraj z API.
- Obsłuż błędy według kontraktu _error.errors[] (field, code, message) oraz limit żądań: po 429 odczekaj tyle sekund, ile podaje nagłówek Retry-After.
- Pełne listy pobieraj stronami, sortując po id.
- Zanim wyślesz do instancji pierwsze żądanie zapisu, pokaż mi, co zostanie zapisane.
Co obejmuje API
Ponad 220 operacji. Poniżej obszary w skrócie, pełna lista w Swaggerze. Większość encji ma listę z filtrami, odczyt po id, tworzenie (POST) i edycję (PUT).
Kontrahenci
Lista, odczyt, tworzenie i edycja, zapis paczkami do 100 pozycji (upsert), adresy, weryfikacja NIP, repozytorium plików (DMS), generowanie dokumentów z szablonów.
/v2/contractors/v2/contractors/upsert/v2/contractors/{id}/addresses/v2/contractors/{id}/dmsKontakty i leady
Osoby kontaktowe i leady: lista, odczyt, tworzenie, edycja, upsert. Lead zapisuje się razem z adresami e-mail w jednym żądaniu.
/v2/contacts/v2/leads/v2/leads/upsertSprzedaż
Szanse sprzedaży, lejki i etapy, produkty i grupy produktów, zamówienia z pozycjami, magazyny i stany magazynowe.
/v2/pipeline/items/v2/products/v2/orders/v2/warehouses/v2/stocksPraca zespołu
Notatki (z kontaktami, załącznikami i szablonami), zadania (z komentarzami, załącznikami, szablonami), zgłoszenia z wątkiem wiadomości, projekty, usługi u kontrahentów i katalog usług.
/v2/notes/v2/tasks/v2/tickets/v2/projects/v2/servicesKomunikacja
Wysyłka maili z podłączonych skrzynek (szablony, stopka, załączniki), połączenia telefoniczne, SMS, wyszukiwanie klienta po numerze telefonu, kalendarze i wydarzenia.
/v2/mail/send/v2/phone-calls/v2/text-messages/v2/lookup/phone/v2/calendarsKonfiguracja
Słowniki (statusy, źródła, typy, branże i inne; odczyt i zapis), procesy zgłoszeń i leadów, pola niestandardowe (definicje, tworzenie, pliki), użytkownicy (lista i zakładanie), role, działy, baza wiedzy, lista aktywnych modułów.
/v2/contractor/statuses/v2/{encja}/custom-fields/v2/users/v2/wiki/entries/v2/modulesZasady kontraktu
Odpowiedzi
Lista: data i pagination. Jeden rekord: data. Zapis: data z pełnym rekordem i info z utworzonymi id, znalezionym duplikatem i ostrzeżeniami.
Błędy
Zawsze _error z listą errors, gdzie każdy błąd ma field, code i message. Błąd w adresie to 400 query.*, błąd w treści żądania to 422 body.*.
Nieznany parametr to błąd
Literówka w filtrze daje 400, a nie całą bazę. Tak samo zła data, pusty updatedAfter czy limit spoza zakresu. API niczego nie zgaduje i nie przycina.
Stronicowanie
page i limit (domyślnie 100, najwyżej 1000). Domyślne sortowanie to data modyfikacji, która zmienia się w trakcie przebiegu. Do pełnego pobrania sortuj po id.
Synchronizacja przyrostowa
updatedAfter zwraca rekordy zmienione po podanej chwili (bez niej). Daty mają dokładność do sekundy, więc cofnij kursor o sekundę i odfiltruj rekordy już przetworzone po id.
Strefa czasowa instancji
Daty i godziny w API są w strefie wybranej w ustawieniach Twojej instancji Tillio, np. Europe/London albo Europe/Warsaw. Dotyczy to filtrów, zapisu i odpowiedzi. Strefa serwera, z którego uruchamiany jest skrypt wykorzystujący API, i strefa z profilu użytkownika nie mają znaczenia.
Wysłane 2026-09-12 14:05:11 to 14:05:11 czasu instancji. Pilnowanie strefy jest po stronie integracji: jeśli skrypt działa w innej strefie, przelicz datę na czas instancji albo wyślij ją z przesunięciem (np. +00:00), a API samo ją przeliczy. Odpowiedzi mają przesunięcie strefy instancji, np. 2026-09-12T14:05:11+01:00.
Pola niestandardowe
Obiekt customField w każdym rekordzie. Kluczem jest zawsze key z GET /v2/{encja}/custom-fields, nigdy etykieta widoczna w aplikacji. Klucze nadaje CRM przy tworzeniu pola, więc są inne w każdej instancji.
Słowniki
Pole o nazwie contractorStatusId mapujesz słownikiem GET /v2/contractor/statuses. Nazwa pola mówi, z którego słownika pochodzi wartość. Id są różne w każdej instancji.
Duplikaty i upsert
duplicateCheck wskazuje pola do sprawdzenia: taxId, email, phone albo custom:<klucz> dla własnego identyfikatora z Twojego systemu. Przy importach używaj /upsert: tworzy albo aktualizuje, do 100 pozycji w paczce.
Jedna nazwa pola
Pole nazywa się tak samo w odczycie i zapisie: ownerUserId to opiekun rekordu, creatorUserId autor. Możesz pobrać rekord, zmienić pole i odesłać bez mapowania. Kwoty to napisy dziesiętne, np. "1250000.00".
Wersje
Różne instancje mogą stać na różnych wersjach API. GET /v2/health podaje version, a opis funkcji dodanych później w Swaggerze mówi „dostępna od wersji API X.Y.Z”.
Moduły
Część obszarów to moduły, których instancja może nie mieć (Zgłoszenia, Leady, Szanse sprzedaży, Zadania, Projekty, DMS, Poczta). Sprawdzisz je z góry w GET /v2/modules.
Limity
Stan limitu żądań zwracamy w każdej odpowiedzi w nagłówkach X-RateLimit-Limit, X-RateLimit-Remaining i X-RateLimit-Reset (sekundy do nowego okna). Wartości poniżej są domyślne dla planu PRO.
| Limit | Wartość | Po przekroczeniu |
|---|---|---|
| Żądania na jeden klucz API | 1000 na 60 s | 429 rateLimit.exceeded i nagłówek Retry-After |
| Żądania z jednego adresu IP | 3000 na 60 s | 429; liczą się wszystkie klucze razem i żądania odrzucone |
| Rekordy na stronę listy | 100, najwyżej 1000 | 400 query.invalidValue |
| Pozycje w paczce upsert | 1 do 100 | 422 |
| Rozmiar treści JSON | 2 MB | 413 body.tooLarge |
| Obiekty i tablice w jednym żądaniu | 20 000 | 413 body.tooComplex |
| Załączniki jednego maila | 50 MB łącznie | 422 body.attachmentsTooLarge; liczą się też załączniki szablonu |
| Link do pobrania pliku | ważny 1 minutę | poproś o nowy link, nie zapisuj go u siebie |
Czego API nie robi
Nie usuwa głównych rekordów Tak jest z założenia: kontrahentów, kontakty, leady, zadania, notatki, zgłoszenia i zamówienia usuwa się w interfejsie Tillio. Przez API (
DELETE) usuniesz wybrane rekordy, wskazane w dokumentacji.Nie powiadamia o zmianach API v2 nie wysyła webhooków. Zmiany pobierasz cyklicznie przez
updatedAfter.Nie działa w imieniu konkretnego użytkownika Tillio Wszystkie zapisy idą jako użytkownik klucza API. Opiekuna rekordu wskazujesz polem
ownerUserId, ale autorem zmiany pozostaje użytkownik klucza.Nie cofa częściowej paczki Upsert zapisuje pozycje po kolei, bez wspólnej transakcji. Błąd jednej pozycji nie zatrzymuje pozostałych. Wynik każdej pozycji (
created,updated,failed) jest w odpowiedzi i trzeba go przeczytać.Nie jest zgodne z API v1 Klucze z v1 działają w v2, ale przejście na v2 wymaga zmian w kodzie skryptu albo integracji.
Nie zapisuje do wyłączonych modułów Zapis do obszaru, którego instancja nie ma w planie albo ma wyłączony, kończy się
403 module.notActivez nazwą modułu.Nie obsłuży funkcji, której nie ma Twoja wersja Tillio Jeśli instancja działa na starszej wersji systemu, nowsza funkcja zwróci
501 feature.notSupportedByCrmVersion. Reszta API działa normalnie.Nie wysyła maili bez podłączonej skrzynki Wysyłka idzie z kont pocztowych podłączonych w Tillio. Listę dostępnych kont zwraca
GET /v2/mail/accounts.
Bezpieczeństwo klucza
Użytkownik klucza API dostaje przy zakładaniu pełne uprawnienia do danych instancji. Traktuj klucz jak hasło administratora.
- Trzymaj klucz po stronie serwera. Nie wołaj API z przeglądarki, aplikacji mobilnej ani wtyczki: klucz byłby widoczny dla każdego użytkownika.
- Przechowuj go w sejfie sekretów albo zmiennej środowiskowej. Nie w repozytorium, nie w logach, nie w treści zgłoszeń.
- Jedna integracja, jeden klucz. Każdy klucz ma własny limit żądań, własnego autora w historii zmian i można go wyłączyć bez zatrzymywania pozostałych.
- Po wycieku zresetuj klucz od razu. Reset unieważnia stary klucz. Nieużywany klucz wyłącz albo usuń w Ustawienia > Moduły > API > Ustawienia > Klucze API.
- Łącz się wyłącznie przez HTTPS.
Gdy coś nie działa
Każdy błąd ma ten sam kształt: _error z kodem i listą errors, w której każdy wpis wskazuje pole, kod i opis. Komunikaty są celowo neutralne: szczegóły techniczne (zapytania, ścieżki na serwerze) nie wychodzą poza API.
use TillioCrm\Api\Exception\ApiException;
use TillioCrm\Api\Exception\ValidationException;
try {
$client->contractors()->list(['updatedAfter' => 'jutro']);
} catch (ValidationException $e) {
// 400 albo 422: wszystkie powody naraz
foreach ($e->errors as $error) {
echo $error->field, ': ', $error->message, PHP_EOL;
}
} catch (ApiException $e) {
// pozostałe błędy API: kod HTTP i pełna treść odpowiedzi
echo $e->status, ' ', $e->rawBody, PHP_EOL;
}
{
"_error": {
"code": 400,
"message": "validation.error",
"errors": [
{ "field": "updatedAfter", "code": "query.invalidDate", "message": "Parametr updatedAfter musi być datą ISO 8601." }
],
"requestId": "9c1e4b2a7f03d615"
}
}
| Odpowiedź | Co znaczy | Co zrobić |
|---|---|---|
| 401auth.missingApiKey auth.missingTenant |
Brakuje nagłówka X-Api-Key, X-Tenant-Domain albo X-Tenant-Id. |
Dodaj wszystkie trzy nagłówki do każdego żądania poza /v2/health i /v2/docs. |
| 401auth.invalidCredentials | Coś się nie zgadza. Ze względów bezpieczeństwa API nie mówi, co dokładnie. | Sprawdź po kolei: czy X-Api-Key ma obie części, nazwa-klucza:klucz, z dwukropkiem i bez spacji (sam klucz to 401); czy klucz jest aktywny i nie był resetowany; czy adres serwera, X-Tenant-Domain i X-Tenant-Id zgadzają się z widokiem Ustawienia > Moduły > API > Ustawienia; czy moduł API jest włączony. |
| 403tenant.blocked | Dane dostępowe są poprawne, ale instancja jest zablokowana. | Napisz na pomoc@tillio.pl. |
| 403module.notActive | Obszar należy do modułu, którego instancja nie ma albo ma wyłączony. | Sprawdź GET /v2/modules. Włącz moduł w ustawieniach albo rozszerz plan. |
| 400query.* | Błędny parametr w adresie: nieznany filtr, zła data, zły limit albo page. |
Popraw pole wskazane w errors[].field. Dozwolone filtry są w Swaggerze przy endpoincie. |
| 404contractor.notFound itp. resource.notFound |
Kod z nazwą encji: rekord o tym id nie istnieje. resource.notFound: takiej ścieżki nie ma w wersji API tego serwera. |
Sprawdź id, pisownię ścieżki i version w /v2/health. |
| 405method.notAllowed | Ścieżka istnieje, ale nie przyjmuje tej metody. | Nagłówek Allow podaje dozwolone metody. |
| 413body.tooLarge body.tooComplex |
Treść żądania przekracza limit. | Podziel dane na kilka mniejszych żądań. |
| 422body.* | Treść żądania nie przeszła walidacji. | Każdy błąd wskazuje pole osobno w errors[]. |
| 429rateLimit.exceeded | Przekroczony limit żądań. | Odczekaj tyle sekund, ile podaje Retry-After, i ponów żądanie. |
| 501feature.notSupportedByCrmVersion | Twoja wersja Tillio nie ma jeszcze tej funkcji. | Funkcja zadziała po aktualizacji systemu. Nie ponawiaj żądania. |
| 503system.maintenance | Trwa przerwa serwisowa Tillio. | Ponów żądanie później. |
| 500 | Błąd po stronie Tillio. | Napisz na pomoc@tillio.pl i dołącz wysłane żądanie oraz odpowiedź (szczegóły niżej). |
Zgłoszenie do Tillio
Z problemem albo pytaniem o API pisz na pomoc@tillio.pl. Diagnozę najbardziej przyspieszy wysłane żądanie razem z odpowiedzią API. Dołącz do zgłoszenia:
- żądanie: metodę, pełny adres z parametrami i treść (body), np.
POST /v2/contractorsz wysłanym JSON-em, - odpowiedź: kod HTTP i pełną treść, także gdy to błąd,
- datę i godzinę żądania,
- domenę instancji i nazwę klucza API (np.
erp-sync).
X-Api-Key. Nie przesyłaj go w mailu ani na zrzucie ekranu. Nazwa klucza wystarczy.
API v1 (wycofywane)
API v1 nie będzie już rozwijane. Tillio utrzymuje je co najmniej do września 2027 roku i wspiera wyłącznie w zakresie ewentualnych błędów bezpieczeństwa.
Jeśli utrzymujesz jeszcze integrację opartą na API v1, jej dokumentacja jest pod adresem doc-api.tillio.pl.