Wydania w Codenica API
Pracę z wydaniami przez Codenica API zacznij 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 releases, a typ pojedynczego obiektu to release. Wydanie służy do opisania planowanej publikacji lub wdrożenia zmian w środowisku IT. Oprócz danych opisowych ma własną grupę pól planowania budowania, testów, wyników i wdrożenia.
W kolejnych krokach znajdziesz adresy, zakresy, schema, listy, filtrowanie, tworzenie, edycję, ETag, batch, relacje, użytkowników, pliki, akcje workflow, akceptację i usuwanie wydań.
Przykłady wykorzystują identyfikator PUBLIC-API-RELEASE-20260905133117. 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.
Wydania - adres API i wybór instalacji
Wszystkie trasy dotyczące wydań zaczynają się od:
{BASE_URL}/api/v1/releasesW Codenica Cloud użyj publicznego adresu przypisanego do właściwej bazy danych:
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, z którym łączy się integracja.
Wydania - 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.
Klucze wygasłe lub nieaktywne pozostają widoczne do czasu użycia opcji Usuń, ale nie zajmują aktywnego miejsca w limicie. Usunięcie klucza jest trwałe. Jeżeli nie ustawisz daty końcowej, domyślny okres aktywności wynosi 90 dni, a maksymalny czas aktywności jednego klucza to 5 lat.
Wydania - 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/releases?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 wydania i nie powinien być używany jako sekret.
Wydania - 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ść
releaseswdata.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.
Wydania - zakresy uprawnień
Zakresy klucza dobierz do operacji, które ma wykonywać integracja. Pełna obsługa wydań może korzystać z następującego zestawu:
releases:read
releases:write
releases:delete
releases:schema
releases:stats
releases:relationships:read
releases:relationships:write
releases:users:read
releases:users:write
releases:files:read
releases:files:write
releases:technical:read
releases:technical:write
releases:pin:write
releases:spam:write
releases:reopen:write
releases:rating:write
releases:escalation:write
releases:approval:writeDo zwykłego odczytu potrzebujesz releases:read. Schema i statystyki wymagają odpowiednio releases:schema oraz releases:stats. Relacje, użytkownicy i pliki mają osobne zakresy odczytu i zapisu. Akcje pin, spam, reopen, rating, eskalacja i approval wymagają swoich zakresów operacyjnych.
Relacja z innym obiektem wymaga również odczytu wskazywanego modułu, na przykład assets:read, documents:read, tickets:read albo notes:read. Przyznawaj zakresy zgodnie z zasadą najmniejszych uprawnień.
Wydania - schema i pola planowania
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/releases/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, dostępne cele relacji i akcje.
Minimalny zapis wydania wymaga obecnie pól subject i requesterEmail. Wydania mają dodatkową grupę pól opisujących plan przygotowania i wdrożenia:
datePlannedStartdatePlannedEndbuildPlantestPlantestResultsimplementationPlanPola dat przekazuj w formacie ISO 8601. Nie przenoś do żądania Wydania pól diagnostycznych z problems ani pól finansowych z innych modułów. Zawsze porównaj payload ze schema Releases.
Wydania - podstawowe endpointy
Najczęściej używane trasy wydań są następujące:
GET /api/v1/releases- lista wydań;GET /api/v1/releases/{id}- pojedyncze wydanie;POST /api/v1/releases- utworzenie;PATCH /api/v1/releases/{id}- częściowa edycja;DELETE /api/v1/releases/{id}- usunięcie;GET /api/v1/releases/schema- schema pól i relacji;GET /api/v1/releases/stats- statystyki;GET /api/v1/releases/values- wartości używane w filtrach;POST /api/v1/releases: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.
Wydania - 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/releases?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/releases?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.
Wydania - wyszukiwanie, filtry i sortowanie
Parametry listy możesz łączyć. Poniższy przykład wyszukuje konkretne wydanie po identyfikatorze, ogranicza wynik do typu release, statusu i wybranych pól, a następnie sortuje go według daty aktualizacji:
curl --get --url "$BASE_URL/api/v1/releases" \
--data-urlencode "itemType=release" \
--data-urlencode "customId=PUBLIC-API-RELEASE-20260905133117-SOURCE" \
--data-urlencode "status=Closed" \
--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, 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/releases" \
--data-urlencode "filter=status:eq:Closed" \
--data-urlencode "filter=buildPlan:contains:pakiet" \
--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.
Wydania - 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/releases/{RELEASE_ID}" \
--data-urlencode "fields=subject,requesterEmail,status,priority,datePlannedStart,datePlannedEnd,buildPlan,testPlan,testResults,implementationPlan" \
--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.
Wydania - statystyki i wartości słownikowe
Statystyki pozwalają na przykład sprawdzić rozkład wydań według statusu. Są operacją odczytową i nie modyfikują rekordów:
curl --get --url "$BASE_URL/api/v1/releases/stats" \
--data-urlencode "field=status" \
--data-urlencode "limit=20" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Wartości pola buildPlan przydatne do budowy podpowiedzi lub filtrów pobierzesz osobno:
curl --get --url "$BASE_URL/api/v1/releases/values" \
--data-urlencode "field=buildPlan" \
--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 planowania konfigurowanych w danej bazie.
Wydania - tworzenie rekordu
Nowe wydanie utworzysz przez POST /api/v1/releases. W body umieść techniczny typ release i zapisywalne pola w attributes. Poniższy przykład zawiera dane opisowe, klasyfikację, identyfikatory integracji oraz całą grupę pól planowania:
curl --request POST --url "$BASE_URL/api/v1/releases" \
--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: public-api-release-create-20260905133117" \
--data-raw '{
"itemType": "release",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-SOURCE",
"subject": "Wydanie integracyjne Public API",
"requesterEmail": "[email protected]",
"description": "Wydanie utworzone przez integrację Codenica Public API.",
"comments": "Przykład planu wdrożenia dla modułu Wydania.",
"source": "Public API",
"type": "Standard",
"status": "Closed",
"priority": "High",
"impact": "Medium",
"urgency": "High",
"severity": "High",
"services": "Codenica Public API",
"tags": "public-api,release",
"externalNumber": "EXT-PUBLIC-API-RELEASE-20260905133117",
"referenceNumber": "REF-PUBLIC-API-RELEASE-20260905133117",
"datePlannedStart": "2026-09-05T08:00:00Z",
"datePlannedEnd": "2026-09-05T10:00:00Z",
"buildPlan": "Przygotowanie pakietu wydania.",
"testPlan": "Testy funkcjonalne przed publikacją.",
"testResults": "Testy demonstracyjne zakończone pozytywnie.",
"implementationPlan": "Wdrożenie etapowe z możliwością wycofania."
},
"customValues": [
{
"name": "description",
"valuePattern": "[release-integration] PUBLIC-API-RELEASE-20260905133117"
}
]
}'Wymagane minimum to subject i requesterEmail, o ile schema nie nakłada dodatkowych wymagań. Po utworzeniu zapisz data.id oraz ETag zwrócony w nagłówku i w data.meta.etag. Sekret klucza nie jest częścią odpowiedzi wydania.
Wydania - bezpieczne ponawianie tworzenia
Jeżeli wynik żądania jest niepewny, powtórz dokładnie ten sam payload z tym samym Idempotency-Key. Dzięki temu integracja nie utworzy drugiego wydania:
curl --request POST --url "$BASE_URL/api/v1/releases" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header "Idempotency-Key: public-api-release-create-20260905133117" \
--data-binary @release.jsonTen sam klucz można powtórzyć tylko dla tej samej intencji i tego samego body. Dla nowego wydania albo nowego payloadu wygeneruj nowy klucz. Nie zmieniaj klucza po timeout, zanim nie sprawdzisz, czy pierwszy zapis zakończył się po stronie serwera.
Wydania - odczyt i ETag
Odczyt pojedynczego wydania z pełnym zestawem pól i danych dołączonych:
curl --get --url "$BASE_URL/api/v1/releases/{RELEASE_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 wydania. Nie używaj ETag-u pobranego dla jednego wydania do modyfikacji innego.
Wydania - edycja z If-Match
Edycja jest częściowa. Prześlij tylko pola, które mają zostać zmienione, i użyj aktualnego ETag-u w nagłówku If-Match:
curl --request PATCH --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-update-20260905133117" \
--data-raw '{
"attributes": {
"description": "Opis zaktualizowany przez integrację.",
"status": "Closed",
"priority": "High",
"datePlannedStart": "2026-09-05T09:00:00Z",
"datePlannedEnd": "2026-09-05T11:00:00Z",
"buildPlan": "Zaktualizowany plan przygotowania.",
"testPlan": "Zaktualizowany scenariusz testów.",
"testResults": "Wyniki testów po poprawce.",
"implementationPlan": "Zaktualizowany plan wdrożenia."
}
}'Prawidłowa wartość If-Match daje HTTP 200 i nowy ETag. Nie wysyłaj w zwykłym PATCH-u pól tylko do odczytu ani pól technicznych obsługiwanych przez dedykowane akcje.
Wydania - kontrola nieaktualnego If-Match
Wydanie może być równocześnie zmieniane przez panel lub inną integrację. API chroni je przed przypadkowym nadpisaniem:
curl --request PATCH --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "stary-etag"' \
--header "Idempotency-Key: public-api-release-stale-update-20260905133117" \
--data-raw '{"attributes":{"description":"Ta zmiana wymaga ponownego odczytu."}}'- 428 Precondition Required z kodem
if_match_requiredoznacza brak wymaganego nagłówkaIf-Match. - 412 Precondition Failed z kodem
if_match_failedoznacza, że użyta wartość ETag nie jest już aktualna.
Odrzucone żądanie nie powinno zmienić wydania. Po HTTP 412 pobierz rekord ponownie, odczytaj nowy ETag i zdecyduj, czy chcesz ponowić zmianę. Nie nadpisuj w ciemno zmian wykonanych przez inną osobę lub proces.
Wydania - operacje batch
Endpoint batch służy do obsługi wielu niezależnych pozycji w jednym żądaniu. Poniższy przykład tworzy dwa wydania:
curl --request POST --url "$BASE_URL/api/v1/releases:batch" \
--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: public-api-release-batch-create-20260905133117" \
--data-raw '{
"items": [
{
"operation": "create",
"create": {
"itemType": "release",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-BATCH-A",
"subject": "Wydanie batch A",
"requesterEmail": "[email protected]",
"source": "Public API",
"type": "Standard",
"status": "Open",
"priority": "Medium",
"datePlannedStart": "2026-09-05T11:00:00Z",
"datePlannedEnd": "2026-09-05T12:00:00Z",
"buildPlan": "Plan budowania wydania A",
"testPlan": "Plan testów wydania A",
"testResults": "Wyniki testów wydania A",
"implementationPlan": "Plan wdrożenia wydania A"
}
}
},
{
"operation": "create",
"create": {
"itemType": "release",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-BATCH-B",
"subject": "Wydanie batch B",
"requesterEmail": "[email protected]",
"source": "Public API",
"type": "Standard",
"status": "Open",
"priority": "Low",
"datePlannedStart": "2026-09-05T13:00:00Z",
"datePlannedEnd": "2026-09-05T14:00:00Z",
"buildPlan": "Plan budowania wydania B",
"testPlan": "Plan testów wydania B",
"testResults": "Wyniki testów wydania B",
"implementationPlan": "Plan wdrożenia wydania B"
}
}
}
]
}'Odpowiedź batch należy sprawdzić element po elemencie. Nie traktuj HTTP 200 jako dowodu, że każda pozycja zakończyła się sukcesem. Sprawdź succeeded, failed, identyfikatory i błędy poszczególnych pozycji.
Aktualizacja i usuwanie korzystają z tego samego endpointu:
{
"items": [
{
"operation": "update",
"id": "{RELEASE_ID}",
"ifMatch": "\"{CURRENT_ETAG}\"",
"update": {
"attributes": {
"datePlannedStart": "2026-09-05T09:30:00Z",
"buildPlan": "Zaktualizowany plan przygotowania"
}
}
},
{
"operation": "delete",
"id": "{OTHER_RELEASE_ID}",
"ifMatch": "\"{OTHER_CURRENT_ETAG}\""
}
]
}Przy update i delete użyj ETag-u pobranego dla konkretnego rekordu. Klucz idempotencji identyfikuje całe żądanie batch, a nie pojedynczy element. Batch nie jest transakcją, dlatego obsłuż wynik każdego elementu osobno.
Wydania - relacje z obiektami
Dostępne cele relacji są zwracane przez /api/v1/releases/schema. Schema może wskazać między innymi zbiory assets, documents, changes, tickets, problems, releases, notes, approvals, worktasks i requesteditems.
To, że cel znajduje się w schema, nie oznacza, że w konkretnej bazie istnieje dostępny rekord do połączenia. Przed dodaniem relacji sprawdź uprawnienia, identyfikator celu i jego itemType. Dla assets, documents, tickets, changes, problems i releases użyj typu relacji wskazanego przez schema, na przykład related. Dla notes, approvals, worktasks i requesteditems wartość relationshipType może być null. Nie wpisuj related na siłę.
Dodanie kilku relacji przez batch:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_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: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-batch-20260905133117" \
--data-raw '{
"add": [
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer",
"relationshipType": "related"
},
{
"targetId": "{DOCUMENT_ID}",
"targetDataSet": "documents",
"targetItemType": "document",
"relationshipType": "related"
},
{
"targetId": "{NOTE_ID}",
"targetDataSet": "notes",
"targetItemType": "note",
"relationshipType": null
}
],
"remove": []
}'Odpowiedź HTTP 200 zawiera liczniki added, removed i skipped. Po operacji pobierz kolekcję relacji i sprawdź, czy wynik odpowiada oczekiwaniu.
Wydania - odczyt i usuwanie relacji
Kolekcję relacji pobierzesz osobną trasą:
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/relationships?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"Pojedynczą relację możesz dodać bez batch, a następnie usunąć po aktualnym ETag-u:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/relationships" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-20260905133117" \
--data-raw '{"targetId":"{TICKET_ID}","targetDataSet":"tickets","targetItemType":"ticket","relationshipType":"related"}'
curl --request DELETE --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/relationships/tickets/{TICKET_ID}?relationshipType=related" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-delete-20260905133117"Jeżeli schema zwraca dla celu relationshipType: null, pomiń parametr relationshipType w trasie usuwania. Relacje można także usunąć przez częściową edycję wydania:
curl --request PATCH --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-relationship-patch-20260905133117" \
--data-raw '{"relationshipsToRemove":[{"targetId":"{TICKET_ID}","targetDataSet":"tickets","targetItemType":"ticket","relationshipType":"related"}]}'Po zmianie relacji pobierz wydanie lub kolekcję relacji ponownie. ETag może się zmienić, dlatego stary ETag nie powinien być używany do następnej akcji.
Wydania - relacje z użytkownikami
Wydanie może mieć relacje użytkownika agent, watcher i appUserRequester. Pierwsza oznacza osobę odpowiedzialną za obsługę, druga obserwatora, a trzecia użytkownika aplikacyjnego zgłaszającego wydanie. Nie dopisuj automatycznie relacji, których nie zwraca schema.
Przypisanie agenta:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_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: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-agent-20260905133117" \
--data-raw '{"targetId":"{USER_ID}","targetDataSet":"users","relationshipType":"agent"}'Dodanie obserwatora przez batch:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_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: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-watcher-20260905133117" \
--data-raw '{"add":[{"targetId":"{WATCHER_ID}","targetDataSet":"users","relationshipType":"watcher"}],"remove":[]}'Odczyt i usunięcie relacji:
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_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/releases/{RELEASE_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: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-agent-delete-20260905133117"Usunięcie watchera może również użyć user-relationships:batch z pustą tablicą add i wpisem w remove. Po każdej zmianie odczytaj nowy ETag.
Wydania - pliki
Przed operacją na pliku odczytaj aktualne wydanie i jego ETag. Wysłanie pliku wymaga formatu multipart/form-data:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files?relationshipType=documentation" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-file-20260905133117" \
--form "[email protected];type=text/plain"Lista plików i pobranie treści:
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files?page=1&pageSize=100" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET"
curl --request GET --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files/{FILE_ID}/content" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--output release-evidence.txtElement listy zawiera między innymi id, name, fileName, contentType, size, relationshipType, isMain oraz downloadUrl. downloadUrl traktuj jako ścieżkę API, a nie jako publiczny, anonimowy link.
Istniejący plik możesz podpiąć do innego wydania, a następnie usunąć jego powiązanie:
curl --request POST --url "$BASE_URL/api/v1/releases/{OTHER_RELEASE_ID}/files/{FILE_ID}?relationshipType=manual" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{OTHER_RELEASE_CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-file-attach-20260905133117"
curl --request DELETE --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/files/{FILE_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-file-delete-20260905133117"Przed usunięciem zweryfikuj wydanie, fileId i aktualny ETag. Limit rozmiaru pobierz z context. Nie przyjmuj pliku do pamięci bez sprawdzenia limitu.
Wydania - przypięcie, spam i ponowne otwarcie
Akcje workflow są osobnymi endpointami. Nie zastępuj ich zwykłym PATCH-em, jeśli API udostępnia dedykowaną akcję. Każda z nich wymaga aktualnego ETag-u oraz własnego klucza idempotencji.
Przypięcie wydania i oznaczenie go jako spam:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/pin" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-pin-20260905133117" \
--data-raw '{"pin":2}'
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/spam" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-spam-on-20260905133117" \
--data-raw '{"isSpam":true}'Oznaczenie można cofnąć, wysyłając {"isSpam":false} na tę samą trasę. Ponowne otwarcie wydania wykonaj tak:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/reopen" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-reopen-20260905133117"Akcje mogą zmienić ETag. Po każdej akcji odczytaj odpowiedź oraz aktualne wydanie przed wykonaniem następnej.
Wydania - ocena i eskalacja
Ocena może jednocześnie przekazać informację zwrotną i zarejestrować prośbę o eskalację:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_ID}/rating" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-rating-20260905133117" \
--data-raw '{
"rating": 4,
"feedback": "Ocena z integracji Public API.",
"isEscalationRequested": true,
"escalationRequestReason": "Wydanie wymaga analizy zespołu drugiej linii."
}'Do samej oceny potrzebujesz releases:rating:write, a do zgłoszenia eskalacji także releases:escalation:write. Po operacji odczytaj wydanie ponownie i sprawdź zapisane pola oceny oraz eskalacji. Nie zakładaj, że sam HTTP 200 oznacza zapis wszystkich wartości.
Wydania - akceptacja i decyzja
Akceptacja jest osobnym obiektem, który można powiązać z wydaniem. Utworzenie akceptacji wymaga zakresów właściwych dla modułu approvals oraz zakresu releases:approval:write:
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-release-approval-create-20260905133117" \
--data-raw '{
"itemType": "approval",
"approverId": "{APPROVER_USER_ID}",
"attributes": {
"customId": "PUBLIC-API-RELEASE-20260905133117-APPROVAL",
"category": "Public API",
"description": "Akceptacja planu wydania."
},
"relationships": [
{
"targetId": "{RELEASE_ID}",
"targetDataSet": "releases",
"targetItemType": "release"
}
]
}'Po utworzeniu odczytaj akceptację przez jej endpoint, a następnie zapisz decyzję przez endpoint wydania:
curl --request POST --url "$BASE_URL/api/v1/releases/{RELEASE_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: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-approval-decision-20260905133117" \
--data-raw '{"approve":true,"remark":"Plan wydania zaakceptowano przez integrację Public API."}'Po decyzji pobierz akceptację ponownie i sprawdź jej status lub dateApproved. W ten sposób potwierdzisz zapis decyzji, a nie tylko poprawne przyjęcie żądania przez serwer.
Wydania - usuwanie rekordu
Usunięcie wymaga aktualnego ETag-u i klucza idempotencji:
curl --request DELETE --url "$BASE_URL/api/v1/releases/{RELEASE_ID}" \
--header "X-Codenica-Client-Id: $CLIENT_ID" \
--header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
--header 'If-Match: "{CURRENT_ETAG}"' \
--header "Idempotency-Key: public-api-release-delete-20260905133117"Po HTTP 200 wykonaj kontrolny GET. Usunięte wydanie powinno zwrócić HTTP 404 z kodem release_not_found albo odpowiednikiem wskazanym w kontrakcie. Jeżeli obiekt ma relacje lub pliki, przed usunięciem sprawdź konsekwencje w schema i polityce swojej bazy.
Wydania - błędy, limity i bezpieczeństwo
Udane odpowiedzi zwracają dane w polu data, a informacje techniczne, takie jak requestId i czasem ETag, w polu meta. Błędy używają formatu Problem Details z polami status, code, detail i requestId.
400- nieprawidłowe body, parametr lub wartość pola;401- brak lub nieprawidłowe uwierzytelnienie;403- brak zakresu albo dostępu do bazy;404- wydanie, plik lub cel relacji nie istnieje albo jest niewidoczny;409- konflikt danych lub idempotencji;412- nieaktualny ETag;413- zbyt duży upload lub body;428- wymagany ETag albo Idempotency-Key;429- przekroczony limit żądań;500lub503- błąd serwera albo chwilowa niedostępność.
Respektuj limity zwrócone w context: pageSize, batch, plików, relacji i rate limitu. Odczytuj X-RateLimit-Limit, X-RateLimit-Remaining oraz, przy 429, Retry-After. Stosuj kontrolowane ponowienia z rosnącym opóźnieniem.
Dla operacji zmieniających dane zawsze używaj unikalnego Idempotency-Key, aktualnego If-Match, gdy endpoint go wymaga, i nowego ETag-u po udanej zmianie. Po timeout najpierw odtwórz wynik przez GET albo powtórz to samo żądanie z tym samym kluczem. Client ID i Client Secret przechowuj poza kodem źródłowym, nie zapisuj ich w logach i nie wysyłaj w rozmowach ani zgłoszeniach.
Wydania - kolejność pracy integracji
- Ustal właściwy adres Cloud albo rzeczywisty adres On-Premise instalacji.
- Utwórz osobny klucz dla aplikacji i środowiska w Ustawienia - API - API Keys.
- Nadaj tylko zakresy potrzebne dla wydań i planowanych relacji.
- Wyślij
GET /api/v1/contexti sprawdź bazę, caller, zakresy oraz limity. - Pobierz
GET /api/v1/releases/schemai zbuduj mapowanie pól. - Pobierz listę z paginacją, wyszukiwaniem lub filtrami.
- Utwórz wydanie przez
POSTz nowymIdempotency-Key. - Zapisz UUID i ETag.
- Przed każdą zmianą odczytaj aktualny rekord i jego ETag.
- Wykonuj edycję, relacje, operacje plikowe i akcje workflow z konkretnym ETag-em oraz nowym kluczem idempotencji.
- Po każdej udanej mutacji zapisz nowy ETag i odczytaj wynik ponownie.
- Po
412odczytaj rekord, rozstrzygnij konflikt i dopiero wtedy ponów operację. - Przy większej liczbie zmian użyj batch, ale sprawdź status każdego elementu, ponieważ batch nie jest transakcją.
- Przy akceptacji sprawdź stan akceptacji po decyzji.
- Przy usuwaniu użyj aktualnego ETag-u i potwierdź późniejszym GET-em HTTP 404.
Taki przebieg pozwala synchronizować planowanie i wdrażanie wydań bez opierania integracji na przypadkowych założeniach o polach, relacjach lub adresie instalacji.
