Problemy w Codenica API
Pracę z problemami przez Codenica API zaczynasz od utworzenia klucza w ustawieniach Codenica. Jeśli klucz nie został jeszcze utworzony, otwórz w nowej karcie Codenica API - wprowadzenie. Znajdziesz tam wspólne zasady wydawania kluczy, przechowywania sekretu i uwierzytelniania.
Techniczna nazwa modułu to problems, a typ pojedynczego obiektu to problem. Problem służy do rejestrowania przyczyny lub źródła powtarzających się incydentów. Oprócz danych opisowych ma pola diagnostyczne isKnown, symptoms, rootCause i impactInfo.
W kolejnych krokach znajdziesz adresy, zakresy, schema, listy, filtrowanie, tworzenie, edycję, ETag, batch, relacje, użytkowników, pliki, akcje workflow, eskalację, akceptację i usuwanie problemów.
Przykłady wykorzystują prefix PUBLIC-API-PROBLEM-20260905131727. W swojej integracji zastąp go własnym identyfikatorem, a adresy e-mail, identyfikatory i wartości pól dopasuj do danych w swojej bazie.
Problemy - adres API i wybór instalacji
Wszystkie trasy dotyczące problemów zaczynają się od:
{BASE_URL}/api/v1/problemsW Codenica Cloud użyj publicznej domeny przypisanej do właściwej instalacji:
export BASE_URL="https://twoja-firma.codenica.com"W domyślnej instalacji On-Premise adres lokalnie rejestrowany przez program Codenica Discovery to:
export BASE_URL="http://codenica.local:5150"Jeżeli administrator udostępnił instalację pod firmową domeną, przez reverse proxy, z HTTPS albo na innym porcie, użyj dokładnego adresu przekazanego dla tej instalacji:
export BASE_URL="https://api.twoja-firma.example"Nie używaj localhost, jeśli program integrujący działa na innym komputerze niż API. Nie przekazuj tenantId w body ani w query stringu. Właściwa baza danych jest wybierana na podstawie adresu hosta, z którym łączy się integracja.
Problemy - klucz API i limity licencyjne
Klucz API utwórz w Codenica w miejscu Ustawienia - API - API Keys. Sekret jest pokazywany tylko raz, bezpośrednio po utworzeniu albo obróceniu klucza. Zapisz wtedy Client ID i Client Secret w bezpiecznym magazynie używanym przez integrację.
Codenica API jest dostępne dla licencji Plus i Enterprise. Licencja Plus pozwala utworzyć do 50 aktywnych kluczy, a Enterprise do 100. Starter nie udostępnia Codenica API. Dla każdej aplikacji i środowiska utwórz osobny klucz, aby można było niezależnie ograniczyć jego zakresy, obrócić sekret albo usunąć dostęp.
Domyślny termin ważności klucza wynosi 90 dni, jeżeli w panelu nie ustawisz innej daty. Maksymalny termin ważności wynosi 5 lat. Klucze wygasłe lub nieaktywne nie zajmują aktywnego slotu, ale pozostają widoczne do czasu użycia opcji Usuń. Usunięcie rekordu jest trwałe.
Problemy - uwierzytelnianie i bezpieczne żądania
Każde żądanie Codenica API uwierzytelniaj dwoma nagłówkami klucza:
export CLIENT_ID="cna_twoj_client_id"
export CLIENT_SECRET="cns_twoj_client_secret"
curl --request GET --url "$BASE_URL/api/v1/problems?page=1&pageSize=25" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Zewnętrzna integracja nie potrzebuje JWT administratora ani ciasteczek z panelu Codenica. Klucza nie umieszczaj w repozytorium, kodzie dostarczanym do przeglądarki, adresie URL, historii poleceń ani logach. Poza lokalnymi testami korzystaj z HTTPS.
W odpowiedzi zachowuj meta.requestId. Jest potrzebny do diagnozowania konkretnego żądania, ale nie zastępuje identyfikatora problemu i nie powinien być używany jako sekret.
Problemy - sprawdzenie kontekstu połączenia
Przed pierwszym zapisem pobierz kontekst. Dzięki temu sprawdzisz, czy adres prowadzi do właściwej bazy, a wybrany klucz ma potrzebne zakresy:
curl --request GET --url "$BASE_URL/api/v1/context" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"W odpowiedzi zweryfikuj:
data.apiVersionidata.contractVersion;data.tenant.id,data.tenant.nameidata.tenant.resolvedDomain;data.caller.authenticationrówneapi_key;- obecność
problemswdata.capabilities.resources; - zakresy przypisane do klucza;
- limity stron, batch, plików i żądań.
Jeżeli kontekst wskazuje inną bazę albo nie zawiera wymaganego zakresu, zatrzymaj integrację i popraw adres lub klucz. Zakresów nie można nadać pojedynczym żądaniem.
Problemy - zakresy uprawnień
Pełna obsługa problemów wymaga zakresów odpowiadających wykorzystywanym operacjom:
problems:read
problems:write
problems:delete
problems:schema
problems:stats
problems:relationships:read
problems:relationships:write
problems:users:read
problems:users:write
problems:files:read
problems:files:write
problems:technical:read
problems:technical:write
problems:pin:write
problems:spam:write
problems:reopen:write
problems:rating:write
problems:escalation:write
problems:approval:writeDo zwykłego odczytu wystarczy problems:read. Schema i statystyki wymagają osobnych zakresów problems:schema oraz problems:stats. Odczyt relacji, użytkowników i plików wymaga odpowiednich zakresów odczytu. Operacje zapisu mają analogiczne zakresy :write.
Relacje z innymi modułami wymagają także odczytu wskazywanego modułu, na przykład assets:read, documents:read, tickets:read albo solutions:read. Do utworzenia i decyzji approval dodaj zakresy potrzebne dla samego modułu approvals. Przyznawaj zakresy zgodnie z zasadą najmniejszych uprawnień.
Problemy - schema i pola diagnostyczne
Schema pokazuje, które pola można odczytać i zapisać w konkretnej bazie. Pobierz je przed przygotowaniem formularza lub mapowania:
curl --request GET --url "$BASE_URL/api/v1/problems/schema" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Dla każdego pola sprawdź między innymi readable, writable, required, technical, unique oraz maxLength. Schema zwraca również słowniki oraz dostępne cele relacji.
Minimalny zapis problemu wymaga obecnie pól subject i requesterEmail. Problemy mają własną grupę diagnostyczną:
subject, requesterEmail, description, commentstype, status, priority, impact, urgency, severityisKnown, symptoms, rootCause, impactInfosource, services, tags, externalNumber, referenceNumberPola pin i isSpam są techniczne i zmienia się je przez dedykowane akcje. Pola systemowe oraz tylko do odczytu, w tym dane oceny i eskalacji, nie powinny być przesyłane w zwykłym PATCH-u. Problemy nie obsługują pól kosztowych currency, estimatedCost i totalValue znanych z innych modułów.
Problemy - podstawowe endpointy
Najczęściej używane trasy problemów są następujące:
GET /api/v1/problems- lista problemów;GET /api/v1/problems/{id}- pojedynczy problem;POST /api/v1/problems- utworzenie;PATCH /api/v1/problems/{id}- częściowa edycja;DELETE /api/v1/problems/{id}- usunięcie;GET /api/v1/problems/schema- schema pól i relacji;GET /api/v1/problems/stats- statystyki;GET /api/v1/problems/values- wartości używane w filtrach;POST /api/v1/problems:batch- operacje create, update i delete.
Relacje, użytkownicy, pliki, akcje workflow i akceptacje mają osobne trasy. Dzięki temu integracja może otrzymać tylko te uprawnienia, które są rzeczywiście potrzebne.
Problemy - listowanie i paginacja
Listę pobieraj stronicami. Nawet przy małej liczbie rekordów podaj jawnie numer strony i jej rozmiar:
curl --request GET --url "$BASE_URL/api/v1/problems?page=1&pageSize=25" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Odpowiedź zawiera data.items oraz informacje page, pageSize, totalItems, totalPages i hasNextPage. Pobieraj następne strony, dopóki hasNextPage ma wartość true:
curl --request GET --url "$BASE_URL/api/v1/problems?page=2&pageSize=25&sort=dateUpdated&direction=desc" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Do synchronizacji najwygodniej sortować po dateUpdated i zapamiętywać ostatnio przetworzone rekordy. Nie ustawiaj pageSize wyższego niż limit zwrócony w kontekście.
Problemy - wyszukiwanie, filtry i sortowanie
Parametry listy możesz łączyć. Poniższy przykład wyszukuje rekord po identyfikatorze, ogranicza wynik do typu problem i znanych problemów, a następnie sortuje go według daty aktualizacji:
curl --get --url "$BASE_URL/api/v1/problems" \
--data-urlencode "itemType=problem" \
--data-urlencode "customId=PUBLIC-API-PROBLEM-20260905131727-SOURCE" \
--data-urlencode "isKnown=true" \
--data-urlencode "sort=dateUpdated" \
--data-urlencode "direction=desc" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"W codziennej synchronizacji przydatne są również parametry search, status, priority, subject, requesterEmail, source, externalNumber, referenceNumber, symptoms, rootCause, impactInfo, createdAfter, createdBefore, updatedAfter i updatedBefore, o ile są dostępne w aktualnym schema.
Filtr strukturalny ma format field:operator:value. Dostępne operatory to eq, ne, in, contains, startsWith, endsWith, empty, notEmpty, gt, gte, lt i lte:
curl --get --url "$BASE_URL/api/v1/problems" \
--data-urlencode "filter=status:eq:Closed" \
--data-urlencode "filter=rootCause:contains:connection" \
--data-urlencode "page=1" \
--data-urlencode "pageSize=25" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Wartości tekstowe i daty koduj zgodnie z zasadami URL. Nie zakładaj, że słownik w dwóch bazach będzie identyczny.
Problemy - wybór pól i dołączanie danych
Parametr fields pozwala ograniczyć odpowiedź do pól potrzebnych integracji. Parametr include dołącza dane powiązane:
curl --get --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--data-urlencode "fields=subject,requesterEmail,status,priority,isKnown,symptoms,rootCause,impactInfo" \
--data-urlencode "include=files,relationships,users" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Przy odczycie całego modelu możesz użyć fields=*. Dołączanie plików, relacji i użytkowników wymaga odpowiednich zakresów odczytu. fields nie omija kontroli dostępu ani nie ujawnia pól technicznych, do których klucz nie ma uprawnień.
W odpowiedzi zwracaj uwagę na data.id, data.itemType, data.attributes i data.meta. Pola techniczne, takie jak pin albo isSpam, odczytuj, ale zmieniaj przez dedykowane akcje opisane dalej.
Problemy - statystyki i wartości słownikowe
Statystyki pozwalają na przykład policzyć problemy według pola isKnown. Są operacją odczytową i nie modyfikują rekordów:
curl --get --url "$BASE_URL/api/v1/problems/stats" \
--data-urlencode "field=isKnown" \
--data-urlencode "limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Wartości pola rootCause przydatne do budowy podpowiedzi lub filtrów pobierzesz osobno:
curl --get --url "$BASE_URL/api/v1/problems/values" \
--data-urlencode "field=rootCause" \
--data-urlencode "search=connection" \
--data-urlencode "limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Najpierw pobierz słownik, a dopiero potem wyślij wartość w body. Jest to szczególnie ważne dla status, priority, type i pól diagnostycznych konfigurowanych w danej bazie.
Problemy - tworzenie rekordu
Nowy problem utworzysz przez POST /api/v1/problems. W body umieść techniczny typ problem i zapisywalne pola w attributes. Przykład zawiera dane opisowe, klasyfikację, informacje integracyjne oraz pełną grupę diagnostyczną:
export IDEMPOTENCY_KEY="public-api-problem-create-20260905131727"
curl --request POST --url "$BASE_URL/api/v1/problems" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: $IDEMPOTENCY_KEY" \
--data-raw '{
"itemType": "problem",
"attributes": {
"customId": "PUBLIC-API-PROBLEM-20260905131727-SOURCE",
"subject": "Problem integracyjny Codenica API",
"requesterEmail": "[email protected]",
"description": "Problem utworzony przez integrację Codenica API.",
"comments": "Przykład diagnostyczny dla modułu Problems.",
"source": "Codenica API",
"type": "Standard",
"status": "Closed",
"priority": "High",
"impact": "Medium",
"urgency": "High",
"severity": "High",
"services": "Codenica API",
"tags": "codenica-api,problem",
"externalNumber": "EXT-CODENICA-API-PROBLEM-20260905131727",
"referenceNumber": "REF-CODENICA-API-PROBLEM-20260905131727",
"isKnown": true,
"symptoms": "Użytkownicy nie mogą zakończyć synchronizacji.",
"rootCause": "Błąd połączenia z usługą zewnętrzną.",
"impactInfo": "Synchronizacja problematycznej grupy danych jest opóźniona."
},
"customValues": [
{
"name": "description",
"valuePattern": "[problem-test] PUBLIC-API-PROBLEM-20260905131727"
}
]
}'Wymagane minimum to subject i requesterEmail, o ile schema nie nakłada dodatkowych wymagań. Udane utworzenie zwraca HTTP 201, identyfikator data.id oraz ETag w nagłówku i w data.meta.etag. Secret klucza nie jest częścią odpowiedzi obiektu.
Problemy - idempotencja tworzenia
Powtórzenie tego samego żądania z tym samym Idempotency-Key powinno zwrócić ten sam wynik logiczny, a nie utworzyć drugi problem:
curl --request POST --url "$BASE_URL/api/v1/problems" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-problem-create-20260905131727" \
--data-binary @problem.jsonTen sam klucz można bezpiecznie powtórzyć po niepewnym wyniku sieciowym tylko dla tego samego żądania. Nie używaj jednego klucza dla dwóch różnych operacji. Dla nowego body wygeneruj nowy klucz.
Idempotency-Key obowiązuje przy każdym żądaniu zmieniającym dane, także przy edycji, relacji, pliku, akcji workflow i usuwaniu. Ponowienie tego samego klucza z inną trasą lub innym body kończy się błędem konfliktu idempotencji.
Problemy - odczyt i ETag
Odczyt pojedynczego problemu z dołączonymi danymi wykonaj tak:
curl --get --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--data-urlencode "fields=*" \
--data-urlencode "include=files,relationships,users" \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Zachowaj ETag z nagłówka odpowiedzi. Wartość powinna odpowiadać data.meta.etag i meta.etag w kopercie odpowiedzi. Po każdym udanym zapisie, akcji, zmianie relacji lub operacji plikowej pobierz albo odczytaj nowy ETag.
ETag reprezentuje wersję konkretnego problemu. Nie używaj ETag-u pobranego dla jednego problemu do modyfikacji innego.
Problemy - edycja z If-Match
Edycja jest częściowa. Prześlij tylko pola, które mają zostać zmienione:
curl --request PATCH --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-update-20260905131727" \
--data-raw '{
"attributes": {
"description": "Opis zaktualizowany przez integrację.",
"status": "Closed",
"priority": "High",
"isKnown": false,
"symptoms": "Objawy po ponownej obserwacji.",
"rootCause": "Zaktualizowana analiza przyczyny.",
"impactInfo": "Wpływ po zastosowaniu obejścia."
}
}'Nie zmieniaj zwykłym PATCH-em pól tylko do odczytu, takich jak rating, dateRating, dateFeedback, dateReopened i dateEscalated. Pin, spam, reopen, rating, eskalacja i approval mają dedykowane endpointy.
Po udanej edycji otrzymasz HTTP 200 i nowy ETag. Zapisz go przed następną operacją.
Problemy - kontrola nieaktualnego If-Match
Każda mutacja poza utworzeniem wymaga aktualnego ETag-u. Brak nagłówka i nieaktualna wartość są odrzucane:
curl --request PATCH --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-problem-missing-if-match-20260905131727" \
--data-raw '{"attributes":{"isKnown":false}}'Brak If-Match zwraca HTTP 428 z kodem if_match_required. Jeżeli wyślesz starszy ETag, otrzymasz HTTP 412 z kodem if_match_failed. Odrzucone żądanie nie powinno zmienić problemu.
Po HTTP 412 pobierz rekord ponownie, odczytaj nowy ETag i dopiero wtedy zdecyduj, czy można ponowić edycję. Nie nadpisuj w ciemno zmian wykonanych przez innego użytkownika lub proces.
Problemy - operacje batch
Batch służy do obsługi wielu niezależnych pozycji. Jedno żądanie może zawierać operacje create, update i delete:
curl --request POST --url "$BASE_URL/api/v1/problems:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-problem-batch-20260905131727" \
--data-raw '{
"items": [
{
"operation": "create",
"create": {
"itemType": "problem",
"attributes": {
"customId": "PUBLIC-API-PROBLEM-20260905131727-BATCH-A",
"subject": "Problem batch A",
"requesterEmail": "[email protected]",
"source": "Codenica API",
"type": "Standard",
"status": "Open",
"priority": "Medium",
"isKnown": true,
"symptoms": "Objawy problemu A",
"rootCause": "Przyczyna problemu A",
"impactInfo": "Wpływ problemu A"
}
}
},
{
"operation": "update",
"id": "PROBLEM_UUID",
"ifMatch": "\"CURRENT_ETAG\"",
"update": {
"attributes": {
"isKnown": false,
"rootCause": "Nowa analiza przyczyny"
}
}
},
{
"operation": "delete",
"id": "OTHER_PROBLEM_UUID",
"ifMatch": "\"OTHER_CURRENT_ETAG\""
}
]
}'W batch update i delete użyj ETag-u konkretnego rekordu. Klucz idempotencji identyfikuje całe żądanie batch, a nie pojedynczy element. Odpowiedź sprawdź element po elemencie, według indeksu, statusu, identyfikatora i błędu. Pełne powodzenie zwykle zwraca HTTP 200, a wynik częściowy HTTP 207 Multi-Status. Batch nie jest transakcją all-or-nothing.
Problemy - relacje z obiektami
Dostępne cele relacji są zwracane przez /api/v1/problems/schema. W aktualnym kontrakcie mogą obejmować:
assets
documents
changes
tickets
problems
solutions
releases
notes
approvals
worktasks
requesteditemsObecność celu w schema nie oznacza, że w konkretnej bazie istnieje rekord dostępny dla użytkownika. Przed dodaniem relacji sprawdź identyfikator, targetDataSet, targetItemType i uprawnienia do odczytu celu.
Dla assets, documents, problems, changes, tickets, solutions i releases użyj relationshipType zgodnego ze schema, na przykład related. Dla notes, approvals, worktasks i requesteditems pozostaw relationshipType równe null. Nie wpisuj related na siłę.
Dodanie kilku relacji:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/relationships:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-relationships-20260905131727" \
--data-raw '{
"add": [
{
"targetId": "ASSET_UUID",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
},
{
"targetId": "DOCUMENT_UUID",
"targetDataSet": "documents",
"targetItemType": "invoice",
"relationshipType": "related"
},
{
"targetId": "NOTE_UUID",
"targetDataSet": "notes",
"targetItemType": "note",
"relationshipType": null
}
],
"remove": []
}'Odpowiedź HTTP 200 zawiera liczniki added, removed i skipped. skipped nie jest błędem transportowym, dlatego po operacji pobierz kolekcję relacji i sprawdź jej zawartość.
Problemy - odczyt i usuwanie relacji
Listę relacji pobierzesz tak:
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/relationships?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Pojedynczą relację usuń z aktualnym ETag-em źródłowego problemu. Dla celu przechowującego relationshipType podaj go w query stringu:
curl --request DELETE --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/relationships/tickets/{TICKET_ID}?relationshipType=related" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-relationship-delete-20260905131727"Przy celu takim jak notes, dla którego schema wskazuje brak typu relacji, pomiń parametr relationshipType. Relację można również usunąć przez częściową edycję:
curl --request PATCH --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-relationship-patch-20260905131727" \
--data-raw '{
"relationshipsToRemove": [
{
"targetId": "TICKET_UUID",
"targetDataSet": "tickets",
"targetItemType": "ticket",
"relationshipType": "related"
}
]
}'Usunięcie relacji nie usuwa rekordu, który był jej celem. Po każdej zmianie pobierz kolekcję ponownie i zapisz nowy ETag problemu.
Problemy - relacje z użytkownikami
Problem może mieć następujące relacje użytkownika:
agent- osoba odpowiedzialna za obsługę;watcher- obserwator;appUserRequester- użytkownik aplikacyjny zgłaszający problem.
Dla Problems nie zakładaj relacji clientRequester. Cele są aktywnymi użytkownikami i podlegają kontroli lokalizacji oraz działu.
Przypisanie agenta:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/user-relationships" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-agent-20260905131727" \
--data-raw '{
"targetId": "USER_UUID",
"targetDataSet": "users",
"relationshipType": "agent"
}'Dodanie obserwatora przez batch:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/user-relationships:batch" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-watcher-20260905131727" \
--data-raw '{
"add": [
{
"targetId": "WATCHER_USER_UUID",
"targetDataSet": "users",
"relationshipType": "watcher"
}
],
"remove": []
}'Odczyt i usunięcie relacji:
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/user-relationships?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request DELETE --url "$BASE_URL/api/v1/problems/{PROBLEM_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: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-agent-delete-20260905131727"Obserwatora można także usunąć przez batch z pustym add i wpisem w remove. Po każdej zmianie odczytaj nowy ETag.
Problemy - pliki
Przed operacją na pliku odczytaj aktualny problem i jego ETag. Wysłanie pliku wymaga żądania multipart/form-data:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files?relationshipType=documentation" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-file-one-20260905131727" \
--form "[email protected];type=text/plain"Lista plików:
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Element listy zawiera między innymi id, name, fileName, contentType, size, relationshipType, isMain oraz downloadUrl. downloadUrl należy traktować jako ścieżkę API, a nie jako publiczny, anonimowy link. W Problems isMain jest zawsze równe false.
Pobranie treści zapisuje odpowiedź jako dane binarne:
curl --request GET --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files/{FILE_ID}/content" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output problem-evidence.txtIstniejący plik możesz dołączyć do innego problemu. ETag dotyczy wtedy problemu docelowego:
curl --request POST --url "$BASE_URL/api/v1/problems/{OTHER_PROBLEM_ID}/files/{FILE_ID}?relationshipType=manual" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $OTHER_PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-file-attach-20260905131727"Usunięcie pliku:
curl --request DELETE --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/files/{FILE_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-file-delete-20260905131727"Limit rozmiaru pliku odczytaj z context przed uploadem. Nie przyjmuj dużego pliku do pamięci bez wcześniejszego sprawdzenia limitu.
Problemy - przypięcie, spam i ponowne otwarcie
Przypięcie, oznaczenie spamu i ponowne otwarcie są osobnymi akcjami. Każda akcja wymaga bieżącego ETag-u oraz nowego klucza idempotencji.
Przypięcie problemu:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/pin" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-pin-20260905131727" \
--data-raw '{"pin":2}'Wartość pin może być liczbą od 0 do 3 albo null, zgodnie ze schema. Oznaczenie jako spam i cofnięcie oznaczenia:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/spam" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-spam-on-20260905131727" \
--data-raw '{"isSpam":true}'
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/spam" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-spam-off-20260905131727" \
--data-raw '{"isSpam":false}'Ponowne otwarcie zamkniętego problemu:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/reopen" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-reopen-20260905131727"Potrzebne zakresy to odpowiednio problems:pin:write, problems:spam:write i problems:reopen:write. Po każdej akcji pobierz problem ponownie i zapisz nowy ETag.
Problemy - ocena i eskalacja
Ocenę zapisuje się przez osobny endpoint. Możesz dołączyć do niej prośbę o eskalację:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/rating" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-rating-20260905131727" \
--data-raw '{
"rating": 4,
"feedback": "Ocena z integracji Codenica API.",
"isEscalationRequested": true,
"escalationRequestReason": "Problem wymaga analizy zespołu drugiej linii."
}'Ocena ma wartość od 0 do 5 i wymaga zakresu problems:rating:write. Dołączenie żądania eskalacji wymaga dodatkowo problems:escalation:write oraz odpowiedniego uprawnienia użytkownika. Jeżeli zapisujesz tylko ocenę, pomiń pola eskalacji. Po zapisaniu odczytaj między innymi rating, feedback, daty oceny i escalationRequestReason.
Problemy - akceptacja i decyzja
Akceptację możesz utworzyć jako osobny obiekt approval i połączyć ją z problemem relacją. Osoba wskazana w approverId musi mieć prawo do podjęcia decyzji:
curl --request POST --url "$BASE_URL/api/v1/approvals" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-problem-approval-create-20260905131727" \
--data-raw '{
"itemType": "approval",
"approverId": "APPROVER_USER_UUID",
"attributes": {
"customId": "PUBLIC-API-PROBLEM-20260905131727-APPROVAL",
"category": "Codenica API",
"description": "Akceptacja analizy problemu."
},
"relationships": [
{
"targetId": "PROBLEM_UUID",
"targetDataSet": "problems",
"targetItemType": "problem"
}
]
}'Po utworzeniu odczytaj approval, a decyzję zapisz trasą problemu. APPROVAL_ID jest identyfikatorem akceptacji, nie użytkownika:
curl --request POST --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}/approvals/{APPROVAL_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-approval-decision-20260905131727" \
--data-raw '{
"approve": true,
"remark": "Zaakceptowano przez integrację Codenica API."
}'Odrzucenie wykonuje się z approve równym false i własnym komentarzem. Po decyzji odczytaj approval ponownie i sprawdź jego status albo datę decyzji. Następnie odśwież problem, ponieważ decyzja może zmienić jego ETag i stan procesu.
Problemy - usuwanie rekordu
Przed usunięciem pobierz problem ponownie i użyj aktualnego ETag-u:
curl --request DELETE --url "$BASE_URL/api/v1/problems/{PROBLEM_ID}" \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "If-Match: $PROBLEM_ETAG" \
--header "Idempotency-Key: public-api-problem-delete-20260905131727"Po HTTP 200 wykonaj kontrolny GET tego samego UUID-u. Oczekuj HTTP 404 z kodem problem_not_found albo odpowiednim kodem wskazanym w kontrakcie. Jeżeli problem ma relacje, pliki lub approval, przed operacją sprawdź konsekwencje w schema i wymaganiach swojej bazy.
Usunięcie problemu nie powinno zastępować archiwizacji historii. Jeżeli rekord ma pozostać w dokumentacji, zmień jego status albo przenieś dane do systemu przeznaczonego do przechowywania historii.
Problemy - błędy, limity i bezpieczeństwo
Błędy zwracane są w formacie application/problem+json. Przykładowa odpowiedź:
{
"type": "https://docs.codenica.com/errors/problem_not_found",
"title": "Problem not found.",
"status": 404,
"detail": "The problem does not exist or is outside the caller's access scope.",
"instance": "/api/v1/problems/PROBLEM_UUID",
"code": "problem_not_found",
"requestId": "request-id-from-response"
}W logice integracji używaj przede wszystkim status i code. Pole detail jest informacją dla człowieka i może zmienić treść.
Odczytuj nagłówki X-RateLimit-Limit i X-RateLimit-Remaining. Po 429 zastosuj opóźnienie narastające i respektuj ewentualny Retry-After. W logach zapisuj metodę, endpoint, status i requestId, ale nigdy Client Secret ani pełnych nagłówków uwierzytelniających.
Dane problemów mogą zawierać informacje operacyjne, osobowe i diagnostyczne. Minimalizuj zakres pól, stosuj HTTPS i ogranicz dostęp integracji do konkretnej bazy danych.
Problemy - kolejność pracy integracji
- Ustaw
BASE_URLdla właściwej instalacji Cloud albo On-Premise. - Utwórz osobny klucz w Ustawienia - API - API Keys i wybierz minimalne zakresy.
- Umieść Client ID i Client Secret w bezpiecznym magazynie.
- Wyślij
GET /api/v1/contexti sprawdź bazę, caller oraz limity. - Pobierz
GET /api/v1/problems/schemai zbuduj mapowanie pól diagnostycznych. - Pobierz listę problemów albo utwórz nowy przez
POSTz unikalnymIdempotency-Key. - Zapisz UUID problemu i jego ETag.
- Przed każdą mutacją odśwież ETag i użyj nowego klucza idempotencji.
- Dodawaj relacje, użytkowników i pliki dopiero po sprawdzeniu celów w schema.
- Wykonuj pin, spam, rating, eskalację, reopen i decyzje approval jako osobne operacje.
- Przy
412pobierz rekord, rozstrzygnij konflikt i świadomie ponów operację. - Przy batch sprawdź wynik każdej pozycji, ponieważ częściowy błąd nie musi cofnąć sukcesów.
- Obsłuż
429, zapisujrequestIdbez sekretów i usuń klucz, gdy integracja przestaje być używana. - Przed usunięciem potwierdź aktualny ETag, a po operacji sprawdź HTTP
404.
Tak przygotowany przepływ pozwala synchronizować problemy i ich analizę z innym systemem bez opierania integracji na wewnętrznej strukturze bazy. Jeśli zmieni się konfiguracja pól, adres instalacji lub zakresy klucza, ponownie odczytaj kontekst i schema.
