Notizen in Codenica API

Um mit Notizen über Codenica API zu arbeiten, erstellen Sie zunächst einen Schlüssel in den Codenica-Einstellungen. Wenn noch kein Schlüssel vorhanden ist, öffnen Sie Codenica API - Einführung in einem neuen Tab. Dort werden die gemeinsamen Regeln für die Ausstellung von Schlüsseln, die Aufbewahrung des Secrets und die Authentifizierung erklärt.

Der technische Modulname lautet notes, der Typ eines einzelnen Objekts note. Eine Notiz ist ein in Codenica gespeicherter Eintrag. Sie kann einen Titel, eine Beschreibung, einen Status, eine Priorität, eine Kategorie, einen Link und Dateien enthalten. Das Feld isPrivate steuert die Sichtbarkeit entsprechend den vorhandenen Berechtigungen, während pin die Anheftstufe des Eintrags festlegt.

Die folgenden Abschnitte behandeln die API-Adresse, Scopes, Context, Schema, Felder, Listen, Filter, Erstellung, Idempotenz, ETag, Bearbeitung, Anheften, Beziehungen, den Autor, Dateien, Batch-Vorgänge und das Löschen.

Die Beispiele verwenden das Präfix PUBLIC-API-NOTE-20260905141812. Ersetzen Sie es durch Ihre eigene Kennung und passen Sie Adressen, IDs und Feldwerte an die Daten in Ihrer Datenbank an.


Notizen - API-Adresse und Installationsauswahl

Alle Routen für Notizen beginnen mit:

{BASE_URL}/api/v1/notes

BASE_URL ist die Adresse des Codenica-Servers ohne das abschließende /api/v1. Für Codenica Cloud verwenden Sie die öffentliche Domain, die dem betreffenden Unternehmen zugewiesen ist:

export BASE_URL="https://ihr-unternehmen.codenica.com"

In der standardmäßigen On-Premise-Installation lautet die lokal von Codenica Discovery registrierte Adresse:

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

Wenn der Administrator die Installation unter einer Unternehmensdomain, über einen Reverse Proxy, mit HTTPS oder an einem anderen Port veröffentlicht hat, verwenden Sie die exakt mitgeteilte Adresse:

export BASE_URL="https://api.ihr-unternehmen.example"

Verwenden Sie localhost nicht, wenn das Integrationsprogramm auf einem anderen Computer als die API läuft. Die verwendete Datenbank wird anhand der Adresse ausgewählt, mit der sich die Integration verbindet. Senden Sie tenantId weder im Body noch im Query-String.


Notizen - API-Schlüssel und Lizenzlimits

Erstellen Sie einen API-Schlüssel in Codenica unter Einstellungen - API - API Keys. Das Secret wird nur einmal angezeigt, direkt nach der Erstellung oder Rotation des Schlüssels. Speichern Sie dann Client ID und Client Secret im sicheren Speicher der Integration.

Codenica API ist mit den Lizenzen Plus und Enterprise verfügbar. Plus erlaubt bis zu 50 aktive Schlüssel, Enterprise bis zu 100. Starter enthält Codenica API nicht. Erstellen Sie für jede Anwendung und Umgebung einen eigenen Schlüssel, damit Sie Scopes verwalten, das Secret rotieren oder den Zugriff unabhängig entfernen können.

Lizenz
API-Zugriff
Maximale Anzahl aktiver Schlüssel
Starter
Nicht verfügbar
0
Plus
Verfügbar
50
Enterprise
Verfügbar
100

Beim Löschen eines Schlüssels wird sein Datensatz entfernt und ein Platz im Limit frei. Nach Ablauf des Gültigkeitsdatums authentifiziert der Schlüssel keine Anfragen mehr, bleibt aber bis zum Löschen in der Liste. Wenn beim Erstellen kein Enddatum festgelegt wird, beträgt die Standardgültigkeit 90 Tage. Die maximale Gültigkeitsdauer eines Schlüssels beträgt 5 Jahre.


Notizen - Authentifizierung und sichere Anfragen

Authentifizieren Sie jede Codenica-API-Anfrage mit den beiden Schlüssel-Headern:

export CLIENT_ID="cna_ihre_client_id"
export CLIENT_SECRET="cns_ihr_client_secret"

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

Eine externe Integration benötigt weder das JWT des Administrators noch Cookies aus dem Codenica-Panel. Legen Sie den Schlüssel nicht in einem Repository, in Browser-Code, in einer URL, in der Shell-History oder in Logs ab. Verwenden Sie außerhalb lokaler Tests HTTPS.

Bewahren Sie meta.requestId aus der Antwort auf. Damit lässt sich eine bestimmte Anfrage diagnostizieren, es ist jedoch nicht die Notiz-ID und darf nicht als Secret behandelt werden.


Notizen - Verbindungskontext prüfen

Lesen Sie vor dem ersten Schreibvorgang den Context. So bestätigen Sie, dass die Adresse auf die gewünschte Datenbank zeigt und der ausgewählte Schlüssel die benötigten Scopes besitzt:

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"

Prüfen Sie in der Antwort:

  • data.apiVersion und data.contractVersion;
  • data.tenant.id, data.tenant.name und data.tenant.resolvedDomain;
  • data.caller.authentication mit dem Wert api_key;
  • das Vorhandensein von notes in data.capabilities.resources;
  • die dem Schlüssel zugewiesenen Scopes;
  • die Limits für Seiten, Beziehungen, Dateien und Anfragen.

Wenn der Context auf eine andere Datenbank zeigt oder ein erforderlicher Scope fehlt, stoppen Sie die Integration und korrigieren Sie Adresse oder Schlüssel. Scopes können nicht für eine einzelne Anfrage ergänzt werden.


Notizen - Scopes und Berechtigungen

Für die vollständige Notizen-Unterstützung benötigen Sie Scopes passend zu den von Ihrer Integration verwendeten Vorgängen:

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

Für gewöhnliche Lesevorgänge genügt notes:read. Schema und Statistiken verwenden zusätzlich notes:schema und notes:stats. Für Erstellen, Bearbeiten und Löschen ergänzen Sie je nach Bedarf notes:write und notes:delete.

  • notes:relationships:read und notes:relationships:write gelten für Objektbeziehungen;
  • notes:users:read gilt für das Lesen des Autors;
  • notes:files:read und notes:files:write gelten für Auflisten, Herunterladen, Hochladen, Zuordnen und Löschen von Dateien;
  • notes:stats gilt für Statistiken und Feldwerte, die für Filter verwendet werden;
  • notes:pin:write ist zum Anheften und Lösen erforderlich;
  • verwenden Sie technische Scopes nur, wenn die Integration im Schema als technisch markierte Felder oder customValues-Regeln benötigt.

Wenn die Integration Beziehungziele selbst sucht, vergeben Sie zusätzlich die passenden Lese-Scopes, zum Beispiel assets:read, clients:read, vendors:read, documents:read, tickets:read, changes:read, problems:read, releases:read, approvals:read, confirmations:read, worktasks:read und requesteditems:read. Die Scopes eines Schlüssels ersetzen weder Benutzerberechtigungen noch den Zugriff auf einen Standort oder eine Abteilung.


Notizen - Schema und Felder

Das Schema zeigt, welche Felder in der ausgewählten Datenbank gelesen und geschrieben werden können. Rufen Sie es vor dem Erstellen eines Formulars oder einer Feldzuordnung ab:

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

Die Antwort enthält unter anderem data.itemType, data.fields und data.relationshipTargets. Der feste Wert von itemType für dieses Modul ist note. Prüfen Sie für jedes Feld readable, writable, required, technical, unique und maxLength. Erstellen Sie die Zuordnung nicht ausschließlich anhand der Beispiele in diesem Artikel, da sich die Feldkonfiguration zwischen Datenbanken unterscheiden kann.

Das Schema zeigt außerdem, ob Beziehungen zu einem bestimmten Datensatz verfügbar sind. Verwenden Sie nur Ziele, die für den aktuellen Schlüssel und Benutzer zurückgegeben werden.


Notizen - beschreibbare und Systemfelder

Der öffentliche Katalog der Geschäftsfelder für Notizen umfasst:

customId
location
department
isPrivate
tag
link
title
status
priority
category
description

Die wichtigsten Feldgrenzen:

Feld
Typ
Maximale Länge
customId
string
500
location, department
string
je 300
isPrivate
boolean
-
tag, link
string
je 2000
title
string
1000
status, priority, category
string
je 300
description
string
10000

pin est renvoyé dans les attributs, mais ne peut pas être modifié via attributes. Utilisez son endpoint dédié. Les champs système et techniques en lecture seule comprennent notamment :

id
itemType
pin
creator
updater
dateCreated
dateUpdated
importId
importSource
dateImported

id et itemType font partie de la ressource. Les dates, l'auteur et le dernier éditeur sont attribués par le système. N'essayez pas de les modifier via attributes.


Notizen - zentrale Endpoints

Die wichtigsten Routen des Moduls notes sind:

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

Jede Route erfordert eine Authentifizierung. Vorgänge, die Daten ändern, benötigen außerdem Idempotency-Key; versionsgeschützte Vorgänge benötigen den aktuellen If-Match-Wert. Die genauen Anforderungen finden Sie in den Antworten von Context und Schema.


Notizen - Auflisten und Paginierung

Die Liste ist paginiert. Dieses Beispiel ruft die erste Seite ab und sortiert Notizen von neu nach alt:

curl --request GET --url "$BASE_URL/api/v1/notes?itemType=note&page=1&pageSize=20&sort=dateCreated&direction=desc" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Die Antwort enthält unter anderem:

data.items
data.page
data.pageSize
data.totalItems
data.totalPages
data.hasNextPage

Das maximale pageSize stammt aus dem Context und beträgt normalerweise 100. Rufen Sie weitere Seiten ab, solange data.hasNextPage den Wert true hat. Gehen Sie nicht davon aus, dass die erste Seite die vollständige Liste enthält.


Notizen - Suche, Filter und Sortierung

Sie können Gleichheitsfilter für Felder wie customId, location, department, isPrivate, tag, link, title, status, priority und category verwenden. Dieses Beispiel sucht private offene Notizen aus der IT-Abteilung:

curl --request GET --url "$BASE_URL/api/v1/notes?isPrivate=true&department=IT&status=Open&page=1&pageSize=50" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

search durchsucht Textfelder der Notiz, unter anderem customId, tag, link, title, status, priority, category und description:

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

Der Parameter filter kann mehrfach vorkommen. Das Format lautet field:operator:value:

filter=status:eq:Open
filter=status:ne:Closed
filter=title:contains:server
filter=title:startswith:Public API
filter=isPrivate:eq:true
filter=description:notempty:

Unterstützte Operatoren sind unter anderem eq, ne, gt, gte, lt, lte, contains, startswith, endswith, empty und notempty. Verfügbar sind außerdem die Kurzformen =, !=, ge, le, sw und ew. Sie können createdAfter, createdBefore, updatedAfter und updatedBefore ergänzen. Sortieren Sie nur nach einem im Schema erlaubten Feld mit direction=asc oder direction=desc. URL-encodieren Sie Werte mit Leerzeichen oder Sonderzeichen.


Notizen - Feldauswahl und eingeschlossene Daten

Wenn die Integration nur einen Teil der Daten benötigt, begrenzen Sie die Antwort mit fields:

curl --request GET --url "$BASE_URL/api/v1/notes?fields=customId%2Ctitle%2Cstatus%2Cpriority%2CisPrivate&page=1&pageSize=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Sie können eine einzelne Notiz zusammen mit ihren Dateien, Beziehungen und Autoreninformationen abrufen:

curl --request GET --url "$BASE_URL/api/v1/notes/{NOTE_ID}?fields=customId%2Ctitle%2Cdescription%2Cstatus&include=files%2Crelationships%2Cusers" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Zulässige include-Werte sind files, relationships und users. Jeder Wert benötigt den entsprechenden Lese-Scope. fields=* fordert alle für den Schlüssel verfügbaren Felder an, technische Felder werden jedoch nur mit dem passenden technischen Scope zurückgegeben.


Notizen - Statistiken und Feldwerte

Statistiken zählen sichtbare Notizen und gruppieren sie nach einem ausgewählten Feld:

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

Beispielantwort:

{
  "data": {
    "total": 42,
    "field": "category",
    "values": [
      {
        "value": "Integration",
        "count": 12
      },
      {
        "value": "Hardware",
        "count": 8
      }
    ]
  },
  "meta": {
    "requestId": "request-id-from-response"
  }
}

Ohne field gibt der Endpoint die Gesamtzahl der Notizen zurück. limit akzeptiert Werte von 1 bis 500. Die Ergebnisse berücksichtigen die Sichtbarkeit des Benutzers.

Der Endpoint values liefert eindeutige Werte, die zum Aufbau von Auswahllisten verwendet werden können:

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

Beispielantwort:

{
  "data": {
    "field": "status",
    "values": [
      "Open",
      "Open - waiting"
    ]
  },
  "meta": {
    "requestId": "request-id-from-response"
  }
}

Beide Endpoints sind schreibgeschützt und ändern keine Notizen. Die Antwort von values ist keine Datensatzliste, sondern eine Liste eindeutiger Werte eines bestimmten Feldes.


Notizen - einen Datensatz erstellen

Setzen Sie den technischen Typ note in den Body und die Geschäftsfelder in attributes. In einer praktischen Integration sollten Sie Titel und Beschreibung auch dann speichern, wenn das Schema sie nicht als Pflichtfelder kennzeichnet:

{
  "itemType": "note",
  "attributes": {
    "customId": "NOTE-ERP-2026-0001",
    "location": "Warsaw",
    "department": "IT",
    "isPrivate": true,
    "tag": "erp,public-api,notes",
    "link": "https://erp.example.com/notes/0001",
    "title": "Server integration check",
    "status": "Open",
    "priority": "Normal",
    "category": "Integration",
    "description": "Note created by an external ERP system."
  }
}

Speichern Sie den Body als note-create.json und senden Sie ihn mit einem eindeutigen Idempotenzschlüssel:

curl --request POST --url "$BASE_URL/api/v1/notes" \
  --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: notes-create-20260905-0001" \
  --data-binary @note-create.json

Eine erfolgreiche Erstellung liefert 201 Created. Die Antwort enthält die UUID in data.id, data.itemType=note, die gespeicherten Attribute, Systemdaten und data.meta.etag. Lassen Sie id vom System vergeben.

isPrivate steuert die Sichtbarkeit und ist keine Verschlüsselung. Speichern Sie keine Passwörter, Tokens, Client Secrets oder anderen vertraulichen Daten in einer Notiz.


Notizen - Erstellung sicher wiederholen

Wenn der Client nicht weiß, ob die erste Anfrage angekommen ist, wiederholen Sie exakt dieselbe Anfrage mit demselben Idempotency-Key:

curl --request POST --url "$BASE_URL/api/v1/notes" \
  --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: notes-create-20260905-0001" \
  --data-binary @note-create.json

Das Wiederholen derselben logischen Anfrage darf keine zweite Notiz erstellen. Die Antwort sollte dieselbe UUID und dasselbe Operationsergebnis ausweisen. Verwenden Sie den Schlüssel nicht für einen anderen Body, Endpoint oder Vorgang. Jede neue Mutation benötigt einen neuen Idempotency-Key.

Erstellen Sie nach einem Timeout nicht sofort einen weiteren Datensatz. Wiederholen Sie zuerst die vorherige Anfrage mit demselben Body und Idempotenzschlüssel.


Notizen - Datensatz lesen und ETag verwenden

Rufen Sie nach der Erstellung oder vor einer Änderung eine einzelne Notiz ab und speichern Sie UUID und aktuellen ETag:

export NOTE_ID="d7a83ba0-41ce-44f6-b2e9-7ddcec716234"

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

Der ETag steht im HTTP-Header ETag, in data.meta.etag und in der Hülle meta.etag. Beispielantwort für eine einzelne Ressource:

{
  "data": {
    "id": "d7a83ba0-41ce-44f6-b2e9-7ddcec716234",
    "itemType": "note",
    "attributes": {
      "customId": "NOTE-ERP-0001",
      "title": "Server integration check",
      "isPrivate": true
    },
    "meta": {
      "customId": "NOTE-ERP-0001",
      "etag": "\"etag-value\""
    }
  },
  "meta": {
    "requestId": "request-id-from-response",
    "etag": "\"etag-value\""
  }
}

Nach jeder erfolgreichen Mutation kann sich der ETag ändern, auch nach einer Änderung an Beziehung, Datei oder Pin. Ersetzen Sie den vorherigen Wert, bevor Sie die nächste Änderung senden.


Notizen - partielle Aktualisierung mit If-Match

PATCH ändert nur Felder, die in attributes gesendet werden. Verwenden Sie den aktuellen ETag und einen eigenen Idempotenzschlüssel:

export NOTE_ETAG='"etag-from-the-latest-response"'

curl --request PATCH --url "$BASE_URL/api/v1/notes/$NOTE_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: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-update-20260905-0001" \
  --data-raw '{
    "attributes": {
      "title": "Updated server integration check",
      "description": "The note was changed by an API workflow.",
      "status": "In progress",
      "priority": "High",
      "isPrivate": false
    }
  }'

Sie müssen nicht alle Felder senden. Ein optionaler Wert kann mit null geleert werden, wenn das Schema der Datenbank dies zulässt:

{
  "attributes": {
    "link": null,
    "description": null
  }
}

Ein leeres PATCH ohne Attribute, Wertregeln oder Beziehungsänderungen wird abgelehnt. Systemfelder und pin gehören nicht in eine gewöhnliche Aktualisierung.


Notizen - veralteter ETag und fehlendes If-Match

Mutationen an Notizen erfordern den Header If-Match. Ohne diesen Header gibt die API 428 Precondition Required zurück:

{
  "type": "https://docs.codenica.com/errors/if_match_required",
  "title": "Precondition required.",
  "status": 428,
  "detail": "Send the ETag returned by GET in the If-Match header.",
  "instance": "/api/v1/notes/{id}",
  "code": "if_match_required",
  "requestId": "request-id-from-response"
}

Wenn der gesendete ETag veraltet ist, gibt die API 412 Precondition Failed zurück:

{
  "type": "https://docs.codenica.com/errors/if_match_failed",
  "title": "Precondition failed.",
  "status": 412,
  "detail": "The supplied ETag is not the current note version.",
  "instance": "/api/v1/notes/{id}",
  "code": "if_match_failed",
  "requestId": "request-id-from-response"
}

Nach 412 rufen Sie die Notiz erneut ab, vergleichen Sie den aktuellen Zustand mit der gewünschten Änderung und senden Sie erst dann ein neues PATCH mit dem neuen ETag. Wiederholen Sie nicht endlos dieselbe Anfrage mit dem alten Wert.


Notizen - Anheften und Lösen

Das Feld pin ist bei einer gewöhnlichen Aktualisierung schreibgeschützt. Verwenden Sie zum Festlegen der Anheftstufe die eigene Route:

curl --request POST --url "$BASE_URL/api/v1/notes/$NOTE_ID/pin" \
  --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: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-pin-20260905-0001" \
  --data-raw '{"pin":3}'

Zulässig sind Ganzzahlen von 0 bis 3. Zum Lösen der Notiz senden Sie null:

curl --request POST --url "$BASE_URL/api/v1/notes/$NOTE_ID/pin" \
  --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: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-unpin-20260905-0001" \
  --data-raw '{"pin":null}'

Der Vorgang erfordert notes:pin:write, vorhandenen Zugriff auf die Notiz und den aktuellen ETag. Rufen Sie nach dem Erfolg den neuen ETag ab. Setzen Sie den Pin nicht über attributes.pin und senden Sie keinen leeren Body.

Angeheftete Notizen können Sie mit einem Filter suchen:

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

Notizen - verfügbare Beziehungen zu Objekten

Eine Notiz kann mit Zielen verbunden werden, die vom schema zurückgegeben werden. Der aktuelle Katalog umfasst:

assets        - asset
clients       - client
vendors       - vendor
documents     - document
tickets       - ticket
changes       - change
problems      - problem
releases      - release
approvals     - approval
confirmations - confirmation
worktasks     - worktask
requesteditems - requesteditem

Eine Notiz kann keine Beziehung zu sich selbst erstellen. Bei den meisten Zielen besteht eine Beziehung aus ID, Datensatz und Objekttyp; lassen Sie relationshipType daher weg. Das aktuelle Beziehungsmodell für confirmations speichert diesen Parameter. Beispiel für ein Confirmation-Ziel:

{
  "targetId": "6efaebb6-8650-4674-8478-34fd3e601427",
  "targetDataSet": "confirmations",
  "targetItemType": "confirmation",
  "relationshipType": "client"
}

Die API prüft die UUID, die Übereinstimmung von targetDataSet und targetItemType, die Existenz und Sichtbarkeit des Ziels, Berechtigungen und Duplikate. Wenn das Schema ein Ziel nicht zurückgibt, verwenden Sie es nicht in der Integration.


Notizen - Beziehungen hinzufügen, lesen und entfernen

Lesen Sie Beziehungen über die Collection:

curl --request GET --url "$BASE_URL/api/v1/notes/$NOTE_ID/relationships?targetDataSet=assets&targetItemType=asset&page=1&pageSize=50" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Das Hinzufügen einer Asset-Beziehung erfordert notes:relationships:write, den aktuellen ETag und einen Idempotenzschlüssel:

curl --request POST --url "$BASE_URL/api/v1/notes/$NOTE_ID/relationships" \
  --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: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-asset-relationship-20260905-0001" \
  --data-raw '{
    "targetId": "71ce005d-4cb8-4c9d-8239-ffe7e5e9f3e9",
    "targetDataSet": "assets",
    "targetItemType": "asset"
  }'

Ein Collection-Element kann targetId, targetDataSet, targetItemType, customId und name enthalten. Das erneute Hinzufügen derselben Beziehung ist sicher und sollte kein Duplikat erzeugen.

Eine Beziehung entfernen:

curl --request DELETE --url "$BASE_URL/api/v1/notes/$NOTE_ID/relationships/assets/71ce005d-4cb8-4c9d-8239-ffe7e5e9f3e9" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-asset-relationship-delete-20260905-0001"

Für confirmations ergänzen Sie in der Query relationshipType=client. Eine erfolgreiche Antwort hat den Status 200 und data=true. Lesen Sie die Notiz nach jeder Beziehungsänderung erneut, da sich ihr ETag ändern kann.


Notizen - Beziehungen gesammelt ändern

Verwenden Sie relationships:batch, um mehrere Beziehungen hinzuzufügen oder zu entfernen. Eine Anfrage kann die Arrays add und remove enthalten:

curl --request POST --url "$BASE_URL/api/v1/notes/$NOTE_ID/relationships: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 "If-Match: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-relationships-batch-20260905-0001" \
  --data-raw '{
    "add": [
      {
        "targetId": "71ce005d-4cb8-4c9d-8239-ffe7e5e9f3e9",
        "targetDataSet": "assets",
        "targetItemType": "asset"
      }
    ],
    "remove": [
      {
        "targetId": "385b51cc-fb4d-4599-9b82-3c5b66705ccd",
        "targetDataSet": "clients",
        "targetItemType": "client"
      }
    ]
  }'

Die Antwort enthält Zähler:

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

Jedes Ziel muss sichtbar sein und zum Beziehungskatalog passen. Das erneute Senden einer bereits vorhandenen Beziehung kann als skipped gezählt werden. Leere add- und remove-Arrays werden abgelehnt, wenn sie keine Operation enthalten. Ein Beziehungs-Batch ändert auch den ETag der Quellnotiz.


Notizen - Autorenbeziehung

Der Autor wird durch den bestehenden Ablauf zur Erstellung einer Notiz gesetzt. Lesen Sie ihn über die Benutzerbeziehung:

curl --request GET --url "$BASE_URL/api/v1/notes/$NOTE_ID/user-relationships?relationshipType=author&page=1&pageSize=20" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Beispiel für ein Antwort-Element:

{
  "targetId": "8e9cbff3-340f-41f6-97ec-6997bb915829",
  "targetDataSet": "users",
  "relationshipType": "author",
  "displayName": "Fred Savage",
  "email": "[email protected]",
  "role": "Administrator"
}

Das Lesen erfordert notes:users:read und die passende Berechtigung zum Auflisten von Notizen. Der aktuelle Vertrag stellt nur die Beziehung author bereit. Es gibt keinen öffentlichen POST- oder DELETE-Endpoint zum Ändern oder Entfernen des Autors. Senden Sie den Autor weder in relationships noch in attributes.


Notizen - Dateien

Notizen können Dateien enthalten, unterstützen aber keine Festlegung einer Hauptdatei. In jeder Dateiresource ist isMain gleich false. Verfügbare Routen:

GET    /api/v1/notes/{NOTE_ID}/files
POST   /api/v1/notes/{NOTE_ID}/files
POST   /api/v1/notes/{NOTE_ID}/files/{FILE_ID}
DELETE /api/v1/notes/{NOTE_ID}/files/{FILE_ID}
GET    /api/v1/notes/{NOTE_ID}/files/{FILE_ID}/content

Prüfen Sie zunächst die Dateiliste:

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

Ein Listenelement enthält unter anderem id, name, fileName, contentType, size, relationshipType, isMain und downloadUrl. Auflisten und Herunterladen erfordern notes:files:read. Hochladen, Zuordnen und Löschen erfordern notes:files:write, Systemberechtigungen, den aktuellen ETag und einen Idempotenzschlüssel.

Laden Sie eine Datei als multipart/form-data hoch:

curl --request POST --url "$BASE_URL/api/v1/notes/$NOTE_ID/files?relationshipType=documentation" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-file-upload-20260905-0001" \
  --form "file=@./note-evidence.txt;type=text/plain"

Ein erfolgreicher Upload liefert 201 Created und die Datei-ID. relationshipType kann den Zweck beschreiben, zum Beispiel documentation, manual oder evidence. Lesen Sie die Größenbegrenzung aus data.capabilities.limits.maxUploadBytes.

Laden Sie den Inhalt über den authentifizierten Pfad herunter:

curl --request GET --url "$BASE_URL/api/v1/notes/$NOTE_ID/files/$FILE_ID/content" \
  --header "Accept: application/octet-stream" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --output ./note-evidence.downloaded.txt

Behandeln Sie downloadUrl als API-Pfad und nicht als öffentlichen anonymen Link. Der Endpoint content liefert Dateibytes und keine JSON-Hülle.

Wenn sich die Datei bereits im Codenica-Speicher befindet, können Sie ihre vorhandene ID zuordnen:

curl --request POST --url "$BASE_URL/api/v1/notes/$NOTE_ID/files/$FILE_ID?relationshipType=manual" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-file-attach-20260905-0001"

Eine Dateibeziehung entfernen:

curl --request DELETE --url "$BASE_URL/api/v1/notes/$NOTE_ID/files/$FILE_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-file-delete-20260905-0001"

Lesen Sie die Notiz nach jedem Dateivorgang erneut und speichern Sie den neuen ETag. Rufen Sie für Notizen nicht files/{FILE_ID}/main auf, da diese Route nicht zum Vertrag dieses Objekts gehört.


Notizen - Batch-Vorgänge

Batch verbindet das Erstellen, Aktualisieren und Löschen von Notizen in einer Anfrage. Jede Position wird einzeln verarbeitet:

curl --request POST --url "$BASE_URL/api/v1/notes: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: notes-batch-create-20260905-0001" \
  --data-raw '{
    "items": [
      {
        "operation": "create",
        "create": {
          "itemType": "note",
          "attributes": {
            "customId": "NOTE-BATCH-A",
            "title": "Batch note A",
            "description": "First note from a batch operation.",
            "category": "Integration",
            "status": "Open",
            "priority": "Normal",
            "isPrivate": false
          }
        }
      },
      {
        "operation": "create",
        "create": {
          "itemType": "note",
          "attributes": {
            "customId": "NOTE-BATCH-B",
            "title": "Batch note B",
            "description": "Second note from a batch operation.",
            "category": "Integration",
            "status": "Open",
            "priority": "Low",
            "isPrivate": true
          }
        }
      }
    ]
  }'

Eine Beispielantwort enthält succeeded, failed und das Ergebnis jeder Position:

{
  "data": {
    "succeeded": 2,
    "failed": 0,
    "items": [
      {
        "index": 0,
        "operation": "create",
        "status": 201,
        "id": "note-id-a"
      },
      {
        "index": 1,
        "operation": "create",
        "status": 201,
        "id": "note-id-b"
      }
    ]
  },
  "meta": {
    "requestId": "request-id-from-response"
  }
}

Rufen Sie vor update und delete den aktuellen ETag jeder Notiz separat ab. Senden Sie in einer Batch-Position id, ifMatch und den passenden Block update. Verwenden Sie zum Löschen operation=delete. Ein Batch ist keine Alles-oder-nichts-Transaktion. Bei Teilerfolg kann die API 207 Multi-Status zurückgeben, deshalb muss jede Position geprüft werden.


Notizen - einen Datensatz löschen

Rufen Sie die Notiz vor dem Löschen erneut ab und verwenden Sie ihren aktuellen ETag:

curl --request DELETE --url "$BASE_URL/api/v1/notes/$NOTE_ID" \
  --header "Accept: application/json" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET" \
  --header "If-Match: $NOTE_ETAG" \
  --header "Idempotency-Key: notes-delete-20260905-0001"

Das Löschen erfordert notes:delete und liefert bei Erfolg 200 OK mit data=true. Der bestehende Löschvorgang bereinigt Beziehungen entsprechend der Systemkonfiguration.

Prüfen Sie den einzelnen Datensatz nach dem Vorgang:

curl --request GET --url "$BASE_URL/api/v1/notes/$NOTE_ID" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Der erwartete Status ist 404 mit dem Code note_not_found. Prüfen Sie außerdem Ihre eigene Kennung:

curl --request GET --url "$BASE_URL/api/v1/notes?customId=NOTE-ERP-2026-0001&page=1&pageSize=10" \
  --header "X-Codenica-Client-Id: $CLIENT_ID" \
  --header "X-Codenica-Client-Secret: $CLIENT_SECRET"

Nach dem erfolgreichen Löschen sollte totalItems den Wert 0 haben. Entfernen Sie die Kennung aus dem lokalen Index der Integration oder markieren Sie sie als inaktiv.


Notizen - Fehler, Limits und Sicherheit

API-Fehler verwenden das Format Problem Details mit zusätzlichen Codenica-Feldern:

{
  "type": "https://docs.codenica.com/errors/note_not_found",
  "title": "Note not found.",
  "status": 404,
  "detail": "The note does not exist or is outside the caller's access scope.",
  "instance": "/api/v1/notes/{id}",
  "code": "note_not_found",
  "requestId": "request-id-from-response"
}

Verwenden Sie in der Anwendungslogik hauptsächlich status und code. Der Text in detail ist ein Hinweis für Menschen und kann sich ändern.

  • 400 - ungültiger Body, Parameter, UUID oder Feldwert;
  • 401 - fehlende oder ungültige Authentifizierung;
  • 403 - fehlender Scope oder fehlende Benutzerberechtigung;
  • 404 - Notiz, Datei, Beziehung oder Ziel nicht verfügbar;
  • 409 - Konflikt bei Kennung, Duplikat oder gleichzeitiger Änderung;
  • 412 - veralteter ETag;
  • 413 - Datei oder Body überschreitet das Limit;
  • 422 - ein bestehender Fachprozess hat den Vorgang abgelehnt;
  • 428 - If-Match oder Idempotency-Key fehlt;
  • 429 - Anfrage-Limit überschritten;
  • 500 oder 503 - Serverfehler oder vorübergehende Nichtverfügbarkeit.

Lesen Sie die Header X-RateLimit-Limit, X-RateLimit-Remaining und bei 429 Retry-After. Verwenden Sie kontrollierte Wiederholungen mit zunehmenden Verzögerungen. Speichern Sie Client Secret niemals in einem Repository, einer URL, Browser-Code, der Shell-History oder Logs. isPrivate ersetzt keine Verschlüsselung.


Notizen - Reihenfolge der Integration

  1. Ermitteln Sie die tatsächliche Cloud- oder On-Premise-Adresse und setzen Sie BASE_URL.
  2. Erstellen Sie unter Einstellungen - API - API Keys einen eigenen Schlüssel für Anwendung und Umgebung.
  3. Vergeben Sie nur die Scopes, die für Lesen, Schreiben, Beziehungen, Dateien, Statistiken oder Anheften benötigt werden.
  4. Senden Sie GET /api/v1/context und prüfen Sie Datenbank, Caller, Scopes und Limits.
  5. Rufen Sie GET /api/v1/notes/schema ab und erstellen Sie die Zuordnung von Feldern und Beziehungszielen.
  6. Rufen Sie eine Notizenliste mit Paginierung, Suche oder Filtern ab.
  7. Erstellen Sie den Datensatz per POST mit einem eindeutigen Idempotency-Key.
  8. Speichern Sie UUID und ETag aus der Antwort.
  9. Wiederholen Sie nach einem Timeout die identische Anfrage mit demselben Idempotenzschlüssel.
  10. Rufen Sie vor jeder Mutation einen aktuellen ETag ab.
  11. Verwenden Sie PATCH für gewöhnliche Felder und den Endpoint /pin zum Anheften.
  12. Verwenden Sie nur vom Schema zurückgegebene Beziehungsziele und den passenden targetItemType.
  13. Für confirmations senden Sie relationshipType=client; für die anderen Datensätze lassen Sie den Parameter weg.
  14. Lesen Sie die Autorenbeziehung nur aus, da es keinen öffentlichen Schreib-Endpoint gibt.
  15. Beachten Sie, dass Notizen keine Hauptdatei haben.
  16. Prüfen Sie bei Batch jeden Eintrag, da ein Teilerfolg erfolgreiche Einträge nicht zurückrollt.
  17. Nach 412 rufen Sie den Datensatz erneut ab und lösen den Konflikt.
  18. Respektieren Sie nach 429 den Wert Retry-After.
  19. Protokollieren Sie requestId, Status und Fehlercode, aber niemals das Secret.
  20. Löschen Sie nach Ende der Integration den nicht mehr benötigten API-Schlüssel.

Mit dieser Reihenfolge können Sie Notizen mit einem anderen System synchronisieren, ohne Annahmen über Felder, Sichtbarkeit, Beziehungen oder Systemdaten zu treffen.