Requested Items in Codenica API

To work with Requested Items through Codenica API, start by creating an API key in Codenica settings. If you have not created a key yet, open Codenica API - introduction in a new tab. It explains the shared rules for creating a key, storing the secret and authenticating requests.

The technical collection name in the API is requesteditems, and the type of one object is requesteditem. A requested item records a need to purchase, deliver, prepare or complete a specific item. In addition to a description, it can contain a due date, quantity, price, cost, value, tax, budget, priority and status.

The examples use the prefix PUBLIC-API-REQUESTEDITEM-20260906053922. Replace it with your own identifier in an integration, and adjust the addresses, UUIDs and field values to the data in your database.


Requested Items - API address and installation choice

All Requested Items routes start with:

{BASE_URL}/api/v1/requesteditems

BASE_URL means the Codenica server address without the /api/v1 suffix. In Cloud, use the public domain assigned to the correct company:

export BASE_URL="https://your-company.codenica.com"

In a default On-Premise installation, the address registered locally by Codenica Discovery is:

export BASE_URL="http://codenica.local:5150"

If an administrator has published the installation under a company domain, through a reverse proxy, with HTTPS or on another port, use the exact address provided for that installation:

export BASE_URL="https://api.your-company.example"

Do not use localhost if the integrating application runs on another computer than the API. The correct database is selected based on the address to which the integration connects. Do not pass tenantId in the body, query string or an additional header.


Requested Items - API key scopes

An API key used to work with Requested Items should contain only the scopes needed by the particular integration. The complete scope set for this module is:

requesteditems:read
requesteditems:write
requesteditems:delete
requesteditems:schema
requesteditems:stats
requesteditems:relationships:read
requesteditems:relationships:write
requesteditems:users:read
requesteditems:files:read
requesteditems:files:write
requesteditems:technical:read
requesteditems:technical:write
requesteditems:pin:write

For reading lists and records, select requesteditems:read; to inspect the field catalog, also select requesteditems:schema. Creating and editing require requesteditems:write, while deleting requires requesteditems:delete. Add relationship, file, statistics, requester and pinning scopes only when the integration uses those operations.

If the integration searches for relationship targets, the key also needs the relevant read scopes, for example assets:read, clients:read, vendors:read, documents:read, tickets:read, changes:read, problems:read, releases:read, notes:read, approvals:read or worktasks:read. The key scope does not replace the user's permissions.


Requested Items - authentication

Authenticate every Codenica API request with two headers:

export CLIENT_ID="cna_your_client_id"
export CLIENT_SECRET="cns_your_client_secret"

curl --request GET --url "$BASE_URL/api/v1/requesteditems?page=1&pageSize=25" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

An external integration does not need the administrator's JWT or cookies from the Codenica panel. Store the secret in a server-side secret store. Do not put it in browser-delivered code, a repository, a URL, command history or logs. Use HTTPS outside local testing.

Store meta.requestId from responses. This identifier helps locate a specific request in logs, but it does not replace the Requested Item UUID and is not a secret.


Requested Items - checking the connection context

Before the first write, retrieve the context. This confirms that the address points to the correct database and that the key has the required scopes and limits:

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"

In the response, verify data.apiVersion, data.contractVersion, data.tenant, data.caller.authentication equal to api_key, the presence of requesteditems in data.capabilities.resources, the key scopes and request limits.

If the context identifies another company or does not contain the required scope, correct the address or create a key with the right permissions. Do not try to route a request to another database by sending a foreign tenantId.


Requested Items - schema and relationship targets

The schema is the source of information about current fields, their types, whether they can be written and which relationship targets are allowed:

curl --request GET --url "$BASE_URL/api/v1/requesteditems/schema" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

The response includes, among other values, data.itemType, data.fields and data.relationshipTargets. For this module, itemType is requesteditem. For each field, check readable, writable, required, technical, unique and maxLength.

Example schema fragment:

{
  "data": {
    "itemType": "requesteditem",
    "fields": [
      { "name": "title", "type": "string", "writable": true },
      { "name": "dateDue", "type": "dateTime", "writable": true },
      { "name": "quantity", "type": "integer", "writable": true },
      { "name": "value", "type": "number", "writable": true },
      { "name": "pin", "type": "integer", "writable": false }
    ],
    "relationshipTargets": [
      { "targetDataSet": "assets", "targetItemType": "asset" },
      { "targetDataSet": "documents", "targetItemType": "document" },
      { "targetDataSet": "worktasks", "targetItemType": "worktask" }
    ]
  }
}

Do not build a mapping only from the example. Before starting an integration, retrieve the schema for the correct database and use only the returned fields and targets.


Requested Items - business and system fields

The most important Requested Item fields are:

Field
Type
Limit or use
customId
string
500 characters, identifier from the integration
dateDue, dateEnd
dateTime
due date and end date
location, department
string
300 characters each
tag, link
string
2000 characters each
title
string
1000 characters
status, priority, category, budget, currency
string
values describing the process and settlement
tax, quantity
integer
whole number
cost, price, value
number
cost, unit price and value
description
string
10000 characters

id, itemType, creator, updater, dateCreated, dateUpdated, importId, importSource and dateImported are set by the system or intended for technical reading. Do not send them in attributes.

appUserRequesterId
clientRequesterId
catalogId
catalogItemId
creator
updater
dateCreated
dateUpdated
importId
importSource
dateImported

Requested Items - available endpoints

The main routes of the requesteditems module are:

GET    /api/v1/requesteditems
POST   /api/v1/requesteditems
GET    /api/v1/requesteditems/{REQUESTED_ITEM_ID}
PATCH  /api/v1/requesteditems/{REQUESTED_ITEM_ID}
DELETE /api/v1/requesteditems/{REQUESTED_ITEM_ID}
GET    /api/v1/requesteditems/schema
GET    /api/v1/requesteditems/stats
GET    /api/v1/requesteditems/values
POST   /api/v1/requesteditems:batch
GET    /api/v1/requesteditems/{REQUESTED_ITEM_ID}/relationships
POST   /api/v1/requesteditems/{REQUESTED_ITEM_ID}/relationships
POST   /api/v1/requesteditems/{REQUESTED_ITEM_ID}/relationships:batch
DELETE /api/v1/requesteditems/{REQUESTED_ITEM_ID}/relationships/{DATASET}/{TARGET_ID}
GET    /api/v1/requesteditems/{REQUESTED_ITEM_ID}/user-relationships
GET    /api/v1/requesteditems/{REQUESTED_ITEM_ID}/files
POST   /api/v1/requesteditems/{REQUESTED_ITEM_ID}/files
POST   /api/v1/requesteditems/{REQUESTED_ITEM_ID}/files/{FILE_ID}
DELETE /api/v1/requesteditems/{REQUESTED_ITEM_ID}/files/{FILE_ID}
GET    /api/v1/requesteditems/{REQUESTED_ITEM_ID}/files/{FILE_ID}/content
POST   /api/v1/requesteditems/{REQUESTED_ITEM_ID}/pin

Reads require read scopes, while individual mutations require additional scopes according to the permission table. Every request that changes data also requires an Idempotency-Key.


Requested Items - lists and pagination

Retrieve Requested Items page by page. Example:

curl --request GET --url "$BASE_URL/api/v1/requesteditems?itemType=requesteditem&page=1&pageSize=25" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

The response contains the data.items collection and page information:

{
  "data": {
    "items": [
      {
        "id": "requested-item-uuid",
        "itemType": "requesteditem",
        "attributes": {
          "customId": "ERP-REQ-2026-0042",
          "title": "Three monitors for a new workstation",
          "status": "Open",
          "quantity": 3,
          "value": 3136.5
        },
        "meta": {
          "etag": "\"etag-value\""
        }
      }
    ],
    "page": 1,
    "pageSize": 25,
    "totalItems": 1,
    "totalPages": 1,
    "hasNextPage": false
  },
  "meta": {
    "requestId": "request-id"
  }
}

Move to the next page based on hasNextPage. Do not assume that the last page always contains fewer elements than the selected pageSize. Check the maximum page size in data.capabilities.limits or the current contract.


Requested Items - search and filters

Use the search parameter for text search. For synchronization, a stable customId, UUID or an explicit filter is preferable:

curl --silent --show-error -G \
  --data-urlencode "search=monitors" \
  --data-urlencode "page=1" \
  --data-urlencode "pageSize=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  "$BASE_URL/api/v1/requesteditems"

Simple filters can use field names:

curl --silent --show-error -G \
  --data-urlencode "status=Open" \
  --data-urlencode "priority=High" \
  --data-urlencode "customId=ERP-REQ-2026-0042" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  "$BASE_URL/api/v1/requesteditems"

A structural filter has the form field:operator:value:

status:eq:Open
priority:ne:Low
quantity:gte:2
price:lt:1000
title:contains:laptop
customId:startswith:ERP-
link:notempty:

Supported operators are eq, ne, gt, gte, lt, lte, contains, startswith, endswith and notempty. URL-encode the filter value, especially when it contains a space, colon or special character.


Requested Items - selecting fields and including data

If you need only part of a response, use fields. Include files, relationships and users with include:

curl --silent --show-error -G \
  --data-urlencode "fields=id,itemType,customId,title,status,priority,dateDue,quantity,value" \
  --data-urlencode "include=files,relationships,users" \
  --data-urlencode "ids=7512ef99-0010-4962-9453-99383a377e4b" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  "$BASE_URL/api/v1/requesteditems"

Available include values are files, relationships and users. Each requires the corresponding scope. fields=* does not bypass permissions for technical fields and does not return system fields intended for the response envelope.

You can also filter with createdAfter, createdBefore, updatedAfter, updatedBefore, sort and direction. Check field names in fields, sort and filter against the current schema.


Requested Items - statistics and field values

The stats endpoint helps inspect the distribution of data, while values returns values useful for building filters:

curl --silent --show-error -G \
  --data-urlencode "field=status" \
  --data-urlencode "limit=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  "$BASE_URL/api/v1/requesteditems/stats"

curl --silent --show-error -G \
  --data-urlencode "field=category" \
  --data-urlencode "search=hard" \
  --data-urlencode "limit=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  "$BASE_URL/api/v1/requesteditems/values"

Example values response:

{
  "data": {
    "field": "category",
    "values": ["Hardware", "Office"]
  },
  "meta": {
    "requestId": "request-id"
  }
}

Statistics and values are read-only operations and do not change Requested Items. Do not poll them in a tight loop without a reason - schema and field values can be cached for a period appropriate to the integration.


Requested Items - minimal creation

Create a record with POST /api/v1/requesteditems. Put itemType in the body and fields inside attributes:

curl --request POST --url "$BASE_URL/api/v1/requesteditems" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Idempotency-Key: requesteditem-create-unique-001" \
  --data-raw '{
    "itemType": "requesteditem",
    "attributes": {
      "customId": "ERP-REQ-2026-0042",
      "title": "Office supplies purchase",
      "category": "Office",
      "quantity": 10,
      "currency": "PLN",
      "status": "Open",
      "description": "Item created by the integration."
    }
  }'

The itemType value must be requesteditem. Match field names and types to the schema response. Send dates as ISO 8601 and numbers as JSON numbers, not formatted strings.

A successful response has status 201 Created. Save data.id, the ETag from the HTTP header and the ETag from data.meta.etag.


Requested Items - complete creation with financial fields

The following example corresponds to a record from the complete demonstration flow. It shows a due date, location, status, priority and settlement data:

curl --request POST --url "$BASE_URL/api/v1/requesteditems" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Idempotency-Key: requesteditem-create-20260906053922-source" \
  --data-raw '{
    "itemType": "requesteditem",
    "attributes": {
      "customId": "PUBLIC-API-REQUESTEDITEM-20260906053922-SOURCE",
      "dateDue": "2026-12-31T17:00:00Z",
      "dateEnd": "2027-01-15T17:00:00Z",
      "location": "Warsaw",
      "department": "IT",
      "tag": "public-api,requesteditems,demo",
      "link": "https://codenica.com",
      "title": "Requested Item API complete flow",
      "status": "Open",
      "priority": "High",
      "category": "Hardware",
      "budget": "IT-2026",
      "currency": "PLN",
      "tax": 23,
      "quantity": 3,
      "cost": 300,
      "price": 100,
      "value": 369,
      "description": "Demo requested item created through the Public API."
    },
    "customValues": [
      {
        "name": "description",
        "valuePattern": "[requested-item-demo] Public API"
      }
    ]
  }'

customValues is optional. Remove this property if the integration does not use additional value rules. Do not send technical fields just because they appeared in a response.


Requested Items - safely retrying creation

If a timeout occurs after sending a request and you do not know whether the record was saved, repeat exactly the same operation with the same Idempotency-Key and identical body:

curl --request POST --url "$BASE_URL/api/v1/requesteditems" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Idempotency-Key: requesteditem-create-20260906053922-source" \
  --data-binary @requesteditem-create.json

The requesteditem-create.json file must contain exactly the body from the first request. The retry returns the same record instead of creating a duplicate. A new business intention, changed body or different route requires a new key. Retrying with a different body returns 422 idempotency_key_reused.

Store the idempotency key on the integration side together with the operation status. Do not use the Client Secret for this purpose.


Requested Items - reading a record and its ETag

After creating or finding a Requested Item, retrieve it by UUID:

export REQUESTED_ITEM_ID="7512ef99-0010-4962-9453-99383a377e4b"

curl --request GET --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID?include=files,relationships,users" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Find the current ETag in the HTTP header and usually in data.meta.etag and the main meta.etag envelope:

ETag: "etag-value"

An ETag is an opaque version of a specific record. Do not remove the quotation marks returned in the header and do not calculate this value yourself. Before every record, relationship or file change, retrieve a fresh ETag if another person or integration could have changed the record.


Requested Items - partial update with If-Match

PATCH changes only the fields sent in the body. It requires the current ETag and a new idempotency key:

export REQUESTED_ITEM_ETAG='"etag-value-from-get"'

curl --request PATCH --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_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: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-update-20260906-0001" \
  --data-raw '{
    "attributes": {
      "dateDue": "2027-01-31T17:00:00Z",
      "title": "Requested Item API complete flow - updated",
      "status": "In progress",
      "priority": "Normal",
      "quantity": 4,
      "price": 125,
      "value": 615
    }
  }'

You do not need to send the complete object. Fields omitted from the body remain unchanged. After a 200 OK response, replace the stored ETag with the value returned by the API. Every following mutation must use the newest version.


Requested Items - stale ETag and missing If-Match

A missing If-Match header is rejected so that an integration cannot overwrite changes made by another person:

curl --request PATCH --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Idempotency-Key: requesteditem-update-without-etag-0001" \
  --data-raw '{"attributes":{"status":"Approved"}}'

The expected result is 428 Precondition Required with code if_match_required. If you send an old ETag, you receive 412 Precondition Failed with code if_match_failed:

HTTP 412 Precondition Failed
code: if_match_failed

After a 412 error, retrieve the record again, compare your change with the current data and only then send another PATCH. Do not run a blind loop that overwrites a user's changes.


Requested Items - pinning and unpinning

pin is a read-only field in attributes. Set it through a separate endpoint with the current ETag:

curl --request POST --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/pin" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-pin-0001" \
  --data '{"pin":3}'

Values from 0 to 3 are allowed. To remove the pin, use null:

curl --request POST --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/pin" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-unpin-0001" \
  --data '{"pin":null}'

Save the new ETag after every operation. Do not try to change pin through a regular PATCH.


Requested Items - requester relationship

Every Requested Item can have a system requester relationship. Read it with:

curl --request GET --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/user-relationships" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

The requester is set by an existing system flow and may point to appUserRequesterId or clientRequesterId. The Public API provides read access, but has no separate POST or DELETE operation for changing this relationship. Do not try to set the requester through an undocumented field in attributes. Reading it requires requesteditems:users:read and the appropriate data permissions.


Requested Items - allowed object relationships

The current catalog of Requested Item relationship targets includes:

Collection
Example itemType
assets
asset
clients, vendors
client, vendor
documents, tickets
document, ticket
changes, problems, releases
change, problem, release
notes, approvals
note, approval
worktasks
worktask

There is no relationship with the requesteditems collection itself or with confirmations. The target must be visible to the user assigned to the key and must match the relationshipTargets list returned by the schema.


Requested Items - adding, reading and removing relationships

An object relationship does not store relationshipType. Send targetId, targetDataSet and a matching targetItemType in the payload:

{
  "targetId": "5ddc5b5a-5bdc-46f9-ab7e-5ad8f6775b3a",
  "targetDataSet": "assets",
  "targetItemType": "asset"
}

Adding a relationship requires the source's current ETag, the requesteditems:relationships:write scope and a separate idempotency key:

curl --request POST --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/relationships" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-relationship-asset-0001" \
  --data '{
    "targetId": "5ddc5b5a-5bdc-46f9-ab7e-5ad8f6775b3a",
    "targetDataSet": "assets",
    "targetItemType": "asset"
  }'

Read the relationship list with:

curl --request GET --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/relationships?page=1&pageSize=50" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Remove one relationship by collection and target UUID:

curl --request DELETE --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/relationships/assets/5ddc5b5a-5bdc-46f9-ab7e-5ad8f6775b3a" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-relationship-asset-delete-0001"

After adding or removing a relationship, read the source data again and save the new ETag. If the schema does not return a target, do not use it in the integration.


Requested Items - batch relationship changes

Use relationships:batch for several changes in one request. For Requested Item relationships, continue to omit relationshipType:

curl --request POST --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_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: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-relationship-batch-0001" \
  --data-raw '{
    "add": [
      {
        "targetId": "5ddc5b5a-5bdc-46f9-ab7e-5ad8f6775b3a",
        "targetDataSet": "assets",
        "targetItemType": "asset"
      },
      {
        "targetId": "88b93fb8-8848-4669-9d87-ed4795e13bcc",
        "targetDataSet": "documents",
        "targetItemType": "document"
      }
    ],
    "remove": [
      {
        "targetId": "8f42dc16-167b-4e4a-983f-862ae85f3c7a",
        "targetDataSet": "worktasks",
        "targetItemType": "worktask"
      }
    ]
  }'

The response contains counters:

{
  "data": {
    "added": 2,
    "removed": 1,
    "skipped": 0
  },
  "meta": {
    "requestId": "request-id"
  }
}

Do not automatically treat skipped as a business success. After the batch, read the relationship collection and verify the result of every change.


Requested Items - listing and uploading files

Files are handled separately from Requested Item fields. Read the current list first:

curl --request GET --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/files?page=1&pageSize=50" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Send a file as multipart/form-data. Pass the file role in the query string:

curl --request POST --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/files?relationshipType=request-form" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-file-upload-0001" \
  --form "[email protected];type=application/pdf"

A file element contains, among other values, id, fileName, contentType, size, relationshipType, isMain and downloadUrl. Check the size before sending and set the MIME type deliberately.


Requested Items - downloading, attaching and deleting files

Download the file content through the content endpoint and save it in binary mode:

curl --request GET --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/files/$FILE_ID/content" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --output downloaded-requested-item.pdf

If a file already exists in the system, you can attach it without uploading another copy:

curl --request POST --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/files/$FILE_ID?relationshipType=quotation" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-file-attach-0001"

Remove a file from a Requested Item:

curl --request DELETE --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID/files/$FILE_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-file-delete-0001"

Attach creates a relationship with an existing file, but does not upload a new copy. The current Requested Items model has no main-file endpoint: every element has isMain=false. Do not use /files/{FILE_ID}/main or makeMain for this object.


Requested Items - batch operations

The /api/v1/requesteditems:batch endpoint can create, edit and delete several records. It does not replace file operations, pinning or relationship batches:

curl --request POST --url "$BASE_URL/api/v1/requesteditems:batch" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Idempotency-Key: requesteditems-batch-20260906-0001" \
  --data-raw '{
    "items": [
      {
        "operation": "create",
        "create": {
          "itemType": "requesteditem",
          "attributes": {
            "customId": "ERP-REQ-BATCH-001",
            "title": "Mouse and keyboard for the team",
            "category": "Hardware",
            "quantity": 5,
            "price": 150,
            "currency": "PLN",
            "status": "Open"
          }
        }
      },
      {
        "operation": "update",
        "id": "7dc877ec-4766-42cc-a34a-900e55ab3f46",
        "ifMatch": "\"etag-from-get\"",
        "update": {
          "attributes": {
            "status": "Approved",
            "quantity": 6
          }
        }
      },
      {
        "operation": "delete",
        "id": "476b8c2e-6da9-409d-bb35-98039619ccfe",
        "ifMatch": "\"etag-after-update\""
      }
    ]
  }'

Each update and delete item has its own ETag. A batch is not an all-or-nothing transaction. Iterate over items in the response and save the status, UUID and error for every item. A partial result may return 207 Multi-Status.


Requested Items - deleting a record

Before deleting, retrieve the record again, check its UUID and current ETag, and make sure the business process allows deletion:

curl --request DELETE --url "$BASE_URL/api/v1/requesteditems/$REQUESTED_ITEM_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $REQUESTED_ITEM_ETAG" \
  --header "Idempotency-Key: requesteditem-delete-20260906-0001"

A successful response returns 200 OK and data=true. After deletion, reading the UUID again should return 404 Not Found with code requestedItem_not_found. You can also perform a final check with a list filtered by customId and expect totalItems=0.

Deleting a record is not a way to preserve process history. If the data has audit value, save the necessary information in the source system before executing DELETE.


Requested Items - errors, limits and a safe order of work

Errors use the Problem Details format. Store status, code and requestId in logs, but never store the Client Secret or complete headers:

HTTP
Code
Response
401
authentication_failed
Check the host and both headers.
403
scope_or_access_denied
Check the scope and the user's permissions.
404
requestedItem_not_found
The record does not exist or is not visible.
412
if_match_failed
Retrieve a new ETag and resolve the conflict.
428
if_match_required or idempotency_key_required
Add the required header.
422
validation_failed
Correct the body according to the schema.
429
rate_limit_exceeded
Use increasing delay and, if provided, Retry-After.

Read X-RateLimit-Limit and X-RateLimit-Remaining. Limit concurrency, cache schema and values, and use backoff after 429. A safe integration sequence is: context, schema, list or UUID lookup, creation with Idempotency-Key, saving the UUID and ETag, files or relationships, update with If-Match, verification read and deletion only at the end. The same pattern can be used in n8n if credentials are stored as a credential and UUIDs, ETags and idempotency keys are passed between nodes.