Zgłoszenia w Codenica API
Pracę ze zgłoszeniami przez API zaczynasz od utworzenia klucza w ustawieniach Codenica. Jeżeli klucz nie został jeszcze utworzony, otwórz w nowej karcie Codenica API - wprowadzenie. Znajdziesz tam opis tworzenia kluczy, limitów licencyjnych oraz wspólnych zasad uwierzytelniania.
Zgłoszenie jest obiektem Service Desk. Oprócz zwykłych danych, takich jak temat, opis i osoba zgłaszająca, może zawierać priorytet, wpływ, pilność, ważność, status, dane SLA, informacje o rozwiązaniu, relacje z innymi obiektami oraz pliki. API udostępnia także akcje właściwe dla obsługi zgłoszeń: przypięcie, oznaczenie jako spam, ponowne otwarcie, ocenę, żądanie eskalacji i decyzję dotyczącą akceptacji.
W przykładach używamy nazw technicznych pól i tras, ponieważ dokładnie takie wartości należy przekazywać w żądaniach. Teksty przykładowe możesz zastąpić danymi swojej aplikacji.
Zgłoszenia - adres API
Wszystkie operacje na zgłoszeniach wykonuje się pod adresem:
{BASE_URL}/api/v1/ticketsW Codenica Cloud użyj publicznego adresu przypisanego do Twojej instalacji. W przykładzie poniżej użyto umownego adresu firmy:
https://twoja-firma.codenica.com/api/v1/ticketsW instalacji On-Premise domyślny adres rejestrowany przez Codenica Discovery to:
http://codenica.local:5150/api/v1/ticketsJeżeli administrator opublikował instalację pod innym adresem, użyj właśnie tego adresu, na przykład:
https://api.twoja-firma.example/api/v1/ticketsAdresu localhost używaj tylko wtedy, gdy aplikacja integrująca działa na tym samym komputerze co API. Do żądań nie dodajesz tenantId. Właściwa baza danych jest wybierana na podstawie adresu, z którym się łączysz.
Zgłoszenia - klucz API i limity licencyjne
Klucz tworzysz w Codenica w miejscu Ustawienia - API - API Keys. Sekret jest pokazywany tylko raz, bezpośrednio po utworzeniu albo obróceniu klucza. Zapisz wtedy obie wartości w bezpiecznym magazynie sekretów używanym przez integrację.
Liczba kluczy zależy od licencji przypisanej do instalacji:
Najlepiej utworzyć osobny klucz dla każdej integracji i środowiska, na przykład osobno dla systemu produkcyjnego, testowego i automatyzacji. Przy tworzeniu klucza wybierz tylko zakresy uprawnień potrzebne dla danego połączenia. Klucz używany w tym artykule powinien mieć co najmniej zakresy tickets:read, tickets:write i pozostałe zakresy wymagane przez planowane operacje.
Zgłoszenia - uwierzytelnianie i bezpieczne żądania
Integracja uwierzytelnia się dwoma nagłówkami. Nie potrzebuje do tego JWT administratora ani ciasteczek z panelu Codenica.
export BASE_URL="https://twoja-firma.codenica.com"
export CLIENT_ID="cna_example"
export CLIENT_SECRET="cns_example"
curl --request GET "$BASE_URL/api/v1/tickets?page=1&pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Klucza nie umieszczaj w kodzie aplikacji, repozytorium, logach ani w komunikatach błędów. Wartości CLIENT_ID i CLIENT_SECRET w przykładach są symboliczne. W środowisku produkcyjnym pobieraj je ze zmiennych środowiskowych albo z dedykowanego magazynu sekretów.
Odpowiedź API zawiera identyfikator żądania w meta.requestId. Zachowuj go w logach technicznych, ponieważ pomaga znaleźć konkretne żądanie podczas diagnozy. Nie zapisuj przy tym sekretu klucza.
Zgłoszenia - sprawdzenie kontekstu połączenia
Przed pierwszą operacją na zgłoszeniach możesz sprawdzić, czy adres, klucz i zakresy zostały ustawione prawidłowo. Endpoint kontekstu zwraca między innymi wersję API, identyfikator bazy, tożsamość wywołującego, zakresy i możliwości dostępne dla klucza.
curl --request GET "$BASE_URL/api/v1/context" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"W prawidłowej odpowiedzi sprawdź:
data.apiVersion- powinna wskazywać wersjęv1;data.contractVersion- wersję kontraktu, z którą pracuje integracja;data.tenant.idorazdata.tenant.resolvedDomain- bazę danych i rozpoznany adres;data.caller.authentication- wartośćapi_key;data.caller.scopes- zakresy przypisane do klucza;data.capabilities.resources- obecność zasobutickets;- limity stron, operacji batch i żądań na minutę.
Jeśli na tym etapie brakuje zakresu, zmień uprawnienia klucza w ustawieniach albo utwórz nowy klucz. Nie próbuj przekazywać zakresów w samym żądaniu.
Zgłoszenia - zakresy uprawnień
Dla pełnej obsługi zgłoszeń potrzebne są następujące zakresy:
tickets:read
tickets:write
tickets:delete
tickets:schema
tickets:stats
tickets:relationships:read
tickets:relationships:write
tickets:users:read
tickets:users:write
tickets:files:read
tickets:files:write
tickets:technical:read
tickets:technical:write
tickets:pin:write
tickets:spam:write
tickets:reopen:write
tickets:rating:write
tickets:escalation:write
tickets:approval:writeNie każda integracja potrzebuje pełnego zestawu. Integracja tylko do odczytu może korzystać z tickets:read, a do pobrania schematu, statystyk i wartości słownikowych dodać odpowiednio tickets:schema i tickets:stats. Odczyt relacji, użytkowników i plików wymaga właściwych zakresów :relationships:read, :users:read i :files:read.
Jeśli używasz decyzji dotyczącej akceptacji zgłoszenia, potrzebujesz tickets:approval:write. Jeżeli dana integracja sama tworzy i obsługuje obiekty akceptacji, potrzebuje dodatkowo zakresów dotyczących approvals. Nie przyznawaj uprawnień zapisu tylko dlatego, że są wygodne w czasie pierwszego testu.
Zgłoszenia - schemat i pola
Schemat pozwala pobrać aktualną konfigurację pól dla Twojej bazy danych. Jest to ważne szczególnie dla wartości słownikowych, takich jak status, priorytet, wpływ, pilność, ważność, typ i kategoria.
curl --request GET "$BASE_URL/api/v1/tickets/schema" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"W odpowiedzi odszukaj pola oznaczone jako required, writable, technical i hasAutoGeneration. Przy tworzeniu zgłoszenia wymagane są co najmniej subject oraz requesterEmail. Pozostałe pola zapisujesz tylko wtedy, gdy są dostępne i potrzebne w Twoim obiegu pracy.
subject, requesterEmail, description, commentstype, category, priority, impact, urgency, severity, statuslocation, department, teams, servicesexternalNumber, referenceNumber, link, tagsPola sla, rating, feedback, pin, isSpam oraz daty związane z akcjami są zarządzane przez system lub dedykowane endpointy. Nie zakładaj, że można je zmienić zwykłym PATCH.
Zgłoszenia - podstawowe trasy
Najczęściej używane trasy wyglądają następująco:
GET /api/v1/tickets- lista zgłoszeń;GET /api/v1/tickets/{id}- jedno zgłoszenie;POST /api/v1/tickets- utworzenie zgłoszenia;PATCH /api/v1/tickets/{id}- częściowa aktualizacja;DELETE /api/v1/tickets/{id}- usunięcie;GET /api/v1/tickets/schema- schemat pól;GET /api/v1/tickets/stats- statystyki;GET /api/v1/tickets/values- wartości używane w filtrach;POST /api/v1/tickets:batch- wiele operacji w jednym żądaniu.
Relacje, użytkownicy, pliki i akcje mają osobne trasy opisane w dalszych częściach. Rozdzielenie tych operacji pozwala przyznać integracji dokładnie takie uprawnienia, jakich potrzebuje.
Zgłoszenia - listy i paginacja
Listę pobierasz metodą GET. Warto zawsze podać numer strony i rozmiar strony, nawet jeśli na początku spodziewasz się niewielkiej liczby rekordów.
curl --request GET "$BASE_URL/api/v1/tickets?page=1&pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"W odpowiedzi otrzymasz obiekt data z polami items, page, pageSize, totalItems, totalPages i hasNextPage. Gdy hasNextPage ma wartość true, pobierz następną stronę.
curl --request GET "$BASE_URL/api/v1/tickets?page=2&pageSize=25&sort=dateUpdated&direction=desc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Sortowanie zależy od pola obsługiwanego przez API. Jeżeli chcesz budować synchronizację, sortuj po dateUpdated malejąco lub rosnąco i zapamiętuj ostatnio przetworzony rekord.
Zgłoszenia - wyszukiwanie i filtrowanie
API pozwala łączyć wyszukiwanie tekstowe z filtrami pól. Parametr search służy do ogólnego wyszukiwania, natomiast filter pozwala określić operator i wartość.
curl --get "$BASE_URL/api/v1/tickets" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=25" \
--data-urlencode "search=VPN" \
--data-urlencode "filter=status:eq:Open" \
--data-urlencode "filter=priority:eq:High" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Przykładowe filtry przydatne przy pracy ze zgłoszeniami:
filter=status:eq:Closed- zamknięte zgłoszenia;filter=priority:eq:High- wysoki priorytet;filter=subject:contains:VPN- temat zawierający określony tekst;filter=description:notEmpty:- zgłoszenia z opisem;filter=isSpam:eq:false- zgłoszenia nieoznaczone jako spam.
Wartości statusu, priorytetu i innych słowników pobieraj z konfiguracji swojej bazy przez endpoint values. Nie zakładaj, że identyczne nazwy występują w każdej instalacji.
Zgłoszenia - pola odpowiedzi i rozszerzenia
Jeśli potrzebujesz tylko podstawowej listy, pozostaw domyślny zestaw pól. Dodatkowe pola możesz wskazać przez fields, a powiązane dane przez include.
curl --get "$BASE_URL/api/v1/tickets" \
--data-urlencode "fields=id,itemType,subject,status,priority,requesterEmail,dateUpdated" \
--data-urlencode "include=relationships,users,files" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=10" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Do odczytu całego modelu możesz użyć fields=*. Rozszerzenia mogą wymagać dodatkowych zakresów. Jeżeli integracja nie ma dostępu do użytkowników, relacji albo plików, usuń odpowiedni element z include lub nadaj właściwe uprawnienie.
Przy synchronizacji warto zwracać uwagę na id, itemType, attributes i meta. Identyfikator obiektu jest stabilny, a meta.etag służy do bezpiecznej aktualizacji.
Zgłoszenia - statystyki i wartości pól
Statystyki są przydatne na przykład do policzenia zgłoszeń według priorytetu. Nie zmieniają danych.
curl --get "$BASE_URL/api/v1/tickets/stats" \
--data-urlencode "field=priority" \
--data-urlencode "limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Wartości pola możesz pobrać z opcjonalnym wyszukiwaniem:
curl --get "$BASE_URL/api/v1/tickets/values" \
--data-urlencode "field=priority" \
--data-urlencode "search=High" \
--data-urlencode "limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Przed wysłaniem nowego zgłoszenia pobierz dostępne wartości z tej samej bazy. Dzięki temu integracja nie będzie wysyłała wartości, której lokalna konfiguracja nie rozpoznaje.
Zgłoszenia - tworzenie
Nowe zgłoszenie tworzysz metodą POST. Minimalny użyteczny zestaw obejmuje itemType, temat i adres osoby zgłaszającej. Pozostałe dane dobierz do procesu obsługi.
curl --request POST "$BASE_URL/api/v1/tickets" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: ticket-create-ERP-2026-001" \
--data '{
"itemType": "ticket",
"attributes": {
"customId": "ERP-TICKET-2026-001",
"subject": "VPN niedostępny dla działu finansowego",
"requesterEmail": "[email protected]",
"description": "Połączenie VPN zostaje przerwane po kilku minutach pracy.",
"comments": "Zgłoszenie utworzone z systemu ERP.",
"source": "ERP",
"type": "Incident",
"category": "Network",
"status": "Open",
"priority": "High",
"impact": "Department",
"urgency": "High",
"severity": "Major",
"services": "VPN",
"tags": "vpn;finance;integration",
"externalNumber": "ERP-4581",
"referenceNumber": "INC-2026-001",
"currency": "PLN",
"estimatedCost": 150.00
}
}'Wartości słownikowe w tym przykładzie są przykładowe. Zastąp je wartościami zwróconymi przez schemat i endpoint values Twojej bazy. Pomyślne utworzenie zwraca 201 Created, identyfikator data.id oraz aktualny ETag w nagłówku i w data.meta.etag. Zapisz te wartości, ponieważ będą potrzebne podczas kolejnych operacji.
Zgłoszenia - idempotencja operacji zapisu
Każde żądanie tworzące, zmieniające lub usuwające dane powinno mieć unikalny nagłówek Idempotency-Key. Chroni to przed podwójnym utworzeniem zgłoszenia, gdy aplikacja ponowi żądanie po przerwaniu połączenia.
curl --request POST "$BASE_URL/api/v1/tickets" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: ticket-create-ERP-2026-001" \
--data '{
"itemType": "ticket",
"attributes": {
"subject": "VPN niedostępny dla działu finansowego",
"requesterEmail": "[email protected]"
}
}'Powtórzenie tego samego żądania z tą samą metodą, trasą, treścią i kluczem idempotencji powinno zwrócić ten sam rekord. Nowa operacja musi mieć nowy klucz. Nie używaj jednego stałego klucza dla wszystkich zgłoszeń.
Klucz idempotencji zapisuj po stronie integracji razem ze stanem przetwarzania. Jeżeli zmienisz treść żądania, użyj nowego klucza, nawet gdy dotyczy tego samego zgłoszenia.
Zgłoszenia - odczyt pojedynczego rekordu
Po utworzeniu lub znalezieniu identyfikatora zgłoszenie odczytasz przez jego UUID:
export TICKET_ID="TICKET_UUID"
curl --get "$BASE_URL/api/v1/tickets/$TICKET_ID" \
--data-urlencode "fields=*" \
--data-urlencode "include=relationships,users,files" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"W odpowiedzi odczytaj data.attributes oraz data.meta.etag. ETag może zmienić się po zmianie danych, relacji, użytkowników, plików albo wykonaniu akcji. Przed operacją zapisu korzystaj z aktualnego ETag, a nie z wartości zapamiętanej podczas wcześniejszego odczytu.
Zgłoszenia - edycja i ochrona ETag
Aktualizację wykonujesz metodą PATCH. Przekazuj tylko pola, które chcesz zmienić, oraz ETag odczytany z bieżącej wersji zgłoszenia.
curl --request PATCH "$BASE_URL/api/v1/tickets/$TICKET_ID" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-update-ERP-2026-001" \
--data '{
"attributes": {
"status": "In Progress",
"priority": "High",
"comments": "Zespół sieci analizuje przerwanie sesji VPN.",
"resolutionSummary": ""
}
}'Po udanej aktualizacji otrzymasz 200 OK i nowy ETag. Pola zarządzane przez akcje, takie jak isSpam, pin i rating, zmieniaj przez ich dedykowane endpointy. Nie próbuj omijać tego podziału zwykłym PATCH.
Jeżeli aktualizujesz termin, koszt albo dane integracji, zachowaj ten sam sposób kodowania typów, który zwraca schemat. Daty przesyłaj w formacie ISO 8601, a wartości dziesiętne jako liczby JSON.
Zgłoszenia - nieaktualny lub brakujący ETag
API blokuje zapis na podstawie nieaktualnej wersji rekordu. Jeżeli dwa procesy pracują równocześnie, drugi nie nadpisze zmian pierwszego bez świadomego ponowienia operacji.
Nieaktualny ETag zwraca 412 Precondition Failed z kodem if_match_failed. Brak nagłówka If-Match zwraca 428 Precondition Required z kodem if_match_required.
curl --request PATCH "$BASE_URL/api/v1/tickets/$TICKET_ID" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-update-retry-ERP-2026-001" \
--data '{
"attributes": {
"comments": "Ponowiona aktualizacja po odczytaniu bieżącej wersji."
}
}'Po otrzymaniu jednego z tych błędów pobierz zgłoszenie ponownie, sprawdź, czy zmiana nadal jest potrzebna, i wyślij ją z nowym ETag oraz nowym kluczem idempotencji. Nie wyłączaj kontroli ETag po stronie integracji.
Zgłoszenia - relacje z obiektami
Zgłoszenie może być łączone z obiektami widocznymi w schemacie relacji, między innymi z zasobami, dokumentami, innymi zgłoszeniami, zmianami, problemami, wydaniami, notatkami, akceptacjami, zadaniami i zapotrzebowaniami. Dostępna lista może zależeć od konfiguracji i zakresów klucza, dlatego przed zapisem sprawdź relationshipTargets w schemacie.
Odczyt relacji:
curl --request GET "$BASE_URL/api/v1/tickets/$TICKET_ID/relationships?page=1&pageSize=50" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Dodanie relacji z zasobem może wyglądać tak:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/relationships" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-relation-asset-ERP-2026-001" \
--data '{
"targetId": "ASSET_UUID",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
}'Jeżeli chcesz dodać kilka relacji w jednym żądaniu, użyj operacji batch:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/relationships:batch" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-relationship-batch-ERP-2026-001" \
--data '{
"add": [
{
"targetId": "OTHER_TICKET_UUID",
"targetDataSet": "tickets",
"targetItemType": "ticket",
"relationshipType": "related"
},
{
"targetId": "DOCUMENT_UUID",
"targetDataSet": "documents",
"targetItemType": "document",
"relationshipType": "related"
}
],
"remove": []
}'Wartość targetItemType musi odpowiadać rzeczywistemu typowi wskazanego obiektu. Po dodaniu i usunięciu relacji aktualizuje się ETag zgłoszenia. Usuwanie wykonuje się trasą z nazwą zbioru i identyfikatorem obiektu, zwykle z parametrem relationshipType:
curl --request DELETE "$BASE_URL/api/v1/tickets/assets/$ASSET_ID?relationshipType=related" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-relation-remove-ERP-2026-001"Zgłoszenia - relacje z użytkownikami i klientami
Relacje użytkowników są oddzielone od relacji z obiektami. Możesz między innymi przypisać pracownika jako agent, dodać obserwatora jako watcher, wskazać użytkownika zgłaszającego przez appUserRequester albo klienta przez clientRequester.
Lista relacji użytkowników:
curl --get "$BASE_URL/api/v1/tickets/$TICKET_ID/user-relationships" \
--data-urlencode "relationshipType=agent" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Przypisanie pracownika:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/user-relationships" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-agent-ERP-2026-001" \
--data '{
"targetId": "USER_UUID",
"targetDataSet": "users",
"relationshipType": "agent"
}'Kilka relacji użytkowników możesz zmienić jednym żądaniem:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/user-relationships:batch" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-user-relationship-batch-ERP-2026-001" \
--data '{
"add": [
{
"targetId": "WATCHER_USER_UUID",
"targetDataSet": "users",
"relationshipType": "watcher"
}
],
"remove": []
}'Dodanie obserwatora ma ten sam format, ale używa typu watcher. Relację z klientem zapisujesz z targetDataSet równym clients i typem clientRequester. Zakres tickets:users:write nie daje dostępu do każdego użytkownika ani nie omija jego uprawnień.
Usunięcie przypisania wymaga typu relacji w parametrze zapytania:
curl --request DELETE "$BASE_URL/api/v1/tickets/$TICKET_ID/user-relationships/users/$USER_ID?relationshipType=agent" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-agent-remove-ERP-2026-001"Zgłoszenia - pliki
Pliki mają własne trasy. Do wysłania pliku potrzebujesz aktualnego ETag zgłoszenia, nagłówka idempotencji oraz żądania typu multipart.
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/files?relationshipType=documentation" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-file-ERP-2026-001" \
--form "[email protected];type=text/plain"Pomyślne wysłanie zwraca 201 Created oraz dane pliku, w tym jego identyfikator i ścieżkę downloadUrl. Listę plików pobierzesz tak:
curl --request GET "$BASE_URL/api/v1/tickets/$TICKET_ID/files?page=1&pageSize=50" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Plik pobierasz jako dane binarne, dlatego zapisz odpowiedź do pliku:
curl --request GET "$BASE_URL/api/v1/tickets/$TICKET_ID/files/$FILE_ID/content" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output pobrany-plik.txtIstniejący plik możesz dołączyć do innego zgłoszenia trasą POST /api/v1/tickets/{id}/files/{fileId}. Przed usunięciem sprawdź identyfikator pliku i użyj ETag zgłoszenia. Usunięcie pliku wykonuje się przez DELETE /api/v1/tickets/{id}/files/{fileId}. Zgłoszenia nie mają osobnej akcji ustawiania pliku głównego.
Dołączenie istniejącego pliku do innego zgłoszenia:
curl --request POST "$BASE_URL/api/v1/tickets/$OTHER_TICKET_ID/files/$FILE_ID?relationshipType=manual" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $OTHER_TICKET_ETAG" \
--header "Idempotency-Key: ticket-file-attach-ERP-2026-001"Usunięcie pliku z bieżącego zgłoszenia:
curl --request DELETE "$BASE_URL/api/v1/tickets/$TICKET_ID/files/$FILE_ID" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-file-delete-ERP-2026-001"Zgłoszenia - przypięcie, spam i ponowne otwarcie
Niektóre właściwości zgłoszenia są zmieniane przez dedykowane akcje. Każda akcja wymaga bieżącego ETag i własnego klucza idempotencji.
Przypięcie zgłoszenia:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/pin" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-pin-ERP-2026-001" \
--data '{"pin":2}'Aby usunąć przypięcie, wyślij wartość null:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/pin" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-unpin-ERP-2026-001" \
--data '{"pin":null}'Oznaczenie zgłoszenia jako spam:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/spam" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-spam-ERP-2026-001" \
--data '{"isSpam":true}'Cofnięcie oznaczenia wykonujesz przez tę samą trasę z treścią {"isSpam":false}. Ponowne otwarcie zamkniętego zgłoszenia:
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/reopen" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-reopen-ERP-2026-001"Do tych operacji potrzebujesz odpowiednio tickets:pin:write, tickets:spam:write albo tickets:reopen:write. Po każdej udanej akcji zapisz nowy ETag zwrócony przez API.
Zgłoszenia - ocena i żądanie eskalacji
Po obsłudze zgłoszenia możesz zapisać ocenę oraz komentarz osoby oceniającej. Ocena ma wartość od 0 do 5.
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/rating" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-rating-ERP-2026-001" \
--data '{
"rating": 4,
"feedback": "Problem został rozwiązany, a kontakt z zespołem był sprawny.",
"isEscalationRequested": true,
"escalationRequestReason": "Proszę o dodatkową weryfikację stabilności połączenia VPN."
}'Jeżeli zapisujesz tylko ocenę, pomiń pola dotyczące eskalacji. Jeżeli dołączasz żądanie eskalacji, potrzebujesz także tickets:escalation:write. Sama ocena wymaga tickets:rating:write. Po zapisaniu wartości są widoczne jako pola tylko do odczytu, między innymi rating, feedback, dateRating, dateFeedback, dateEscalationRequest i escalationRequestReason.
Zgłoszenia - decyzja dotycząca akceptacji
Jeżeli do zgłoszenia przypisano akceptację, wyznaczony akceptujący może podjąć decyzję bezpośrednio przez trasę zgłoszenia. Potrzebuje do tego zakresu tickets:approval:write i musi być osobą przypisaną do danej akceptacji.
export APPROVAL_ID="APPROVAL_UUID"
curl --request POST "$BASE_URL/api/v1/tickets/$TICKET_ID/approvals/$APPROVAL_ID" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-approval-ERP-2026-001" \
--data '{
"approve": true,
"remark": "Zmiana została sprawdzona i może zostać wdrożona."
}'Odrzucenie wykonujesz z approve równym false i własnym komentarzem. APPROVAL_ID jest identyfikatorem akceptacji, nie identyfikatorem użytkownika. Jeżeli integracja tworzy akceptację samodzielnie, korzysta z osobnego zasobu approvals, wskazuje użytkownika akceptującego i łączy akceptację ze zgłoszeniem relacją. Po decyzji odczytaj zgłoszenie ponownie i zapisz nowy ETag.
Zgłoszenia - operacje batch, usuwanie i błędy
Wiele operacji możesz wysłać przez POST /api/v1/tickets:batch. Każdy element opisuje operację create, update albo delete. Aktualizacja i usunięcie wymagają własnego ifMatch, ponieważ każdy rekord może mieć inną wersję.
curl --request POST "$BASE_URL/api/v1/tickets:batch" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Content-Type: application/json" \
--header "Idempotency-Key: tickets-batch-ERP-2026-001" \
--data '{
"items": [
{
"operation": "create",
"create": {
"itemType": "ticket",
"attributes": {
"subject": "Brak dostępu do drukarki",
"requesterEmail": "[email protected]",
"description": "Drukarka nie odpowiada na żądania wydruku.",
"source": "ERP"
}
}
},
{
"operation": "update",
"id": "TICKET_UUID",
"ifMatch": "\"CURRENT_ETAG\"",
"update": {
"attributes": {
"priority": "Normal"
}
}
}
]
}'Odpowiedź może mieć status 200 albo 207 Multi-Status, gdy część elementów się nie powiedzie. Przetwórz każdą pozycję odpowiedzi według jej indeksu, operacji, statusu i pola error. Nie zakładaj, że błąd jednego elementu cofa wszystkie pozostałe.
Usunięcie pojedynczego zgłoszenia wymaga najpierw odczytania aktualnego ETag:
curl --request DELETE "$BASE_URL/api/v1/tickets/$TICKET_ID" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $TICKET_ETAG" \
--header "Idempotency-Key: ticket-delete-ERP-2026-001"Po 200 OK sprawdź ponownym odczytem, że zgłoszenie zwraca 404 z kodem ticket_not_found. Najczęstsze odpowiedzi problemowe to: 400 dla nieprawidłowych danych, 401 dla braku uwierzytelnienia, 403 dla brakującego zakresu, 404 dla nieistniejącego rekordu, 409 dla konfliktu, 412 dla nieaktualnego ETag, 428 dla brakującego ETag albo idempotencji i 429 po przekroczeniu limitu. Odpowiedź problemowa zawiera między innymi title, detail, code i requestId. Zachowuj te informacje w logach i ponawiaj tylko te operacje, które można bezpiecznie powtórzyć.
Praktyczna kolejność pracy wygląda tak: sprawdź kontekst, pobierz schemat i wartości, pobierz lub utwórz zgłoszenie, zapisz ETag, wykonuj zmiany z idempotencją i aktualnym ETag, a po każdej akcji odczytaj nowy stan. Na końcu zweryfikuj synchronizację listą filtrowaną po customId albo externalNumber.
