Zadania w Codenica API
Zanim wyślesz pierwsze żądanie dotyczące zadań, utwórz klucz w ustawieniach swojej instalacji. Jeżeli nie masz jeszcze klucza, otwórz w nowej karcie stronę Codenica API - wprowadzenie. Znajdziesz tam wspólne zasady tworzenia kluczy, uwierzytelniania, obsługi adresu API i bezpiecznego przechowywania sekretu.
Zadanie służy do zapisania konkretnej czynności, obowiązku albo pracy do wykonania. W jednym rekordzie możesz przechować termin, status, priorytet, kategorię, opis, miejsce, dział, odnośnik i tagi. Zadanie może być także powiązane z innymi obiektami używanymi w pracy Service Desk i zarządzaniu zasobami.
W technicznym kontrakcie API pojedynczy rekord ma wartość itemType równą worktask, a kolekcja endpointów nosi nazwę worktasks. Przykłady zawierają bezpieczne wartości demonstracyjne. Identyfikatory, adresy i daty zastąp danymi własnej integracji.
Zadania - adres API i wybór instalacji
Wszystkie trasy dotyczące zadań zaczynają się od adresu:
{BASE_URL}/api/v1/worktasksBASE_URL oznacza adres aplikacji Codenica bez końcówki /api/v1. Do adresu nie dopisuj nazwy bazy danych ani identyfikatora firmy.
Codenica Cloud: użyj domeny lub subdomeny przypisanej do firmy:
export BASE_URL="https://{domena-twojej-firmy}"Codenica On-Premise: domyślny adres rejestrowany lokalnie przez Codenica Discovery to:
export BASE_URL="http://codenica.local:5150"Jeżeli administrator udostępnił instalację przez firmową domenę, HTTPS, reverse proxy albo na innym porcie, użyj dokładnego adresu przekazanego dla tej instalacji. Szczegóły wdrożenia znajdziesz w instrukcji instalacji Codenica On-Premise. Adres localhost stosuj tylko w świadomym lokalnym środowisku testowym, gdy klient HTTP i API działają na tym samym komputerze.
Nie przesyłaj tenantId w body ani w parametrach URL. Właściwa baza danych jest wybierana na podstawie adresu i hosta żądania.
Zadania - klucz API i limity licencyjne
Klucz utwórz w panelu Ustawienia -> API -> API Keys. Dla każdej aplikacji i środowiska warto utworzyć osobny klucz, nadać mu czytelną nazwę i wybrać tylko zakresy potrzebne do obsługi zadań.
Usunięcie klucza usuwa jego rekord i zwalnia miejsce w limicie. Wygaśnięcie daty aktywności zatrzymuje uwierzytelnianie, ale nie zastępuje porządkowania listy. Jeżeli data końcowa nie zostanie ustawiona, domyślny okres aktywności wynosi 90 dni, a maksymalny okres jednego klucza to 5 lat.
Zadania - uwierzytelnianie żądań
Każde żądanie do Codenica API uwierzytelnij dwoma nagłówkami:
X-Codenica-Client-Id: {CLIENT_ID}
X-Codenica-Client-Secret: {CLIENT_SECRET}
Accept: application/jsonPrzykład pierwszego odczytu:
export PUBLIC_API_CLIENT_ID="cna_twoj_client_id"
export PUBLIC_API_CLIENT_SECRET="cns_twoj_client_secret"
curl --fail-with-body --silent --show-error \
--header "Accept: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/context"Zewnętrzna integracja nie potrzebuje sesji panelu ani Bearer JWT użytkownika. Sekret przechowuj po stronie serwera albo w menedżerze sekretów. Nie umieszczaj go w kodzie przeglądarkowym, repozytorium, adresie URL, historii poleceń ani logach.
Zadania - sprawdzenie kontekstu połączenia
Przed pobraniem listy albo utworzeniem pierwszego zadania odczytaj kontekst. Sprawdzisz, czy adres prowadzi do właściwej bazy danych oraz czy klucz ma wymagane zakresy i limity.
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/context" | jqW odpowiedzi zweryfikuj data.tenant.id, data.tenant.name, data.tenant.subdomain, data.tenant.resolvedDomain, data.caller.clientId oraz data.caller.scopes. Sprawdź również, czy możliwości obejmują supportsRelationships, supportsFiles, supportsETag i supportsIdempotency.
{
"data": {
"apiVersion": "v1",
"caller": {
"authentication": "api_key",
"clientId": "{CLIENT_ID}",
"scopes": [
"worktasks:read",
"worktasks:write"
]
},
"capabilities": {
"supportsETag": true,
"supportsIdempotency": true,
"supportsRelationships": true,
"supportsFiles": true
}
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}Jeżeli context wskazuje inną firmę albo nie zawiera potrzebnego zakresu, zatrzymaj integrację i popraw adres lub klucz. Nie próbuj zmieniać bazy danych przez dodanie obcego identyfikatora do body.
Zadania - schema i obsługiwane pola
Schema jest źródłem informacji o aktualnej konfiguracji zadań. Zwraca typy pól, wymagane wartości, zapisywalność, pola techniczne oraz targety relacji dostępne w danej instalacji.
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/schema" | jq{
"data": {
"itemType": "worktask",
"fields": [
{
"name": "customId",
"type": "string",
"readable": true,
"writable": true,
"required": false
},
{
"name": "title",
"type": "string",
"readable": true,
"writable": true,
"required": false
}
],
"relationshipTargets": [
{
"targetDataSet": "assets",
"targetItemType": "asset"
},
{
"targetDataSet": "tickets",
"targetItemType": "ticket"
}
]
}
}Nie zakładaj, że konfiguracja wszystkich baz danych jest identyczna. Przed mapowaniem pól sprawdź bieżące schema i respektuj wartości readable, writable, required, technical oraz maxLength.
Zadania - pola do zapisu i pola systemowe
Poniższe pola są przeznaczone do przekazywania w attributes. Jeżeli schema bieżącej instalacji podaje inne ograniczenia, to ono ma pierwszeństwo.
customIddateDuedateEndlocationdepartmenttaglinktitlestatusprioritycategorydescriptionPole pin jest tylko do odczytu i zmienia się je przez dedykowaną trasę /pin. Pola techniczne, takie jak authorId, agentId, workTimeId, creator, updater, dateCreated, dateUpdated, importId, importSource i dateImported, są uzupełniane przez system. Nie przesyłaj ich w zwykłym tworzeniu ani w PATCH. Wartość itemType musi zawsze wynosić worktask.
Zadania - najważniejsze endpointy
Poniższa lista pokazuje główne operacje udostępnione dla obiektu worktask. Dodatkowy zakres klucza dobierz do operacji, którą chcesz wykonać.
Zadania - listowanie i paginacja
Listę zadań pobieraj stronami. Sortowanie warto ustawić jawnie, aby kolejne odczyty miały przewidywalną kolejność:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks?page=1&pageSize=25&sort=dateCreated&direction=desc" | jqW odpowiedzi odczytaj data.items, page, pageSize, totalItems, totalPages i hasNextPage. Gdy hasNextPage ma wartość true, pobierz następną stronę. Maksymalny rozmiar strony sprawdź w data.capabilities.limits.maxPageSize z context.
Parametr ids służy do pobrania wskazanych UUID-ów. Do synchronizacji lepiej używać stabilnego customId po stronie własnej aplikacji, a następnie zapisywać UUID zwrócony przez Codenica API.
Zadania - wyszukiwanie i filtry
Lista obsługuje wyszukiwanie tekstowe, dopasowanie konkretnych pól oraz filtr strukturalny. Najczęściej używane parametry to customId, search, title, status, priority, category, location, department, tag, createdAfter, createdBefore, updatedAfter i updatedBefore.
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks?search=stacja&filter=status%3Aeq%3AOpen&sort=dateDue&direction=asc&page=1&pageSize=25" | jqFiltr ma postać field:operator:value. Przykłady operatorów:
status:eq:Open
priority:ne:Low
title:startswith:Przygotuj
description:contains:stacja
dateDue:gte:2026-09-01T00:00:00ZSkróty =, !=, ge, le, sw i ew odpowiadają odpowiednio operatorom równości, nierówności, większe lub równe, mniejsze lub równe, startswith i endswith. Wartości zawierające znaki specjalne zakoduj w adresie URL.
Zadania - wybór pól i dołączanie danych
Parametr fields ogranicza pola zwracane w rekordzie. Dzięki temu odpowiedź jest mniejsza i łatwiejsza do przetwarzania:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks?fields=customId,title,status,priority,dateDue&page=1&pageSize=25" | jqJeśli potrzebujesz danych powiązanych, użyj include:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/{WORKTASK_ID}?fields=%2A&include=files%2Crelationships%2Cusers" | jqDostępne dołączenia nie zwiększają uprawnień klucza. Aby zobaczyć pliki, relacje albo użytkowników, potrzebujesz odpowiednich zakresów worktasks:files:read, worktasks:relationships:read i worktasks:users:read. Pełne fields=* stosuj tylko wtedy, gdy rzeczywiście potrzebujesz pól technicznych.
Zadania - statystyki i wartości pól
Statystyki pomagają zbudować zestawienia bez pobierania całej kolekcji. Przykład liczby zadań według statusu:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/stats?field=status&limit=20" | jq{
"data": {
"total": 42,
"field": "status",
"values": [
{ "value": "Open", "count": 12 },
{ "value": "In progress", "count": 18 },
{ "value": "Closed", "count": 12 }
]
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}Endpoint values zwraca wartości pola pasujące do wyszukiwania. Przydaje się na przykład do podpowiedzi w formularzu:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/values?field=category&search=oper&limit=20" | jqObie trasy są tylko do odczytu i wymagają zakresu worktasks:stats.
Zadania - utworzenie minimalne
Minimalny zapis powinien zawierać itemType oraz obiekt attributes. W praktyce warto od razu nadać własny customId i tytuł:
{
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Przygotowanie stanowiska pracy",
"status": "Open",
"priority": "High",
"category": "IT"
}
}Żądanie tworzące rekord:
curl --fail-with-body --silent --show-error \
--request POST \
--header "Accept: application/json, application/problem+json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Idempotency-Key: erp-worktask-create-2026-0042" \
--data-raw '{
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Przygotowanie stanowiska pracy",
"status": "Open",
"priority": "High",
"category": "IT"
}
}' \
"$BASE_URL/api/v1/worktasks" | jqPrawidłowa odpowiedź ma status 201 Created. Zapisz data.id oraz ETag rekordu do dalszej pracy.
Zadania - kompletne utworzenie
Poniższy przykład zapisuje dane, które zwykle są potrzebne do przekazania zadania z systemu planowania pracy:
{
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Przygotowanie stanowiska dla nowej osoby",
"description": "Zainstaluj komputer, skonfiguruj dostęp do sieci i potwierdź gotowość stanowiska.",
"status": "Open",
"priority": "High",
"category": "Onboarding",
"dateDue": "2026-09-30T12:00:00Z",
"location": "Kraków",
"department": "IT",
"tag": "onboarding,stanowisko-pracy",
"link": "https://portal.example.com/tasks/ERP-WORKTASK-2026-0042"
}
}Wartości statusu, priorytetu i kategorii powinny odpowiadać konfiguracji używanej w Twojej bazie. API nie tworzy automatycznie własnego słownika tylko dlatego, że integracja przesłała nową nazwę.
curl --fail-with-body --silent --show-error \
--request POST \
--header "Accept: application/json, application/problem+json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Idempotency-Key: erp-worktask-create-2026-0042" \
--data-binary @worktask.json \
"$BASE_URL/api/v1/worktasks" | jqZadania - Idempotency-Key i bezpieczne ponowienie
Każda mutacja wykonywana kluczem API wymaga nagłówka Idempotency-Key. Wartość identyfikuje jedną intencję biznesową. Dla ponowienia tego samego żądania zachowaj ten sam klucz i nie zmieniaj body. Dla nowego zadania albo innej operacji wygeneruj inną wartość.
--header "Idempotency-Key: erp-worktask-create-2026-0042"Jeżeli połączenie zostało przerwane po wysłaniu żądania, najpierw ponów identyczne żądanie z tym samym kluczem. Nie twórz od razu nowego klucza, bo możesz zapisać duplikat. Brak nagłówka kończy mutację odpowiedzią 428 z kodem idempotency_key_required.
Zadania - odczyt pojedynczego rekordu
Po utworzeniu pobierz rekord po UUID zwróconym w data.id:
export WORKTASK_ID="{UUID_Z_ODPOWIEDZI_CREATE}"
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID?fields=customId,title,status,priority,category,dateDue,description" | jqPojedynczy rekord zawiera id, itemType, attributes i meta. W meta odczytaj ETag, który będzie potrzebny przy kolejnej mutacji.
{
"data": {
"id": "{WORKTASK_ID}",
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-2026-0042",
"title": "Przygotowanie stanowiska dla nowej osoby",
"status": "Open"
},
"meta": {
"customId": "ERP-WORKTASK-2026-0042",
"etag": "{CURRENT_ETAG}"
}
},
"meta": {
"requestId": "{REQUEST_ID}",
"etag": "{CURRENT_ETAG}"
}
}Zadania - edycja z ETag i If-Match
Przed zmianą odczytaj aktualny rekord i zachowaj dokładną wartość ETag, razem z cudzysłowami, jeżeli są jej częścią:
ETAG=$(curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID?fields=customId,title,status,priority,description" \
| jq -r '.data.meta.etag // .meta.etag')PATCH zmienia tylko wskazane atrybuty. Po powodzeniu zapisz nowy ETag:
curl --fail-with-body --silent --show-error \
--request PATCH \
--header "Accept: application/json, application/problem+json" \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $ETAG" \
--header "Idempotency-Key: erp-worktask-update-2026-0042" \
--data-raw '{
"attributes": {
"title": "Konfiguracja stanowiska dla nowej osoby",
"status": "In progress",
"priority": "Normal",
"description": "Komputer i dostęp sieciowy są w trakcie konfiguracji."
}
}' \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID" | jqNie używaj ETag zapisanego przed inną zmianą. Każda udana mutacja może zmienić wersję rekordu.
Zadania - nieaktualny lub brakujący ETag
Jeżeli inna osoba albo integracja zmieniła zadanie, stary ETag kończy się odpowiedzią 412 Precondition Failed z kodem if_match_failed. API nie powinno zastosować odrzuconej zmiany.
{
"type": "https://docs.codenica.com/errors/if_match_failed",
"title": "Precondition failed.",
"status": 412,
"detail": "The supplied ETag is not the current workTask version.",
"code": "if_match_failed",
"requestId": "{REQUEST_ID}"
}PATCH, DELETE, relacje, pliki i pinowanie bez wymaganego If-Match zwracają 428 Precondition Required z kodem if_match_required. Po 412 pobierz rekord ponownie, zdecyduj, czy zachować lokalną zmianę, i dopiero wtedy wyślij nowe żądanie.
Zadania - przypięcie i odpięcie
Pole pin jest tylko do odczytu w attributes. Zmianę wykonuj przez dedykowany endpoint:
POST /api/v1/worktasks/{WORKTASK_ID}/pinPrzypięcie na poziomie 3:
curl --fail-with-body --silent --show-error \
--request POST \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $ETAG" \
--header "Idempotency-Key: erp-worktask-pin-2026-0042" \
--data '{"pin":3}' \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/pin" | jqWartość null odpina zadanie:
curl --fail-with-body --silent --show-error \
--request POST \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $NEW_ETAG" \
--header "Idempotency-Key: erp-worktask-unpin-2026-0042" \
--data '{"pin":null}' \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/pin" | jqPo każdej z tych operacji pobierz zadanie ponownie, ponieważ jego ETag może się zmienić.
Zadania - relacje użytkowników: autor i agent
Relacja użytkownika jest dostępna przez osobną trasę i służy do odczytu autora zadania oraz przypisanego agenta:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/user-relationships?page=1&pageSize=20" | jqW kolekcji pojawiają się wyłącznie relacje o typie author albo agent. Przykładowy element może wyglądać tak:
{
"targetId": "{USER_ID}",
"targetDataSet": "users",
"relationshipType": "agent",
"displayName": "Anna Kowalska",
"email": "[email protected]",
"role": "Agent"
}Pola authorId i agentId są polami technicznymi. Nie próbuj zmieniać ich przez zwykły PATCH attributes. Jeżeli konkretna wersja API udostępnia osobną akcję przypisania, kieruj się jej schema i zakresem uprawnień.
Zadania - dozwolone relacje z obiektami
Schema zadań udostępnia jedenaście grup obiektów, które mogą być targetem relacji:
Dla assets typ zależy od konkretnego zasobu. W tabeli pokazano przykład computer, ale przed zapisaniem relacji odczytaj rzeczywiste itemType wybranego obiektu.
Zadania - wybór targetItemType i format relacji
targetItemType musi odpowiadać rzeczywistemu typowi obiektu docelowego. Najbezpieczniejsza kolejność to: pobierz listę albo schema targetu, odczytaj jego itemType, a dopiero potem zbuduj body relacji.
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/assets?page=1&pageSize=10&sort=dateCreated&direction=desc" | jq '.data.items[0] | {id, itemType}'Relacje obiektowe zadań nie przyjmują pola relationshipType. Przekaż tylko identyfikator, nazwę zbioru i typ obiektu:
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer"
}Nie kopiuj wartości asset, document albo task bez sprawdzenia konkretnego targetu. Nieprawidłowy typ kończy się błędem walidacji.
Zadania - dodanie, odczyt i usunięcie relacji
Dodanie jednej relacji z zasobem wymaga aktualnego ETag zadania oraz osobnego klucza idempotencji:
curl --fail-with-body --silent --show-error \
--request POST \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $ETAG" \
--header "Idempotency-Key: erp-worktask-relation-assets-2026-0042" \
--data '{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer"
}' \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/relationships" | jqRelację odczytaj z filtrem zbioru:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/relationships?targetDataSet=assets&page=1&pageSize=100" | jqUsunięcie pojedynczego powiązania:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $ETAG" \
--header "Idempotency-Key: erp-worktask-relation-delete-assets-2026-0042" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/relationships/assets/{ASSET_ID}" | jqPo usunięciu odpowiedź powinna zawierać data=true. Dodanie nowej relacji zwraca 201 Created, a w niektórych sytuacjach ponowne wskazanie już istniejącej relacji może zwrócić 200 OK.
Zadania - relacje batch
Wiele relacji możesz dodać albo usunąć jednym żądaniem:
{
"add": [
{
"targetId": "{DOCUMENT_ID}",
"targetDataSet": "documents",
"targetItemType": "document"
}
],
"remove": [
{
"targetId": "{ASSET_ID}",
"targetDataSet": "assets",
"targetItemType": "computer"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $ETAG" \
--header "Idempotency-Key: erp-worktask-relationships-batch-2026-0042" \
--data-binary @worktask-relationships.json \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/relationships:batch" | jq{
"data": {
"added": 1,
"removed": 1,
"skipped": 0
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}Batch relacji także nie przyjmuje relationshipType. Użyj aktualnego ETag zadania, a limit elementów odczytaj z context. Po operacji zapisz nowy ETag, jeżeli został zwrócony, i odczytaj kolekcję w celu weryfikacji.
Zadania - lista plików i upload
Pliki przypisane do zadania obsługuje osobna grupa endpointów. Najpierw pobierz listę:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/files?page=1&pageSize=100" | jqElement listy zawiera między innymi id, fileName, contentType, size, relationshipType, isMain i downloadUrl. Nowy plik prześlij jako multipart/form-data:
curl --fail-with-body --silent --show-error \
--request POST \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $ETAG" \
--header "Idempotency-Key: erp-worktask-file-upload-2026-0042" \
--form "file=@./instrukcja-stanowiska.pdf;type=application/pdf" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/files?relationshipType=instruction" | jqUpload wymaga zakresu worktasks:files:write, aktualnego ETag i limitu pliku odczytanego z context. Dla zadań API ustawia isMain=false; nie zakładaj osobnego pliku głównego.
Zadania - pobieranie i dołączenie pliku
Treść pliku pobierz przez trasę content i zapisz w trybie binarnym:
curl --fail-with-body --silent --show-error \
--output ./instrukcja-stanowiska-pobrana.pdf \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/files/{FILE_ID}/content"Jeżeli plik jest już zapisany w systemie, możesz podpiąć go do drugiego zadania bez ponownego wysyłania treści. Pobierz wcześniej ETag drugiego zadania:
curl --fail-with-body --silent --show-error \
--request POST \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $SECOND_WORKTASK_ETAG" \
--header "Idempotency-Key: erp-worktask-file-attach-2026-0042" \
"$BASE_URL/api/v1/worktasks/$SECOND_WORKTASK_ID/files/{FILE_ID}?relationshipType=reference" | jqAttach tworzy relację pliku z drugim zadaniem. Ten sam plik może być widoczny w obu rekordach, a reference jest typem relacji pliku, nie relacją obiektową zadania.
Zadania - odłączenie i usunięcie pliku
Odłącz plik od drugiego zadania, używając jego aktualnego ETag:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $SECOND_WORKTASK_ETAG" \
--header "Idempotency-Key: erp-worktask-file-detach-2026-0042" \
"$BASE_URL/api/v1/worktasks/$SECOND_WORKTASK_ID/files/{FILE_ID}" | jqOdłączenie powinno zwrócić data=true i nie usuwać relacji pliku ze źródłowego zadania. Aby usunąć plik ze źródła, pobierz jego nowy ETag i wykonaj:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $SOURCE_WORKTASK_ETAG" \
--header "Idempotency-Key: erp-worktask-file-delete-2026-0042" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID/files/{FILE_ID}" | jqPo usunięciu sprawdź listę plików. Zadania nie mają osobnej trasy ustawiania pliku głównego.
Zadania - operacje batch dla rekordów
Endpoint /api/v1/worktasks:batch pozwala połączyć tworzenie, edycję i usuwanie zadań. Każda pozycja aktualizacji albo usunięcia ma własny ETag:
{
"items": [
{
"operation": "create",
"create": {
"itemType": "worktask",
"attributes": {
"customId": "ERP-WORKTASK-BATCH-A",
"title": "Przygotowanie dostępu",
"status": "Open",
"priority": "Normal",
"category": "IT"
}
}
},
{
"operation": "update",
"id": "{WORKTASK_ID}",
"ifMatch": "{CURRENT_ETAG}",
"update": {
"attributes": {
"title": "Przygotowanie dostępu - etap drugi",
"status": "In progress"
}
}
},
{
"operation": "delete",
"id": "{OTHER_WORKTASK_ID}",
"ifMatch": "{OTHER_CURRENT_ETAG}"
}
]
}curl --fail-with-body --silent --show-error \
--request POST \
--header "Content-Type: application/json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "Idempotency-Key: erp-worktasks-batch-2026-0042" \
--data-binary @worktasks-batch.json \
"$BASE_URL/api/v1/worktasks:batch" | jq{
"data": {
"items": [
{
"index": 0,
"operation": "create",
"status": 201,
"id": "{CREATED_WORKTASK_ID}",
"data": {
"meta": {
"etag": "{CREATED_ETAG}"
}
}
}
],
"succeeded": 1,
"failed": 0
},
"meta": {
"requestId": "{REQUEST_ID}"
}
}Przy częściowym wyniku API może zwrócić 207 Multi-Status. Przejdź wtedy po data.items, sprawdź wynik każdej pozycji i ponów tylko te operacje, które rzeczywiście tego wymagają.
Zadania - usunięcie rekordu
Przed usunięciem ponownie odczytaj rekord, sprawdź UUID i aktualny ETag, a następnie użyj nowego klucza idempotencji:
curl --fail-with-body --silent --show-error \
--request DELETE \
--header "Accept: application/json, application/problem+json" \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
--header "If-Match: $CURRENT_ETAG" \
--header "Idempotency-Key: erp-worktask-delete-2026-0042" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID" | jqPrawidłowa odpowiedź zawiera 200 OK i data=true. Po usunięciu zweryfikuj, że rekord nie jest już dostępny:
curl --fail-with-body --silent --show-error \
--header "X-Codenica-Client-Id: $PUBLIC_API_CLIENT_ID" \
--header "X-Codenica-Client-Secret: $PUBLIC_API_CLIENT_SECRET" \
"$BASE_URL/api/v1/worktasks/$WORKTASK_ID"Oczekiwany status to 404 Not Found. Dodatkowo możesz sprawdzić listę filtrem customId=ERP-WORKTASK-2026-0042 i potwierdzić totalItems=0.
Zadania - błędy, limity i bezpieczna kolejność
Odpowiedzi problemowe mają format Problem Details. Do logiki integracji używaj pola code, a do zgłoszenia problemu zachowaj także requestId. Nie zapisuj w logach sekretu ani pełnych nagłówków.
validation_failedauthentication_requiredworktask_not_foundfile_not_foundif_match_failedfile_too_largeif_match_requiredidempotency_key_requiredinternal_errorOdczytuj nagłówki X-RateLimit-Limit i X-RateLimit-Remaining. Przy 429 zastosuj rosnące opóźnienie z losowym rozrzutem, ogranicz liczbę prób i nie wykonuj nieskończonej pętli dla błędów 400, 401, 403, 404 albo 412.
Bezpieczna kolejność pracy
- Ustal
BASE_URLwłaściwej instalacji i odczytajcontext. - Sprawdź scope’y, limity, schema i rzeczywiste
itemTypetargetów relacji. - Utwórz zadanie z własnym
Idempotency-Key, a następnie zapisz UUID i ETag. - Przed każdą zmianą, relacją, operacją na pliku albo pinowaniem pobierz aktualny ETag.
- Po udanej mutacji zapisz nowy ETag i zweryfikuj wynik odczytem.
- Po zakończeniu synchronizacji sprawdź rekord po
customId, a dane demonstracyjne usuń osobnym żądaniem. - W n8n użyj węzła HTTP Request; przechowuj Client ID i Client Secret w credentials, a UUID, ETag i klucz idempotencji przekazuj między kolejnymi węzłami.
