Vendors in Codenica API

The technical resource name in the Public API is vendors, while the type returned by the API is vendor. A vendor record can contain the company name, contact details, registration data, status and a description of the business relationship.

Before sending your first request, prepare the key described in Codenica API - introduction. The workflow below covers the full path: inspect the schema and list records, create and update a vendor, manage the limited relationship targets, work with files, use batch operations and remove a record.

  • reading vendor lists with pagination, sorting and filters;
  • requesting only the fields required by the integration;
  • creating vendor records and applying partial updates;
  • protecting changes with ETag and If-Match;
  • retrying mutations safely with Idempotency-Key;
  • using the relationship targets exposed for Vendors by the schema;
  • uploading, downloading, attaching and deleting files;
  • reading statistics, field values and processing batches.

Required fields and accepted values may depend on your database configuration. Read the current schema before writing data.


Vendors - API address and installation type

Send requests to the public address where your Codenica installation is available. Do not use the database address, a container address or a port reachable only inside the server. Vendor paths begin with:

{BASE_URL}/api/v1/vendors

In Codenica Cloud, use the domain assigned to your installation:

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

In the default On-Premise setup, Codenica Discovery registers the service locally at:

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

If the administrator published the On-Premise installation through a company domain, reverse proxy, HTTPS or another external port, use the exact address provided for that installation:

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

The database is selected from the host address. Do not select it with tenantId, an extra query-string parameter or a value in the request body. Do not use localhost when the integrating program runs on another computer.

BASE_URL must not include the final /api/v1:

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

# Default On-Premise with Codenica Discovery:
# export BASE_URL="http://codenica.local:5150"

# On-Premise with an address published by the administrator:
# export BASE_URL="https://api.your-company.example"

Vendors - API key and access scopes

Create the key for an external integration in Codenica under Settings - API - API Keys. Give it a name that identifies the application, environment and purpose, for example Purchasing - Vendors - production. Select only the scopes needed by that integration, then save the displayed Client ID and Client Secret once in a secure secret store.

The complete workflow in this article requires:

  • vendors:read, vendors:write and vendors:delete - reading, creating, updating and deleting records;
  • vendors:schema - fields and relationship targets;
  • vendors:stats - statistics and field values;
  • vendors:relationships:read and vendors:relationships:write - reading and changing relationships;
  • vendors:files:read and vendors:files:write - file operations.

If the integration reads Documents or another relationship target, add its read scope as well, for example documents:read. A Vendors relationship scope does not replace access to the target object.

A read-only integration usually needs:

vendors:read
vendors:schema

Key limits depend on the licence:

Licence
Public API
Maximum keys
Starter
unavailable
0
Plus
available
50
Enterprise
available
100

The API panel stores keys created for your database. A separate key for each application and environment makes it easier to control access, rotate a secret or delete one integration without interrupting the others. A deleted key can no longer authenticate requests and is not counted as active.

The Client Secret is displayed only when a key is created or rotated. Do not store it in a repository, URL, logs, command history or browser-side code.


Vendors - authentication headers

The external application sends server-to-server requests with two headers identifying the key:

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

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

Do not send an administrator JWT or panel cookies in this scenario. The integration uses the API key assigned to this database, and a production installation should be accessed over HTTPS.

Every mutation requires a unique header:

Idempotency-Key: public-api-vendors-create-20260905111218

Updates, deletion, relationship changes and file operations require the record's current ETag:

If-Match: "current-vendor-etag"

After every successful mutation, store the new ETag returned in the header and in data.meta.etag. When repeating the same logical operation, keep the same Idempotency-Key and identical body.


Vendors - checking the installation context

Read the context before starting synchronisation:

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"

Check apiVersion, contractVersion, the database identifier, tenant.resolvedDomain, caller.authentication equal to api_key, the required scopes and vendors in capabilities.resources. Also read page, file, batch and rate-limit values.

A complete integration should normally expose supportsBatch, supportsRelationships, supportsFiles, supportsETag and supportsIdempotency. Keep meta.requestId from every response. It is needed when investigating an error or contacting the administrator.

If the context points to another database or a required scope is missing, stop synchronisation and correct the address or key. Do not try to change the database in the request body.


Vendors - field schema and relationship targets

Read the schema before the first write:

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

In the response, data.itemType is vendor. The schema describes the field type, whether it can be read or written, whether it is required, its maximum length, uniqueness and automatic generation. In the current schema, name is required and can contain up to 300 characters:

Field
Type
Required
Limit
Example meaning
name
string
yes
300
vendor name

Frequently used fields belong to several groups:

  • identification: customId, name, displayName, type, category, role, status;
  • location: location, department, address, city, country, state, zipCode;
  • contact: email, phone, phoneWork, phoneMobile, contactName, contactPhone, contactMobile, contactEmail;
  • registries and labels: website, tag, taxId, idNumber, registryNumber, link, number;
  • description and state: comments, description, notification, value, isLicensed, isVerified.

The schema also returns the relationship-target catalogue. In the current Vendors model these targets are documents, notes, worktasks and requesteditems. Do not assume that every resource visible in the context can be a Vendor relationship target.


Vendors - endpoint map

This map groups the main operations on vendor records. Replace the values in braces with UUIDs returned by earlier responses.

  • GET /api/v1/vendors - list;
  • GET /api/v1/vendors/schema - fields and relationship schema;
  • GET /api/v1/vendors/stats - statistics;
  • GET /api/v1/vendors/values - field values;
  • GET /api/v1/vendors/{id} - single record;
  • POST /api/v1/vendors - create;
  • PATCH /api/v1/vendors/{id} - partial update;
  • DELETE /api/v1/vendors/{id} - delete;
  • POST /api/v1/vendors:batch - create, update and delete operations;
  • GET /api/v1/vendors/{id}/relationships - relationship list;
  • POST /api/v1/vendors/{id}/relationships - add a relationship;
  • POST /api/v1/vendors/{id}/relationships:batch - change relationships in one request;
  • DELETE /api/v1/vendors/{id}/relationships/{targetDataSet}/{targetId} - remove a relationship;
  • GET /api/v1/vendors/{id}/files - file list;
  • POST /api/v1/vendors/{id}/files - upload;
  • POST /api/v1/vendors/{id}/files/{fileId} - attach an existing file;
  • PUT /api/v1/vendors/{id}/files/{fileId}/main - set the primary file;
  • DELETE /api/v1/vendors/{id}/files/{fileId} - delete a file;
  • GET /api/v1/vendors/{id}/files/{fileId}/content - download content.

If an endpoint returns 403, first check the scope assigned to the key and then the permissions of its owner.


Vendors - listing, sorting and pagination

Read the list page by page. This example returns the first twenty records and sorts them by name:

curl --request GET --url "$BASE_URL/api/v1/vendors?page=1&pageSize=20&sort=name&direction=asc" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

The collection envelope contains items, page, pageSize, totalItems, totalPages and hasNextPage. When hasNextPage is true, read the next page. For repeatable synchronisation, set the sort order explicitly.

Read the pageSize limit from the context. Do not assume the first page contains every record or that the default order will remain unchanged.


Vendors - searching and filtering

After creating a record, find it by its own identifier and status:

curl --request GET --url "$BASE_URL/api/v1/vendors?customId=PUBLIC-API-VEN-20260905111218-SOURCE&status=Active&sort=customId&direction=asc&page=1&pageSize=10" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Use search for a text search:

curl --request GET --url "$BASE_URL/api/v1/vendors?search=technology&page=1&pageSize=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Depending on the schema, you can use parameters such as ids, search, name, displayName, email, status, category, type, role, location, department, customId, tag, createdAfter, createdBefore, updatedAfter and updatedBefore.

Use filter for more precise conditions:

filter=status:eq:Active
filter=name:contains:Technology
filter=category:in:Technology,Hardware
filter=description:notEmpty:

The operators compare values, find text fragments, select one of several values and test empty fields. URL-encode spaces and special characters before sending a filter.


Vendors - selecting fields and including data

Use fields to limit the response to the properties the integration needs:

curl --request GET --url "$BASE_URL/api/v1/vendors?fields=id,itemType,customId,displayName,email,status" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Use include to read files and relationships together with the record:

curl --request GET --url "$BASE_URL/api/v1/vendors/a8156781-3b1c-4fa5-9cf2-05077e5d1399?fields=customId,displayName,email,status,description&include=files,relationships" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

The response may contain the requested attributes and the files and relationships collections. Access to included data must be granted separately. Missing vendors:files:read or vendors:relationships:read cannot be bypassed with fields=*.


Vendors - creating a vendor record

Use POST /api/v1/vendors to create a record. Put writable properties inside attributes. The minimum request requires name, but it is useful to send the source-system identifier and basic contact details at the same time:

{
  "attributes": {
    "customId": "ERP-VENDOR-2026-001",
    "name": "Northwind Technology Services",
    "displayName": "Northwind Technology Services",
    "email": "[email protected]",
    "category": "Technology",
    "type": "Supplier",
    "role": "Supplier",
    "status": "Active",
    "description": "IT infrastructure services provider."
  }
}
curl --request POST --url "$BASE_URL/api/v1/vendors" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Idempotency-Key: public-api-vendors-create-erp-vendor-2026-001" \
  --data @vendor-create.json

A successful response has status 201 Created. Store data.id, data.meta.etag and the HTTP ETag header. In the demonstration record, the API returned itemType: vendor and the identifier a8156781-3b1c-4fa5-9cf2-05077e5d1399.


Vendors - safely retrying a create request

If a timeout occurs or the response is lost after sending a request, do not create a second record immediately. Repeat the exact same request with the same key:

Idempotency-Key: public-api-vendors-create-erp-vendor-2026-001

The body must be identical, and the key should belong to this one logical operation only. Repeating it with the same key will not create a second Vendor. Do not reuse it for another record, update or deletion.

Idempotency applies to mutations. Give every new write a new, unique key.


Vendors - reading one record

After creating or finding a vendor, read it by the UUID returned by the API:

VENDOR_ID="a8156781-3b1c-4fa5-9cf2-05077e5d1399"

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

A 200 OK response contains data.itemType: vendor; the current ETag is present in the HTTP header and data.meta.etag. Do not use a source-system identifier instead of a UUID unless you first search for the record.


Vendors - partial update with an ETag

First read the record and use the returned ETag. PATCH changes only the properties sent in attributes:

CURRENT_ETAG='"ao_LJiJqs-uhBu9oDENCFJH6JY8qwbl_vt77Gl5cjGQ"'

curl --request PATCH --url "$BASE_URL/api/v1/vendors/$VENDOR_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-vendors-update-20260905111218" \
  --data '{"attributes":{"displayName":"Northwind Technology Services - purchasing department","description":"Vendor data updated by the integration."}}'

A successful response has status 200 OK. Do not send properties you do not intend to update. After success, replace the stored ETag with the new value, for example "ek44P2KnmKSAB1xX4Ycs_NgIn0I3NLoDdqsezEUgBTY".


Vendors - protecting against overwriting changes

If two processes read the same record, the second one may already hold an old version. The Public API rejects that update with code if_match_failed and status 412 Precondition Failed:

{
  "type": "https://docs.codenica.com/errors/if_match_failed",
  "title": "Precondition failed.",
  "status": 412,
  "detail": "The supplied ETag is not the current vendor version.",
  "code": "if_match_failed"
}

Missing If-Match on an update or deletion returns 428 Precondition Required with code if_match_required. After 412 or 428, read the record again, inspect its current state and only then decide whether to retry. Do not send a random ETag.


Vendors - limited relationship catalogue

Not every object available in the system can be a Vendor relationship target. The source of truth is relationshipTargets returned by /api/v1/vendors/schema. The current model exposes:

documents
notes
worktasks
requesteditems

Do not link Vendors to clients or assets. Do not infer support for another collection just because it appears in capabilities.resources. The installation-wide resource list is broader than the relationship-target list for one object.

Vendor object relationships do not use relationshipType. Do not send it in the body or append relationshipType=related to the query string. If a file endpoint uses relationshipType=documentation or relationshipType=manual, that value is file metadata and does not mean a Vendor relationship with another object.


Vendors - adding and reading a relationship

Read a fresh Vendor ETag before changing a relationship. The relationship body contains the target, collection and, when required by the target object, its targetItemType:

{
  "targetId": "31fe2881-6236-4100-9a87-2c018cbaf709",
  "targetDataSet": "documents",
  "targetItemType": "warranty"
}
curl --request POST --url "$BASE_URL/api/v1/vendors/$VENDOR_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-vendors-relationship-document-a-20260905111218" \
  --data '{"targetId":"31fe2881-6236-4100-9a87-2c018cbaf709","targetDataSet":"documents","targetItemType":"warranty"}'

A successful add returns 201 Created. Read the relationships separately:

curl --request GET --url "$BASE_URL/api/v1/vendors/$VENDOR_ID/relationships?targetDataSet=documents&page=1&pageSize=50" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

The response includes values such as targetId, targetDataSet, targetItemType, customId and status. The relationship list does not contain a relationshipType parameter.


Vendors - relationship batches and removing a link

Use relationships:batch to add or remove several relationships in one request:

{
  "add": [
    {
      "targetId": "31eed973-79cf-4650-ac0e-1e3ef5513d9f",
      "targetDataSet": "documents",
      "targetItemType": "warranty"
    }
  ],
  "remove": []
}
curl --request POST --url "$BASE_URL/api/v1/vendors/$VENDOR_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-vendors-relationship-batch-20260905111218" \
  --data @vendor-relationships-batch.json

The result contains the counters added, removed and skipped. Remove one relationship with:

curl --request DELETE --url "$BASE_URL/api/v1/vendors/$VENDOR_ID/relationships/documents/31fe2881-6236-4100-9a87-2c018cbaf709" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $CURRENT_ETAG" \
  --header "Idempotency-Key: public-api-vendors-relationship-delete-20260905111218"

Do not add relationshipType. Read the collection again after the operation to confirm the relationship state.


Vendors - listing files

Files are a separate collection attached to the vendor record:

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

An empty collection includes values such as items: [], totalItems: 0 and hasNextPage: false. After every file operation, read the collection again because it shows the actual isMain, relationshipType, size and download address.


Vendors - uploading a file

Read the current Vendor ETag before uploading. The upload uses a multipart request:

curl --request POST --url "$BASE_URL/api/v1/vendors/$VENDOR_ID/files?makeMain=true&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-vendors-file-upload-20260905111218" \
  --form "[email protected];type=text/plain"

Here relationshipType=documentation describes the file, not an object relationship. A 201 Created response includes the file identifier, name, content type, size and downloadUrl. Confirm through the list that the file has isMain: true.

Read the upload limit from data.capabilities.limits.maxUploadBytes. In the example installation it was 20971520 bytes.


Vendors - downloading a file and changing the primary file

Download the content through downloadUrl or the equivalent endpoint:

FILE_ID="025222b9-abef-4bad-a2ba-28229a0d73fb"

curl --request GET --url "$BASE_URL/api/v1/vendors/$VENDOR_ID/files/$FILE_ID/content" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --output vendors-primary-downloaded.txt

The response should contain 200 OK, the correct Content-Type and a Content-Disposition header. To add a second file without changing the primary one, use makeMain=false and, for example, relationshipType=manual. Then set it as primary:

curl --request PUT --url "$BASE_URL/api/v1/vendors/$VENDOR_ID/files/cc182dea-47d3-4ca2-818b-c639cde5a124/main" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $CURRENT_ETAG" \
  --header "Idempotency-Key: public-api-vendors-file-set-main-20260905111218"

After reading the list again, the new file has isMain: true and the previous one has isMain: false.


Vendors - attaching an existing file

You can attach a file stored with one Vendor to another record without uploading its content again. This is a file operation, so relationshipType is file metadata here:

TARGET_VENDOR_ID="4bfece8f-5bb3-438c-a95b-f14ccf93cce3"
TARGET_ETAG='"l5sRayy308rVRi4PNmUReFFcJGowi0KZUi8-hOGGlr0"'

curl --request POST --url "$BASE_URL/api/v1/vendors/$TARGET_VENDOR_ID/files/2a1f9727-0990-405d-b22c-fbd93273cc6e?makeMain=true&relationshipType=manual" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $TARGET_ETAG" \
  --header "Idempotency-Key: public-api-vendors-file-attach-20260905111218"

Detaching removes the connection from the target Vendor but does not delete the file from its owner record:

curl --request DELETE --url "$BASE_URL/api/v1/vendors/$TARGET_VENDOR_ID/files/2a1f9727-0990-405d-b22c-fbd93273cc6e" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $TARGET_ETAG" \
  --header "Idempotency-Key: public-api-vendors-file-detach-20260905111218"

After detaching, check the file list for both the target Vendor and the owner.


Vendors - deleting a file

Deleting a file also requires the current Vendor ETag:

curl --request DELETE --url "$BASE_URL/api/v1/vendors/$VENDOR_ID/files/cc182dea-47d3-4ca2-818b-c639cde5a124" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $CURRENT_ETAG" \
  --header "Idempotency-Key: public-api-vendors-file-delete-20260905111218"

If you delete the current primary file, the system may automatically choose another remaining file as primary. After 200 OK, read the list again and check totalItems and isMain. Detaching a file is not the same as deleting the owner's file.


Vendors - statistics and field values

Statistics help you inspect how data is distributed across vendor records:

curl --request GET --url "$BASE_URL/api/v1/vendors/stats?field=status&limit=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

The result may contain the total number of records, the field name and values with counts. Values are returned from your database. For example, active, Active and active supplier may be different entries when they come from different sources.

Use values to build filter suggestions:

curl --request GET --url "$BASE_URL/api/v1/vendors/values?field=status&search=Act&limit=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Statistics and values are read-only operations and do not change data.


Vendors - batch creation

A batch can create several vendor records in one request. Each item contains operation: create and a create object:

{
  "items": [
    {
      "operation": "create",
      "create": {
        "attributes": {
          "customId": "ERP-VENDOR-BATCH-A",
          "name": "Northwind Batch A",
          "email": "[email protected]",
          "category": "Technology",
          "type": "Supplier",
          "role": "Supplier",
          "status": "Active"
        }
      }
    },
    {
      "operation": "create",
      "create": {
        "attributes": {
          "customId": "ERP-VENDOR-BATCH-B",
          "name": "Northwind Batch B",
          "email": "[email protected]",
          "category": "Technology",
          "type": "Supplier",
          "role": "Supplier",
          "status": "Active"
        }
      }
    }
  ]
}
curl --request POST --url "$BASE_URL/api/v1/vendors:batch" \
  --header "Content-Type: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "Idempotency-Key: public-api-vendors-batch-create-20260905111218" \
  --data @vendors-batch-create.json

The result contains the status of the complete request and the status of each operation in data.items. A successful batch may return 200 OK, succeeded: 2, failed: 0 and two items with status 201. Store every new UUID and ETag separately.


Vendors - batch updates, deletion and partial success

A batch update requires id, the current ifMatch and an update object:

{
  "items": [
    {
      "operation": "update",
      "id": "76d1698d-dfdb-47a3-9d84-3e476fa7894c",
      "ifMatch": "ETAG_FROM_GET",
      "update": {
        "attributes": {
          "displayName": "Northwind Batch A - updated",
          "description": "Change made through the Vendors batch operation."
        }
      }
    },
    {
      "operation": "invalid"
    }
  ]
}

If one operation succeeds and another is invalid, the API returns 207 Multi-Status. Do not treat 207 as complete failure or complete success. Process every data.items entry separately. Deletion follows the same rule: send the identifier and current ifMatch:

{
  "operation": "delete",
  "id": "9462d541-c405-44bf-9c75-000d8b862136",
  "ifMatch": "ETAG_FROM_GET"
}

After a batch delete, perform a control GET. The deleted record should return 404 with code vendor_not_found.


Vendors - deleting a vendor record

Read the record again before deletion so that you have a current ETag:

curl --request DELETE --url "$BASE_URL/api/v1/vendors/$VENDOR_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-vendors-delete-20260905111218"

A successful deletion returns 200 OK and data: true. A later read returns 404 Not Found with code vendor_not_found. You can also list by your own customId and confirm totalItems: 0.

If the DELETE response was lost, do not immediately send a new operation with another key. Keep the original Idempotency-Key, check the record state and only then decide what to do.


Vendors - errors, limits and the complete integration path

Public API errors use the Problem Details format. Base application logic on the stable code field and keep requestId when reporting a problem.

  • 400 - invalid field, relationship target or batch item;
  • 401 - missing or invalid credentials;
  • 403 - missing scope or permission;
  • 404 - record, file or target does not exist or is not visible;
  • 409 - data or uniqueness conflict;
  • 412 - stale ETag;
  • 413 - file exceeds the limit;
  • 422 - domain validation error;
  • 428 - missing If-Match or Idempotency-Key;
  • 429 - request limit exceeded;
  • 207 - batch completed partially.

Read X-RateLimit-Limit and X-RateLimit-Remaining. On 429, use Retry-After when returned and increase the delay between attempts. Never log X-Codenica-Client-Secret, secrets or sensitive file contents.

Recommended order:

  1. Set BASE_URL to the correct installation.
  2. Create a key under Settings - API - API Keys with minimum scopes.
  3. Read /api/v1/context and /api/v1/vendors/schema.
  4. Create a Vendor with a unique Idempotency-Key, then store its UUID and ETag.
  5. Read lists with pagination, filters and optional include.
  6. Update the record only with the current If-Match.
  7. Add relationships only to schema targets and without relationshipType.
  8. Use dedicated file endpoints and check the file list after each change.
  9. For larger sets, inspect the result of every batch operation.
  10. Read the current ETag before deletion and perform a control GET afterwards.

The examples use the demonstration prefix PUBLIC-API-VEN-20260905111218. Your integration must use identifiers returned by your own database, not the values shown on this page.