SuiteCRM API v8 w praktyce: uwierzytelnianie OAuth2, pobieranie i zapis rekordów
Każda integracja z SuiteCRM – przez n8n, Mautic, system do obsługi KSeF czy własny skrypt – sprowadza się do trzech operacji: uzyskania tokenu, odczytu rekordu i zapisu rekordu. SuiteCRM API v8 to interfejs REST zgodny ze standardem JSON:API 1.0, zabezpieczony wbudowanym serwerem OAuth 2.0. Pokazujemy, jak przygotować go w SuiteCRM 7.x i 8.x, jak uzyskać token oraz jak czytać i zapisywać dane – z przykładami w cURL i listą błędów, które najczęściej blokują wdrożenia.
Czym jest SuiteCRM API v8 i czym różni się od starszego API v4.1?
SuiteCRM API v8 to REST API wprowadzone w SuiteCRM 7.10, które wymienia dane w formacie JSON:API 1.0 przez HTTPS i wymaga uwierzytelnienia OAuth 2.0 (dokumentacja SuiteCRM, 2026). Starsze API v4.1, przejęte z SugarCRM Community Edition, nadal działa, ale korzysta z sesji uzyskiwanej loginem i hasłem oraz z własnego, niestandardowego formatu wywołań. Dla nowych integracji punktem wyjścia powinno być SuiteCRM API v8.
SuiteCRM 8 wprowadził dodatkowo warstwę GraphQL, z której korzysta nowy interfejs użytkownika. SuiteCRM API v8 działa w SuiteCRM 8 z tą samą logiką wywołań, ale pod inną ścieżką – w katalogu legacy. Dla integracji zewnętrznych to SuiteCRM API v8 pozostaje interfejsem opisanym w oficjalnej dokumentacji, z przewidywalnym kontraktem i obsługą przez gotowe narzędzia, takie jak n8n.
| Cecha | API v4.1 | SuiteCRM API v8 | GraphQL (SuiteCRM 8) |
| Dostępne od | SuiteCRM 7.0 (dziedzictwo SugarCRM CE) | SuiteCRM 7.10 | SuiteCRM 8.0 |
| Format | SOAP i REST, własny format wywołań | REST, JSON:API 1.0 | GraphQL |
| Uwierzytelnianie | Login i hasło, identyfikator sesji | OAuth 2.0, token Bearer | Sesja aplikacji SuiteCRM 8 |
| Główne zastosowanie | Starsze integracje | Integracje zewnętrzne | Komunikacja interfejsu użytkownika SuiteCRM 8 |
| Rekomendacja dla nowych integracji | Tylko utrzymanie istniejących | Tak | Nie jako pierwszy wybór – ograniczona dokumentacja dla integracji zewnętrznych |
Jak przygotować SuiteCRM do pracy z API v8?
Przygotowanie SuiteCRM do pracy z API v8 wymaga trzech kroków: wygenerowania pary kluczy RSA dla serwera OAuth2, utworzenia klienta OAuth2 w panelu administratora oraz założenia dedykowanego użytkownika API. Klucze podpisują tokeny dostępu, klient identyfikuje integrację, a użytkownik API wyznacza zakres danych, do których integracja ma dostęp. Pominięcie któregokolwiek kroku kończy się błędem już przy pierwszym żądaniu tokenu.
Jak wygenerować klucze OAuth2 dla SuiteCRM API v8?
Klucze OAuth2 dla SuiteCRM API v8 przechowuje się w katalogu Api/V8/OAuth2 (SuiteCRM 7.x) lub public/legacy/Api/V8/OAuth2 (SuiteCRM 8.x). Dokumentacja SuiteCRM wymaga, aby pliki kluczy miały uprawnienia 600 lub 660, a ich właścicielem był użytkownik serwera WWW, np. www-data.
# SuiteCRM 7.x – w SuiteCRM 8.x: cd /var/www/suitecrm/public/legacy/Api/V8/OAuth2
cd /var/www/suitecrm/Api/V8/OAuth2
openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout -out public.key
sudo chmod 600 private.key public.key
sudo chown www-data:www-data private.key public.key
Serwer OAuth2 potrzebuje także klucza szyfrującego zapisanego w pliku config.php jako oauth2_encryption_key. Instalator SuiteCRM generuje go automatycznie, dlatego problem z tym kluczem pojawia się zwykle po migracji lub ręcznym kopiowaniu konfiguracji między środowiskami. Dodatkowo serwer WWW musi obsługiwać przepisywanie adresów URL – w Apache oznacza to włączony mod_rewrite i obecny plik .htaccess w katalogu Api.
Jak utworzyć klienta OAuth2 w SuiteCRM?
Klienta OAuth2 tworzy się w panelu administratora SuiteCRM, w sekcji Admin > OAuth2 Clients and Tokens. Do wyboru są typy klienta odpowiadające grantom OAuth 2.0: client credentials, password oraz authorization code. Po zapisaniu klient otrzymuje identyfikator (Client ID), a sekret ustala administrator. Sekret należy przechowywać w menedżerze sekretów lub zmiennych środowiskowych integracji, nigdy w kodzie źródłowym ani repozytorium.
Dlaczego integracja potrzebuje dedykowanego użytkownika API?
Token SuiteCRM API v8 działa w kontekście konkretnego użytkownika SuiteCRM, więc integracja dziedziczy jego role, uprawnienia ACL i grupy bezpieczeństwa. Integracja działająca na koncie administratora ma dostęp do całej bazy, a wyciek jej sekretu oznacza wyciek wszystkich danych. Dedykowany użytkownik API z rolą ograniczoną do potrzebnych modułów zawęża skutki incydentu. Przykład: integracja z Mautic potrzebuje dostępu do modułów Leads i Contacts, ale nie do Opportunities ani Quotes.
Dedykowany użytkownik API porządkuje też historię zmian. W polu „Zmodyfikowane przez” widać wtedy nazwę integracji, np. api_mautic, zamiast nazwiska administratora. Przy kilku równoległych integracjach – na przykład osobno dla n8n, Mautic i systemu fakturowego – osobny użytkownik dla każdej z nich pozwala w kilka minut ustalić, który proces nadpisał dane klienta.
Jak uzyskać token dostępu OAuth2 w SuiteCRM API v8?
Token dostępu uzyskuje się żądaniem POST na adres /Api/access_token (SuiteCRM 7.x) lub /legacy/Api/access_token (SuiteCRM 8.x), przesyłając typ grantu, Client ID i sekret. Ścieżka tokenu nie zawiera segmentu V8, w przeciwieństwie do ścieżek modułów – to jedna z najczęstszych pułapek przy pierwszej konfiguracji. Typ grantu dobiera się do scenariusza integracji.
| Typ grantu | Kiedy stosować | Czy zwraca refresh token? |
| client_credentials | Integracje maszyna–maszyna: n8n, nocna synchronizacja, eksport do hurtowni danych | Nie – specyfikacja OAuth 2.0 (RFC 6749, sekcja 4.4.3) zaleca, by go nie wydawać |
| password | Aplikacja działająca w imieniu konkretnego użytkownika, który podaje login i hasło SuiteCRM | Tak |
| authorization_code | Aplikacje webowe i mobilne – użytkownik loguje się w SuiteCRM i zatwierdza dostęp | Tak |
Przykład żądania tokenu w grancie client_credentials:
curl -X POST “https://crm.example.com/Api/access_token” \
-H “Content-Type: application/vnd.api+json” \
-H “Accept: application/vnd.api+json” \
-d ‘{
“grant_type”: “client_credentials”,
“client_id”: “CLIENT_ID”,
“client_secret”: “CLIENT_SECRET”
}’
Odpowiedź zawiera token i czas jego ważności:
{
“token_type”: “Bearer”,
“expires_in”: 3600,
“access_token”: “eyJ0eXAi…”
}
Pole expires_in podaje czas ważności tokenu w sekundach – w przykładzie z dokumentacji SuiteCRM jest to 3600 sekund, czyli godzina. Integracja powinna odczytywać tę wartość z odpowiedzi, przechowywać token i pobierać nowy dopiero przed wygaśnięciem lub po odpowiedzi 401. Pobieranie nowego tokenu przed każdym wywołaniem niepotrzebnie obciąża serwer i zaśmieca listę aktywnych tokenów widoczną w panelu List OAuth2 Tokens.
W grantach password i authorization_code odpowiedź zawiera także refresh_token. Pozwala on uzyskać nowy token dostępu bez ponownego podawania danych logowania – wystarczy wysłać na ten sam adres żądanie z “grant_type”: “refresh_token”, wartością refresh tokenu oraz Client ID i sekretem.
Jak pobrać rekordy przez SuiteCRM API v8?
Pojedynczy rekord pobiera się żądaniem GET na /Api/V8/module/{Moduł}/{id}, a listę rekordów – na /Api/V8/module/{Moduł}. Każde żądanie musi zawierać nagłówek Authorization: Bearer {token}. W SuiteCRM 8.x obie ścieżki poprzedza segment /legacy. Zakres zwracanych danych kontrolują parametry fields, filter, sort i page.
curl -G “https://crm.example.com/Api/V8/module/Accounts/11a71596-83e7-624d-c792-5ab9006dd493” \
-H “Authorization: Bearer $TOKEN” \
-H “Accept: application/vnd.api+json” \
–data-urlencode “fields[Accounts]=name,account_type,billing_address_city”
Parametry SuiteCRM API v8 zawierają nawiasy kwadratowe, które cURL domyślnie traktuje jako wzorzec do rozwinięcia. Bezpieczne rozwiązanie to przełącznik -G z –data-urlencode, jak w przykładach, albo wyłączenie tej funkcji przełącznikiem -g. Ten sam problem dotyczy innych klientów HTTP – parametry z nawiasami należy kodować zgodnie z zasadami kodowania adresów URL.
Przykład listy klientów z Poznania, posortowanej od ostatnio zmienionych, po 50 rekordów na stronę:
curl -G “https://crm.example.com/Api/V8/module/Accounts” \
-H “Authorization: Bearer $TOKEN” \
-H “Accept: application/vnd.api+json” \
–data-urlencode “fields[Accounts]=name,account_type,date_modified” \
–data-urlencode “filter[operator]=and” \
–data-urlencode “filter[account_type][eq]=Customer” \
–data-urlencode “filter[billing_address_city][eq]=Poznań” \
–data-urlencode “sort=-date_modified” \
–data-urlencode “page[size]=50” \
–data-urlencode “page[number]=1”
| Parametr | Do czego służy | Przykład |
| fields[Moduł] | Ogranicza odpowiedź do wskazanych pól | fields[Accounts]=name,account_type |
| filter | Filtruje rekordy; operatory: eq, neq, gt, gte, lt, lte, in, nin, li (LIKE) | filter[account_type][eq]=Customer |
| filter[operator] | Łączy kilka warunków (and/or) | filter[operator]=and |
| sort | Sortuje wyniki; minus oznacza kolejność malejącą | sort=-date_modified |
| page[size], page[number] | Stronicowanie wyników, numeracja stron od 1 | page[size]=50&page[number]=2 |
Nazwy pól w SuiteCRM API v8 to nazwy systemowe, a nie etykiety z interfejsu. Listę modułów zwraca endpoint /Api/V8/meta/modules, a definicje pól danego modułu – /Api/V8/meta/fields/{Moduł}. Pola niestandardowe utworzone w Studio mają końcówkę _c, np. nip_c. Sprawdzenie nazw przez endpoint meta przed napisaniem integracji eliminuje większość błędów typu „pole nie zapisuje się”.
Jak utworzyć i zaktualizować rekord przez SuiteCRM API v8?
Nowy rekord tworzy się żądaniem POST na /Api/V8/module, przesyłając w treści nazwę modułu w polu type i wartości pól w obiekcie attributes. Aktualizacja to żądanie PATCH na ten sam adres – identyfikator rekordu podaje się w treści żądania, a nie w ścieżce URL. To odstępstwo od typowej konwencji REST regularnie zaskakuje programistów piszących pierwszą integrację.
Utworzenie firmy w module Accounts:
curl -X POST “https://crm.example.com/Api/V8/module” \
-H “Authorization: Bearer $TOKEN” \
-H “Content-Type: application/vnd.api+json” \
-H “Accept: application/vnd.api+json” \
-d ‘{
“data”: {
“type”: “Accounts”,
“attributes”: {
“name”: “Przykładowa Sp. z o.o.”,
“account_type”: “Customer”,
“billing_address_city”: “Poznań”
}
}
}’
Odpowiedź zawiera utworzony rekord wraz z identyfikatorem w polu id. Integracja powinna zapisać to ID po swojej stronie – na przykład w tabeli mapującej identyfikator z systemu źródłowego na identyfikator SuiteCRM. Bez takiego mapowania każda kolejna synchronizacja musi wyszukiwać rekord po nazwie lub NIP, co jest wolniejsze i prowadzi do duplikatów przy literówkach.
Aktualizacja wybranych pól istniejącego rekordu:
curl -X PATCH “https://crm.example.com/Api/V8/module” \
-H “Authorization: Bearer $TOKEN” \
-H “Content-Type: application/vnd.api+json” \
-H “Accept: application/vnd.api+json” \
-d ‘{
“data”: {
“type”: “Accounts”,
“id”: “11a71596-83e7-624d-c792-5ab9006dd493”,
“attributes”: {
“account_type”: “Partner”
}
}
}’
PATCH w SuiteCRM API v8 zmienia wyłącznie pola przesłane w attributes, a pozostałe pozostawia bez zmian. Usunięcie rekordu to żądanie DELETE na /Api/V8/module/{Moduł}/{id}. SuiteCRM oznacza wtedy rekord jako usunięty w polu deleted, zamiast fizycznie kasować wiersz z bazy danych, więc dane da się odzyskać na poziomie bazy.
Jak powiązać rekordy, np. kontakt z firmą?
Relacje w SuiteCRM API v8 obsługuje endpoint /Api/V8/module/{Moduł}/{id}/relationships/{nazwaPolaRelacji}. Nazwa pola relacji pochodzi z definicji modułu (vardefs), a nie z nazwy modułu – dla powiązania kontaktów z firmą jest to contacts. Powiązanie tworzy się żądaniem POST, a usuwa żądaniem DELETE z identyfikatorem powiązanego rekordu na końcu ścieżki.
curl -X POST “https://crm.example.com/Api/V8/module/Accounts/{ID_FIRMY}/relationships/contacts” \
-H “Authorization: Bearer $TOKEN” \
-H “Content-Type: application/vnd.api+json” \
-H “Accept: application/vnd.api+json” \
-d ‘{“data”: {“type”: “Contacts”, “id”: “{ID_KONTAKTU}”}}’
Jakie błędy najczęściej blokują integrację z SuiteCRM API v8?
Większość problemów z SuiteCRM API v8 wynika z konfiguracji serwera i uprawnień, a nie z samego kodu integracji. Poniższa tabela zestawia objawy, które widzimy najczęściej przy wdrożeniach i przejęciach istniejących integracji, wraz z przyczyną i sposobem naprawy.
| Objaw | Najczęstsza przyczyna | Rozwiązanie |
| 404 Not Found w SuiteCRM 8.x | Ścieżki skopiowane z dokumentacji dla SuiteCRM 7.x | Dodać segment /legacy, np. /legacy/Api/V8/module/Accounts |
| 404 przy żądaniu tokenu | Segment V8 w ścieżce tokenu lub brak przepisywania URL | Użyć /Api/access_token; sprawdzić mod_rewrite i plik .htaccess w katalogu Api |
| Błąd serwera przy generowaniu tokenu | Złe uprawnienia lub właściciel plików kluczy, brak oauth2_encryption_key | Ustawić uprawnienia 600/660 i właściciela www-data; sprawdzić config.php |
| 401 mimo poprawnego tokenu | Serwer (np. Apache z PHP-FPM) nie przekazuje nagłówka Authorization do PHP | Włączyć przekazywanie nagłówka, np. dyrektywą CGIPassAuth On lub regułą przepisującą HTTP_AUTHORIZATION |
| API zwraca mniej rekordów niż interfejs | Rola ACL lub grupy bezpieczeństwa użytkownika API | Zweryfikować rolę i grupy użytkownika, z którego kontekstu działa token |
| Pole nie zapisuje się | Nazwa etykiety zamiast nazwy systemowej, brak końcówki _c | Sprawdzić nazwy w /Api/V8/meta/fields/{Moduł} |
| Przekroczenie czasu przy dużych zbiorach | Pobieranie wszystkich rekordów bez stronicowania | Stosować page[size] i synchronizację przyrostową |
Synchronizacja przyrostowa ogranicza obciążenie SuiteCRM przy dużych bazach. Zamiast pobierać przy każdym przebiegu wszystkie rekordy, integracja zapamiętuje czas ostatniej synchronizacji i pobiera tylko rekordy zmienione później, filtrem filter[date_modified][gt]=2026-10-01 00:00:00. Hipotetyczny przykład: przy bazie 80 tys. firm, w której dziennie zmienia się kilkaset rekordów, nocna synchronizacja przenosi wtedy ułamek procenta danych zamiast całej bazy.
Kiedy pisać integrację bezpośrednio na SuiteCRM API v8, a kiedy użyć n8n lub gotowego konektora?
Integrację bezpośrednio na SuiteCRM API v8 opłaca się pisać, gdy logika jest złożona, wolumen danych duży, a obsługa błędów i ponowień musi być w pełni kontrolowana – na przykład przy synchronizacji z ERP. Narzędzia takie jak n8n sprawdzają się w typowych przepływach, jak formularz → lead czy nowy kontakt → Mautic, które zmieniają się często i utrzymuje je zespół bez programisty.
Oba podejścia korzystają z tego samego SuiteCRM API v8. Węzeł SuiteCRM w n8n, konektor Mautic czy integracja z KSeF wysyłają w tle te same żądania tokenu, odczytu i zapisu, które opisujemy wyżej. Znajomość API skraca diagnozę problemów niezależnie od wybranego narzędzia. Szczegóły konfiguracji opisujemy w osobnych artykułach: integracja SuiteCRM z n8n oraz SuiteCRM i KSeF.
Od czego zacząć pracę z SuiteCRM API v8?
Pracę z SuiteCRM API v8 najlepiej zacząć od środowiska testowego i jednego, prostego scenariusza: wygenerowania kluczy, utworzenia klienta client_credentials z dedykowanym użytkownikiem i pobrania listy pięciu firm. Jeśli to działa, problemy z kolejnymi wywołaniami wynikają już z danych lub uprawnień, a nie z konfiguracji serwera.
Przed uruchomieniem integracji produkcyjnej warto odpowiedzieć na jedno pytanie: z uprawnieniami którego użytkownika działają dziś Twoje integracje z SuiteCRM – i czy ten użytkownik naprawdę potrzebuje dostępu do wszystkich modułów?
Jeśli zainteresował Cię ten temat, skontaktuj się z nami. Chętnie odpowiemy na Twoje pytania.
Najczęściej zadawane pytania
Tak. W SuiteCRM 8.x SuiteCRM API v8 działa pod ścieżką z segmentem /legacy: token uzyskuje się z /legacy/Api/access_token, a moduły odpytuje przez /legacy/Api/V8/module/{Moduł}. Format JSON:API, uwierzytelnianie OAuth 2.0 i parametry zapytań pozostają takie same jak w SuiteCRM 7.x.
Czas ważności tokenu zwraca pole expires_in w odpowiedzi serwera, podane w sekundach. W przykładzie z dokumentacji SuiteCRM wynosi 3600 sekund, czyli godzinę. Integracja powinna odczytywać tę wartość z odpowiedzi zamiast zakładać ją na sztywno.
Dla integracji serwer–serwer, takich jak n8n czy nocna synchronizacja z ERP, właściwy jest grant client_credentials. Nie wymaga loginu i hasła użytkownika, a uprawnienia integracji wyznacza użytkownik SuiteCRM powiązany z klientem OAuth2.
Pola niestandardowe pobiera się tak samo jak standardowe, używając ich nazw systemowych. Pola utworzone w Studio mają końcówkę _c, np. nip_c. Pełną listę nazw pól modułu zwraca endpoint /Api/V8/meta/fields/{Moduł}.
Token SuiteCRM API v8 działa w kontekście użytkownika, więc obowiązują go role ACL i grupy bezpieczeństwa tego użytkownika. Jeśli użytkownik API nie ma dostępu do części rekordów, API ich nie zwróci. Rozwiązaniem jest korekta roli, a nie zmiana kodu integracji.
Tak, API v4.1 nadal jest dostępne i obsługuje istniejące integracje. Dla nowych integracji rekomendujemy jednak SuiteCRM API v8, które korzysta ze standardów JSON:API i OAuth 2.0, a więc współpracuje z typowymi bibliotekami i narzędziami integracyjnymi.



