Entwickler
API-Dokumentation
So rufen Ihre Systeme Kabel, Familien und Dateien ab und legen Anfragen an. Die Beispiele zeigen erfundene Daten einer Beispiel-Website; Ihre eigene Adresse und Ihre Daten sehen Sie erst mit einem API-Schlüssel.
Grundlagen
Basis-URL: https://testing.cablecreations.de/api/v1
- Alle Antworten sind JSON. Zeitangaben sind ISO 8601 in UTC, IDs sind undurchsichtige Zeichenketten.
- Die API liefert nur veröffentlichte Kabel und öffentliche Dateien – dasselbe, was Ihr öffentlicher Katalog zeigt.
- Datei-URLs sind absolut und dürfen dauerhaft zwischengespeichert werden: Ändert sich eine Datei, ändert sich ihr contentHash.
- Die Antworten sind ein stabiler Vertrag der Version v1. Neue Felder können hinzukommen; bestehende ändern ihre Bedeutung nicht.
- Die technischen Daten eines Kabels (technical) sind eine geordnete Liste: Die Reihenfolge ist die des Datenblatts.
Authentifizierung
Jeder Aufruf braucht einen API-Schlüssel Ihrer Organisation im Kopf Authorization:
Authorization: Bearer cbl_…- Ein Schlüssel gilt genau für Ihre Organisation. Mit ihm lässt sich nichts anderer Organisationen lesen oder ändern.
- Die Berechtigung Lesen genügt für alle Abrufe; zum Anlegen von Anfragen braucht der Schlüssel zusätzlich Schreiben.
- Über die API angelegte Anfragen werden der Person zugeordnet, die den Schlüssel angelegt hat. Verlässt sie Ihre Organisation, kann der Schlüssel weiter lesen, aber nicht mehr schreiben: Legen Sie dann einen neuen an.
- Die API ist für die Kommunikation zwischen Servern gedacht. Sie sendet keine CORS-Freigaben: Verwenden Sie den Schlüssel nie im Browser oder in einer App, sondern nur auf Ihrem Server.
- Behandeln Sie den Schlüssel wie ein Passwort. Widerrufen Sie ihn, sobald er nicht mehr gebraucht wird oder bekannt geworden sein könnte.
Aufrufe
Kabel auflisten
GET /api/v1/cablesBerechtigung: Lesen
Alle veröffentlichten Kabel Ihrer Organisation, sortiert nach dem URL-Namen (slug), mit technischen Daten und öffentlichen Dateien.
Aufruf
curl "https://testing.cablecreations.de/api/v1/cables?limit=1" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"data": [
{
"id": "0f8b3c1e-5a0d-4a51-9d0e-3a8f4a8f5b11",
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5",
"designation": "NYM-J 3x1,5 mm²",
"description": "Mantelleitung für die feste Verlegung.",
"family": {
"id": "7c1d2a90-0d53-4f0e-8f47-5a0c1c0a2e01",
"slug": "installationsleitungen",
"name": "Installationsleitungen"
},
"technical": [
{
"kind": "field",
"label": "Nennspannung",
"value": {
"kind": "text",
"text": "300/500 V"
}
},
{
"kind": "field",
"label": "Aderzahl",
"value": {
"kind": "text",
"text": "3"
}
}
],
"assets": [
{
"id": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"kind": "image",
"name": "nym-j-3x1-5-catalog-profile.png",
"url": "https://kabel.example/files/b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22/nym-j-3x1-5-catalog-profile.png",
"mime": "image/png",
"bytes": 184320,
"width": 1600,
"height": 256,
"contentHash": "9f2c7d0b6a1e4c3f8b5d2a7e0c9f4b1d6e3a8c5f2b7d0e9a4c1f6b3d8e5a2c7f",
"createdAt": "2026-03-09T12:00:00.000Z"
}
],
"mainPictureId": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"variants": [
{
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5",
"articleNumber": "100-315",
"outerDiameterMm": 8.4,
"weightKgPerKm": 122,
"copperKgPerKm": 43,
"extra": [
{
"label": "Biegeradius",
"value": "34 mm"
}
],
"hasModel": true,
"crossSectionUrl": "https://kabel.example/files/derived/7c2f1d7e-0b4a-4f0e-9d53-6a1b2c3d4e5f/4be1c07a92d35f68/querschnitt-nym-j-3x1-5.svg",
"crossSectionDatasheetUrl": "https://kabel.example/files/derived/a41d9c3b-58e2-4c17-b0f6-2d7e8f9a0b1c/90c3e6f1a2b4d578/querschnitt-sw-nym-j-3x1-5.svg",
"webModelUrl": "https://kabel.example/files/derived/e8b05f26-1c3d-4a79-8e42-5f6a7b8c9d0e/1f6d2a8c4e0b7359/modell-nym-j-3x1-5.glb",
"crossSectionLineArtUrl": "https://kabel.example/files/derived/3d7a2c51-9e4b-4f86-a1c0-6b8e2d4f7a19/5e8c1a3f7b2d9046/querschnitt-linien-nym-j-3x1-5.svg",
"crossSectionShadedUrl": "https://kabel.example/files/derived/9f41c2d8-6a7e-4b35-8d10-2e5c7b9a4f63/7a2e5c9d1f4b8036/querschnitt-schattiert-nym-j-3x1-5.svg",
"crossSectionEngravedUrl": "https://kabel.example/files/derived/c58e3b1a-2d9f-4e70-b6a4-8f1c0d7e5a92/e9b4d27c3a6f1085/querschnitt-kreuzschraffur-nym-j-3x1-5.svg",
"profileUrl": "https://kabel.example/files/derived/b62e9f17-4a3c-4d58-9b0e-1c7f3a5d8e24/c3a91f6e2b8d4075/profil-nym-j-3x1-5.svg"
},
{
"id": "5a9e1f04-2b7c-4d3e-8c61-7e2f9d0a1b33",
"name": "5x2,5",
"articleNumber": null,
"outerDiameterMm": 11.2,
"weightKgPerKm": null,
"copperKgPerKm": null,
"extra": [],
"hasModel": false,
"crossSectionUrl": null,
"crossSectionDatasheetUrl": null,
"webModelUrl": null,
"crossSectionLineArtUrl": null,
"crossSectionShadedUrl": null,
"crossSectionEngravedUrl": null,
"profileUrl": null
}
],
"publishedAt": "2026-03-10T08:30:00.000Z",
"updatedAt": "2026-03-10T08:30:00.000Z",
"datasheetUrl": "https://kabel.example/api/v1/cables/nym-j-3x1-5/datasheet"
}
],
"next": "WyJueW0tai0zeDEtNSJd"
}Ein Kabel abrufen
GET /api/v1/cables/{slug}Berechtigung: Lesen
Ein veröffentlichtes Kabel anhand seines URL-Namens. Entwürfe und archivierte Kabel antworten mit 404.
Aufruf
curl "https://testing.cablecreations.de/api/v1/cables/nym-j-3x1-5" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"id": "0f8b3c1e-5a0d-4a51-9d0e-3a8f4a8f5b11",
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5",
"designation": "NYM-J 3x1,5 mm²",
"description": "Mantelleitung für die feste Verlegung.",
"family": {
"id": "7c1d2a90-0d53-4f0e-8f47-5a0c1c0a2e01",
"slug": "installationsleitungen",
"name": "Installationsleitungen"
},
"technical": [
{
"kind": "field",
"label": "Nennspannung",
"value": {
"kind": "text",
"text": "300/500 V"
}
},
{
"kind": "field",
"label": "Aderzahl",
"value": {
"kind": "text",
"text": "3"
}
}
],
"assets": [
{
"id": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"kind": "image",
"name": "nym-j-3x1-5-catalog-profile.png",
"url": "https://kabel.example/files/b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22/nym-j-3x1-5-catalog-profile.png",
"mime": "image/png",
"bytes": 184320,
"width": 1600,
"height": 256,
"contentHash": "9f2c7d0b6a1e4c3f8b5d2a7e0c9f4b1d6e3a8c5f2b7d0e9a4c1f6b3d8e5a2c7f",
"createdAt": "2026-03-09T12:00:00.000Z"
}
],
"mainPictureId": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"variants": [
{
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5",
"articleNumber": "100-315",
"outerDiameterMm": 8.4,
"weightKgPerKm": 122,
"copperKgPerKm": 43,
"extra": [
{
"label": "Biegeradius",
"value": "34 mm"
}
],
"hasModel": true,
"crossSectionUrl": "https://kabel.example/files/derived/7c2f1d7e-0b4a-4f0e-9d53-6a1b2c3d4e5f/4be1c07a92d35f68/querschnitt-nym-j-3x1-5.svg",
"crossSectionDatasheetUrl": "https://kabel.example/files/derived/a41d9c3b-58e2-4c17-b0f6-2d7e8f9a0b1c/90c3e6f1a2b4d578/querschnitt-sw-nym-j-3x1-5.svg",
"webModelUrl": "https://kabel.example/files/derived/e8b05f26-1c3d-4a79-8e42-5f6a7b8c9d0e/1f6d2a8c4e0b7359/modell-nym-j-3x1-5.glb",
"crossSectionLineArtUrl": "https://kabel.example/files/derived/3d7a2c51-9e4b-4f86-a1c0-6b8e2d4f7a19/5e8c1a3f7b2d9046/querschnitt-linien-nym-j-3x1-5.svg",
"crossSectionShadedUrl": "https://kabel.example/files/derived/9f41c2d8-6a7e-4b35-8d10-2e5c7b9a4f63/7a2e5c9d1f4b8036/querschnitt-schattiert-nym-j-3x1-5.svg",
"crossSectionEngravedUrl": "https://kabel.example/files/derived/c58e3b1a-2d9f-4e70-b6a4-8f1c0d7e5a92/e9b4d27c3a6f1085/querschnitt-kreuzschraffur-nym-j-3x1-5.svg",
"profileUrl": "https://kabel.example/files/derived/b62e9f17-4a3c-4d58-9b0e-1c7f3a5d8e24/c3a91f6e2b8d4075/profil-nym-j-3x1-5.svg"
},
{
"id": "5a9e1f04-2b7c-4d3e-8c61-7e2f9d0a1b33",
"name": "5x2,5",
"articleNumber": null,
"outerDiameterMm": 11.2,
"weightKgPerKm": null,
"copperKgPerKm": null,
"extra": [],
"hasModel": false,
"crossSectionUrl": null,
"crossSectionDatasheetUrl": null,
"webModelUrl": null,
"crossSectionLineArtUrl": null,
"crossSectionShadedUrl": null,
"crossSectionEngravedUrl": null,
"profileUrl": null
}
],
"publishedAt": "2026-03-10T08:30:00.000Z",
"updatedAt": "2026-03-10T08:30:00.000Z",
"datasheetUrl": "https://kabel.example/api/v1/cables/nym-j-3x1-5/datasheet"
}Dateien auflisten
GET /api/v1/assetsBerechtigung: Lesen
Die öffentlichen Dateien Ihrer veröffentlichten Kabel, die neueste zuerst. Mit cable=<slug> nur die Dateien eines Kabels.
Aufruf
curl "https://testing.cablecreations.de/api/v1/assets?cable=nym-j-3x1-5" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"data": [
{
"id": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"kind": "image",
"name": "nym-j-3x1-5-catalog-profile.png",
"url": "https://kabel.example/files/b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22/nym-j-3x1-5-catalog-profile.png",
"mime": "image/png",
"bytes": 184320,
"width": 1600,
"height": 256,
"contentHash": "9f2c7d0b6a1e4c3f8b5d2a7e0c9f4b1d6e3a8c5f2b7d0e9a4c1f6b3d8e5a2c7f",
"createdAt": "2026-03-09T12:00:00.000Z",
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
}
}
],
"next": null
}Familien auflisten
GET /api/v1/familiesBerechtigung: Lesen
Die Kabelfamilien, die mindestens ein veröffentlichtes Kabel enthalten, sortiert nach Position.
Aufruf
curl "https://testing.cablecreations.de/api/v1/families" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"data": [
{
"id": "7c1d2a90-0d53-4f0e-8f47-5a0c1c0a2e01",
"slug": "installationsleitungen",
"name": "Installationsleitungen",
"position": 1,
"cableCount": 12
}
],
"next": null
}Anfrage anlegen
POST /api/v1/requestsBerechtigung: Schreiben
Legt eine Anfrage für ein neues Kabel an. Pflicht ist nur der Titel; es gelten dieselben Regeln wie im Formular des Portals. Unbekannte Felder werden abgelehnt.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/requests" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Steuerleitung für Schleppketten","construction":"4x2x0,75","sheathColour":"grau RAL 7001","datasheetReference":"https://example.com/datenblatt.pdf"}'Antwort (201)
{
"id": "3d5e7a10-2b4c-4d6e-8f90-1a2b3c4d5e6f",
"title": "Steuerleitung für Schleppketten",
"status": "open",
"details": {
"designation": null,
"construction": "4x2x0,75",
"sheathColour": "grau RAL 7001",
"printText": null,
"datasheetReference": "https://example.com/datenblatt.pdf",
"note": null
},
"source": "api",
"rejectionReason": null,
"cable": null,
"createdAt": "2026-04-01T10:00:00.000Z",
"updatedAt": "2026-04-01T10:00:00.000Z"
}Anfragen auflisten
GET /api/v1/requestsBerechtigung: Lesen
Die Anfragen Ihrer Organisation, die neueste zuerst.
Aufruf
curl "https://testing.cablecreations.de/api/v1/requests" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"data": [
{
"id": "3d5e7a10-2b4c-4d6e-8f90-1a2b3c4d5e6f",
"title": "Steuerleitung für Schleppketten",
"status": "open",
"details": {
"designation": null,
"construction": "4x2x0,75",
"sheathColour": "grau RAL 7001",
"printText": null,
"datasheetReference": "https://example.com/datenblatt.pdf",
"note": null
},
"source": "api",
"rejectionReason": null,
"cable": null,
"createdAt": "2026-04-01T10:00:00.000Z",
"updatedAt": "2026-04-01T10:00:00.000Z"
}
],
"next": null
}Eine Anfrage abrufen
GET /api/v1/requests/{id}Berechtigung: Lesen
Status einer Anfrage. Bei abgelehnten Anfragen steht der Grund in rejectionReason, bei gelieferten das Kabel in cable, sobald es veröffentlicht ist.
Aufruf
curl "https://testing.cablecreations.de/api/v1/requests/3d5e7a10-2b4c-4d6e-8f90-1a2b3c4d5e6f" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"id": "3d5e7a10-2b4c-4d6e-8f90-1a2b3c4d5e6f",
"title": "Steuerleitung für Schleppketten",
"status": "open",
"details": {
"designation": null,
"construction": "4x2x0,75",
"sheathColour": "grau RAL 7001",
"printText": null,
"datasheetReference": "https://example.com/datenblatt.pdf",
"note": null
},
"source": "api",
"rejectionReason": null,
"cable": null,
"createdAt": "2026-04-01T10:00:00.000Z",
"updatedAt": "2026-04-01T10:00:00.000Z"
}Motive und Preise abrufen
GET /api/v1/render-motifsBerechtigung: Bestellen
Alle bestellbaren Motive mit Größen in Pixeln und dem Preis je Größe – ohne und mit Untergrund. Den Preis in Euro nennt der Preis einer Bestellung (amount). options nennt die Dateiformate und die Untergründe.
Aufruf
curl "https://testing.cablecreations.de/api/v1/render-motifs" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"data": [
{
"key": "catalog-profile",
"label": "Katalogbild (Seitenansicht)",
"look": "catalog",
"shot": "profile",
"surface": "none",
"sizes": [
{
"key": "web",
"width": 1600,
"height": 256,
"price": 1,
"priceOnSurface": null
},
{
"key": "print",
"width": 3200,
"height": 512,
"price": 2,
"priceOnSurface": null
},
{
"key": "max",
"width": 6400,
"height": 1024,
"price": 4,
"priceOnSurface": null
}
],
"video": {
"motions": [
{
"name": "turn",
"seconds": 8,
"loops": true,
"surface": false,
"lettered": false,
"requires": []
}
],
"resolutions": [
{
"key": "hd",
"width": 1280,
"height": 204,
"pricePerSecond": 1
},
{
"key": "fullhd",
"width": 1920,
"height": 308,
"pricePerSecond": 2
}
]
}
}
],
"options": {
"formats": [
"png",
"jpg",
"webp"
],
"surfaces": [
{
"name": "concrete",
"label": "Beton"
}
],
"poses": [
"straight",
"arc",
"s-curve",
"loop",
"end-lift",
"bend-90",
"u-turn",
"wave",
"coil"
],
"cuts": [
"cores-out",
"cores-stripped",
"flush",
"pie",
"pie-stepped",
"stepped",
"straight"
],
"videoFormats": [
"mp4",
"webm",
"mov",
"zip"
],
"videoLengths": [
"short",
"standard",
"long"
],
"frameRates": [
25,
30,
60
],
"videoSurfacePricePercent": 150,
"views": [
{
"key": "profile",
"label": "Seitenansicht",
"group": "whole",
"environments": [
"cutout",
"white",
"grey",
"custom"
],
"videoEnvironments": [
"cutout",
"white",
"grey",
"custom"
]
}
],
"environments": [
{
"key": "cutout",
"label": "Freigestellt",
"group": "plain",
"looks": [
"catalog"
],
"colour": null,
"surface": null,
"pricePercent": 100
},
{
"key": "white",
"label": "Weiß",
"group": "plain",
"looks": [
"catalog"
],
"colour": "#ffffff",
"surface": null,
"pricePercent": 100
}
],
"compositions": [
{
"key": "stairs",
"label": "Treppe",
"fewest": 2,
"most": 6,
"film": false,
"views": [
{
"key": "above",
"label": "Von oben",
"format": "4:5",
"sizes": [
{
"key": "web",
"width": 600,
"height": 750
},
{
"key": "print",
"width": 1200,
"height": 1500
},
{
"key": "max",
"width": 2400,
"height": 3000
}
]
}
],
"environments": [
"cutout",
"white",
"grey",
"custom",
"studio-light",
"studio-dark"
],
"priceFactors": [
{
"count": 2,
"percent": 150
},
{
"count": 3,
"percent": 200
},
{
"count": 4,
"percent": 250
},
{
"count": 5,
"percent": 300
},
{
"count": 6,
"percent": 350
}
]
}
]
}
}Preis einer Bestellung abfragen
POST /api/v1/orders/priceBerechtigung: Bestellen
Nennt den Preis einer Auswahl in Euro (amount, netto) und ob die Bestellung jetzt etwas kosten würde: nichts, wenn es das Bild schon gibt oder es gerade entsteht. Es wird nichts bestellt.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/orders/price" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"cable":"nym-j-3x1-5","view":"profile","environment":"white","format":"png","extraFormats":["jpg"],"size":"web"}'Antwort (200)
{
"state": "new",
"amount": {
"currency": "EUR",
"netCents": 200
}
}Bild bestellen
POST /api/v1/ordersBerechtigung: Bestellen
Bestellt ein Bild eines Kabels – auch eines noch nicht veröffentlichten. Der Kopf Idempotency-Key ist Pflicht: Wiederholen Sie einen Aufruf mit demselben Schlüssel, wird nichts doppelt bestellt. 201 heißt: neu bestellt; berechnet wird, sobald das Bild geliefert ist. 200 heißt: Das Bild gibt es schon oder es entsteht gerade – ohne Kosten.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/orders" \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: 8f14e45f-ceea-467f-a9f1-0b6d2c3e4f50" \
-H "Content-Type: application/json" \
-d '{"cable":"nym-j-3x1-5","view":"profile","environment":"white","format":"png","extraFormats":["jpg"],"size":"web","expectedNetCents":200}'Antwort (201)
{
"id": "6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192",
"status": "queued",
"source": "api",
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
},
"variant": {
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5"
},
"motif": "catalog-profile",
"kind": "image",
"format": "png",
"size": "web",
"video": null,
"scene": {
"kind": "colour",
"colour": "#ffffff"
},
"view": "profile",
"environment": "white",
"extraFormats": [
"jpg"
],
"pose": null,
"cut": null,
"cables": null,
"composition": null,
"compositionView": null,
"amount": {
"currency": "EUR",
"netCents": 200,
"state": "authorised"
},
"files": [],
"createdAt": "2026-04-01T10:00:00.000Z",
"finishedAt": null
}Bestellungen auflisten
GET /api/v1/ordersBerechtigung: Bestellen
Die Bildbestellungen Ihrer Organisation, die neueste zuerst – auch die im Portal aufgegebenen (source).
Aufruf
curl "https://testing.cablecreations.de/api/v1/orders" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"data": [
{
"id": "6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192",
"status": "delivered",
"source": "api",
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
},
"variant": {
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5"
},
"motif": "catalog-profile",
"kind": "image",
"format": "png",
"size": "web",
"video": null,
"scene": {
"kind": "colour",
"colour": "#ffffff"
},
"view": "profile",
"environment": "white",
"extraFormats": [
"jpg"
],
"pose": null,
"cut": null,
"cables": null,
"composition": null,
"compositionView": null,
"amount": {
"currency": "EUR",
"netCents": 200,
"state": "captured"
},
"files": [
{
"id": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"name": "nym-j-3x1-5-catalog-profile.png",
"url": "https://kabel.example/api/v1/orders/6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192/files/b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"mime": "image/png",
"bytes": 184320,
"width": 1600,
"height": 256,
"contentHash": "9f2c7d0b6a1e4c3f8b5d2a7e0c9f4b1d6e3a8c5f2b7d0e9a4c1f6b3d8e5a2c7f"
},
{
"id": "c7a1b5e3-04d5-4b7c-b2c6-3a2a7a4a0d33",
"name": "nym-j-3x1-5-catalog-profile.jpg",
"url": "https://kabel.example/api/v1/orders/6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192/files/c7a1b5e3-04d5-4b7c-b2c6-3a2a7a4a0d33",
"mime": "image/jpeg",
"bytes": 61440,
"width": 1600,
"height": 256,
"contentHash": "4e1b8d3a6c0f2e5b9a7d1c4f8e2b6a0d3c9f5e1b7a4d0c6e2f8b5a1d9c3e7f0b"
}
],
"createdAt": "2026-04-01T10:00:00.000Z",
"finishedAt": "2026-04-01T10:04:12.000Z"
}
],
"next": null
}Eine Bestellung abrufen
GET /api/v1/orders/{id}Berechtigung: Bestellen
Status einer Bestellung: queued, rendering, delivered, failed oder cancelled. Nach der Lieferung stehen die Dateien in files.
Aufruf
curl "https://testing.cablecreations.de/api/v1/orders/6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"id": "6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192",
"status": "delivered",
"source": "api",
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
},
"variant": {
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5"
},
"motif": "catalog-profile",
"kind": "image",
"format": "png",
"size": "web",
"video": null,
"scene": {
"kind": "colour",
"colour": "#ffffff"
},
"view": "profile",
"environment": "white",
"extraFormats": [
"jpg"
],
"pose": null,
"cut": null,
"cables": null,
"composition": null,
"compositionView": null,
"amount": {
"currency": "EUR",
"netCents": 200,
"state": "captured"
},
"files": [
{
"id": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"name": "nym-j-3x1-5-catalog-profile.png",
"url": "https://kabel.example/api/v1/orders/6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192/files/b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"mime": "image/png",
"bytes": 184320,
"width": 1600,
"height": 256,
"contentHash": "9f2c7d0b6a1e4c3f8b5d2a7e0c9f4b1d6e3a8c5f2b7d0e9a4c1f6b3d8e5a2c7f"
},
{
"id": "c7a1b5e3-04d5-4b7c-b2c6-3a2a7a4a0d33",
"name": "nym-j-3x1-5-catalog-profile.jpg",
"url": "https://kabel.example/api/v1/orders/6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192/files/c7a1b5e3-04d5-4b7c-b2c6-3a2a7a4a0d33",
"mime": "image/jpeg",
"bytes": 61440,
"width": 1600,
"height": 256,
"contentHash": "4e1b8d3a6c0f2e5b9a7d1c4f8e2b6a0d3c9f5e1b7a4d0c6e2f8b5a1d9c3e7f0b"
}
],
"createdAt": "2026-04-01T10:00:00.000Z",
"finishedAt": "2026-04-01T10:04:12.000Z"
}Bestellung stornieren
POST /api/v1/orders/{id}/cancelBerechtigung: Bestellen
Storniert eine Bestellung, die noch in der Warteschlange steht; sie wird nicht berechnet. Sobald ein Bild in Arbeit ist, antwortet der Aufruf mit 409.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/orders/6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192/cancel" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"id": "6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192",
"status": "cancelled",
"source": "api",
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
},
"variant": {
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5"
},
"motif": "catalog-profile",
"kind": "image",
"format": "png",
"size": "web",
"video": null,
"scene": {
"kind": "colour",
"colour": "#ffffff"
},
"view": "profile",
"environment": "white",
"extraFormats": [
"jpg"
],
"pose": null,
"cut": null,
"cables": null,
"composition": null,
"compositionView": null,
"amount": {
"currency": "EUR",
"netCents": 200,
"state": "authorised"
},
"files": [],
"createdAt": "2026-04-01T10:00:00.000Z",
"finishedAt": "2026-04-01T10:01:00.000Z"
}Preis einer Umwandlung
POST /api/v1/conversions/priceBerechtigung: Umwandeln
Nennt den Preis in Euro (netto) für eine Umwandlung mit den gewählten Ausgaben. Braucht keine Datei und startet nichts.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/conversions/price" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"outputs":["dxf"]}'Antwort (200)
{
"currency": "EUR",
"lines": [
{
"kind": "conversion",
"name": "conversion",
"cents": 3900
},
{
"kind": "extra",
"name": "dxf",
"cents": 500
}
],
"netCents": 4400,
"tier": {
"fromJobs": 0,
"percentOff": 0,
"requestsPerWindow": 100
}
}Spec umwandeln
POST /api/v1/conversionsBerechtigung: Umwandeln
Prüft die Spec eines Kabels (JSON) mit dem Generator, reserviert den Preis in Ihrem Monatslimit und baut die Dateien ohne weiteren Schritt, in der Regel in wenigen Minuten. Eine Spec, die der Generator ablehnt, beantwortet der Aufruf sofort mit 400 und je einem Fehler an seiner Stelle (field ist der JSON-Pfad); es wird nichts reserviert. Sonst antwortet er mit 202. Der Header Idempotency-Key ist Pflicht. Ohne Rechnungsadresse oder bei erreichtem Monatslimit antwortet der Aufruf mit 402, bei zu vielen laufenden Umwandlungen mit 429.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/conversions" \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: 2c6f8a1e-9d3b-4e75-a0c4-7b1d5f3e8a92" \
-H "Content-Type: application/json" \
-d '{"spec":{"name":"RG 58 C/U","cut":{"preset":"stepped","at":68},"build":[{"conductor":{"diameter":0.9,"strand_pitch":0.19,"material":"copper-tinned","color":"#c9cdd1"}},{"insulation":{"thickness":1.02,"material":"rubber","color":"#d3dde3"}},{"braid":{"carriers":12,"wires_per_carrier":8,"wire_diameter":0.12,"lay_length":20,"material":"copper-tinned","color":"#c9cdd1"}},{"sheath":{"thickness":0.76,"material":"pvc","color":"#1e1e20"}}]},"outputs":["dxf"]}'Antwort (202)
{
"id": "cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f",
"status": "queued",
"source": "spec_json",
"size": "RG 58 C/U",
"outputs": [
"glb_web",
"section_svg",
"check_json",
"dxf"
],
"amount": {
"currency": "EUR",
"netCents": 4400,
"state": "authorised"
},
"refusal": null,
"files": [],
"cable": null,
"filesKeptUntil": null,
"createdAt": "2026-04-01T10:02:00.000Z",
"finishedAt": null
}Umwandlungen auflisten
GET /api/v1/conversionsBerechtigung: Umwandeln
Alle Umwandlungen Ihrer Organisation, die neueste zuerst, mit Status und Dateien.
Aufruf
curl "https://testing.cablecreations.de/api/v1/conversions" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"data": [
{
"id": "cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f",
"status": "completed",
"source": "spec_json",
"size": "RG 58 C/U",
"outputs": [
"glb_web",
"section_svg",
"check_json",
"dxf"
],
"amount": {
"currency": "EUR",
"netCents": 4400,
"state": "captured"
},
"refusal": null,
"files": [
{
"id": "e1c7b0a4-5d2f-4a39-8c6e-9b3d1f7a2c58",
"name": "rg-58-c-u-3d-web.glb",
"kind": "glb_web",
"mime": "model/gltf-binary",
"bytes": 412860,
"url": "https://kabel.example/api/v1/conversions/cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f/files/e1c7b0a4-5d2f-4a39-8c6e-9b3d1f7a2c58",
"contentHash": "3b5d9e1f7a2c4806b1d3f5a7c9e0b2d4f6a8c1e3b5d7f9a0c2e4b6d8f1a3c5e7"
}
],
"cable": {
"slug": "rg-58-c-u",
"name": "RG 58 C/U"
},
"filesKeptUntil": "2027-03-31T22:00:00.000Z",
"createdAt": "2026-04-01T10:02:00.000Z",
"finishedAt": "2026-04-01T10:04:00.000Z"
}
],
"next": null
}Eine Umwandlung abrufen
GET /api/v1/conversions/{id}Berechtigung: Umwandeln
Status der Umwandlung: queued, reading, in_review, building, completed, refused (mit Code und Satz) oder cancelled. Geliefert wird ein 3D-Modell für das Web (GLB), die Schnittzeichnung (SVG) und der Prüfbericht (JSON), auf Wunsch weitere Formate.
Aufruf
curl "https://testing.cablecreations.de/api/v1/conversions/cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"id": "cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f",
"status": "completed",
"source": "spec_json",
"size": "RG 58 C/U",
"outputs": [
"glb_web",
"section_svg",
"check_json",
"dxf"
],
"amount": {
"currency": "EUR",
"netCents": 4400,
"state": "captured"
},
"refusal": null,
"files": [
{
"id": "e1c7b0a4-5d2f-4a39-8c6e-9b3d1f7a2c58",
"name": "rg-58-c-u-3d-web.glb",
"kind": "glb_web",
"mime": "model/gltf-binary",
"bytes": 412860,
"url": "https://kabel.example/api/v1/conversions/cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f/files/e1c7b0a4-5d2f-4a39-8c6e-9b3d1f7a2c58",
"contentHash": "3b5d9e1f7a2c4806b1d3f5a7c9e0b2d4f6a8c1e3b5d7f9a0c2e4b6d8f1a3c5e7"
}
],
"cable": {
"slug": "rg-58-c-u",
"name": "RG 58 C/U"
},
"filesKeptUntil": "2027-03-31T22:00:00.000Z",
"createdAt": "2026-04-01T10:02:00.000Z",
"finishedAt": "2026-04-01T10:04:00.000Z"
}Umwandlung stornieren
POST /api/v1/conversions/{id}/cancelBerechtigung: Umwandeln
Storniert eine Umwandlung, bevor sie gebaut wird; die Reservierung auf der Karte wird freigegeben. Danach antwortet der Aufruf mit 409.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/conversions/cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f/cancel" \
-H "Authorization: Bearer $API_KEY"Antwort (200)
{
"id": "cv_4f7a1c9e2b8d4a6f9c3e5d7b1a2c4e6f",
"status": "cancelled",
"source": "spec_json",
"size": "RG 58 C/U",
"outputs": [
"glb_web",
"section_svg",
"check_json",
"dxf"
],
"amount": {
"currency": "EUR",
"netCents": 4400,
"state": "released"
},
"refusal": null,
"files": [],
"cable": null,
"filesKeptUntil": null,
"createdAt": "2026-04-01T10:02:00.000Z",
"finishedAt": "2026-04-01T10:05:00.000Z"
}Datenblatt eines Kabels abrufen
GET /api/v1/cables/{slug}/datasheetBerechtigung: Lesen
Das Datenblatt eines veröffentlichten Kabels als PDF in Ihrem Erscheinungsbild: Typdaten, öffentliche Bilder und die Tabelle der Querschnitte. Die Adresse steht bei jedem Kabel im Feld datasheetUrl.
Antwort (200) · application/pdf
Gelieferte Datei herunterladen
GET /api/v1/orders/{id}/files/{fileId}Berechtigung: Bestellen
Die Datei selbst. Der Aufruf braucht den API-Schlüssel wie jeder andere; die Adresse steht bei jeder Datei im Feld url.
Antwort (200) · application/octet-stream
Datei einer Umwandlung
GET /api/v1/conversions/{id}/files/{fileId}Berechtigung: Umwandeln
Die Datei selbst. Der Aufruf braucht den API-Schlüssel wie jeder andere; die Adresse steht bei jeder Datei im Feld url.
Antwort (200) · application/octet-stream
Bilder bestellen
Mit der Berechtigung Bestellen geben Ihre Systeme dieselben Bildbestellungen auf wie Ihre Mitarbeiter im Portal – zu denselben Preisen und Regeln.
- Ablauf: Motive und Preise abrufen, optional den Preis einer Auswahl abfragen, bestellen, den Status abrufen (oder sich per Webhook benachrichtigen lassen), die Dateien herunterladen.
- Ein Bild benennen Sie mit Ansicht und Umgebung: view (von wo die Kamera schaut) und environment (wo das Kabel liegt – Hintergrund und Boden passen immer zusammen), bei custom dazu environmentColour. options.views und options.environments der Motivliste nennen, welche Paare bestellbar sind. Die ältere Form mit motif und scene gilt weiter; beides in einer Bestellung wird abgelehnt.
- Eine Bestellung ist eine Bildgröße (web, print oder max) oder eine Filmauflösung; mehrere bestellen Sie mit mehreren Aufrufen. Weitere Dateiformate desselben Bildes oder Films stehen in extraFormats (zum Beispiel png und dazu jpg); sie kosten nichts. Ein freigestelltes JPG oder MP4 liegt auf Weiß.
- Filme gibt es in HD, Full HD und 4K (resolution uhd, 3.840 Pixel an der langen Seite). 4K gibt es in jeder Länge und Bildrate. Eine Datei, die größer als 1 GiB würde (etwa ProRes oder PNG-Einzelbilder eines langen 4K-Films), wird mit too_large abgelehnt; MP4 und WebM passen immer.
- Jede Bestellung braucht den Kopf Idempotency-Key mit einem Wert Ihrer Wahl (z. B. eine UUID). Derselbe Wert mit demselben Inhalt bestellt nie doppelt; die Antwort trägt dann Idempotent-Replay: true. Derselbe Wert mit anderem Inhalt wird mit 409 abgelehnt.
- Gibt es das Bild schon oder entsteht es gerade, kostet die Bestellung nichts (200 statt 201).
- Mit expectedNetCents sichern Sie sich ab – dem Nettopreis in Cent, den die Preisabfrage genannt hat (amount.netCents): Kostet ein neues Bild etwas anderes, wird nichts bestellt (409 price_changed).
- Überschreitet die Bestellung das Ausgabenlimit, ist das Budget des Schlüssels erschöpft oder sind Bestellungen angehalten, antwortet die API mit 402 und einem eigenen code. Es wird nichts bestellt; derselbe Idempotency-Key gilt danach weiter.
- Preise: amount nennt den Preis netto in Cent (netCents) mit der Währung. Hersteller bezahlen mit der Monatsrechnung, Entwickler mit ihrer monatlichen Sammelrechnung innerhalb ihres Monatslimits; ein fehlgeschlagenes oder storniertes Bild wird nicht berechnet.
- Bestellungen werden der Person zugeordnet, die den Schlüssel angelegt hat, und erscheinen im Portal unter Bestellungen.
- Gelieferte Dateien laden Sie mit dem Schlüssel über die Adresse in files[].url herunter. Die Adressen funktionieren nicht ohne Schlüssel.
- Pro Schlüssel sind 60 Bestellungen in 10 Minuten möglich; darüber antwortet die API mit 429.
Mehrere Kabel in einem Bild
- Statt cable nennen Sie cables: zwei bis sechs Kabel in der Reihenfolge des Bildes (von links nach rechts, von vorn nach hinten), jedes mit cable und auf Wunsch variant. Dasselbe Kabel darf mehrfach vorkommen.
- Dazu composition (wie die Kabel zueinander liegen) und compositionView (der Blickwinkel; ohne ihn der erste angebotene) sowie environment – freigestellt, auf einer Farbe oder im Studio, nicht auf einem Boden. options.compositions der Motivliste nennt, welche Anordnungen mit welchen Blickwinkeln, Größen und Umgebungen bestellbar sind.
- Eine Abmantelung (cut) gilt für alle Kabel und geht nur, wenn jedes Kabel sie erlaubt. pose, view, motif und scene gibt es bei mehreren Kabeln nicht; einen Film nur verdrillt, von der Seite (compositionView side; „Mit Kabelenden“ gibt es nur als Bild).
- Jedes weitere Kabel kostet die Hälfte des Einzelpreises dazu (priceFactors). Die Preisabfrage nennt den Preis der Auswahl; expectedNetCents, Idempotency-Key und die Antworten 200, 402 und 409 gelten wie bei einem Kabel.
- Abgelehnt wird Feld für Feld: cables[i] mit unknown_cable oder not_ready, composition mit not_offered, count_needs oder einem Grund des Bündels (helix_sizes_apart, helix_too_stiff, helix_too_short), environment mit not_with_several, video mit only_helix, compositionView mit unavailable (ein Film der Kabelenden).
- Die Bestellung nennt cables (mit position), composition und compositionView; cable und variant nennen das erste Kabel. Webhooks tragen dieselbe Bestellung.
Aufruf
curl -X POST "https://testing.cablecreations.de/api/v1/orders" \
-H "Authorization: Bearer $API_KEY" \
-H "Idempotency-Key: 4b7e2d90-6c1f-4a83-b5d2-9e0f1a3c5e77" \
-H "Content-Type: application/json" \
-d '{"cables":[{"cable":"nym-j-3x1-5"},{"cable":"nym-j-3x2-5"},{"cable":"nym-j-5x1-5"}],"composition":"stairs","compositionView":"above","environment":"cutout","format":"png","size":"web","expectedNetCents":1200}'Antwort (201)
{
"id": "8c2d4e6f-1a3b-4c5d-9e7f-2b4d6f8a0c13",
"status": "queued",
"source": "api",
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
},
"variant": {
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5"
},
"motif": "photo-stairs",
"kind": "image",
"format": "png",
"size": "web",
"video": null,
"scene": {
"kind": "transparent"
},
"view": null,
"environment": "cutout",
"extraFormats": [],
"pose": null,
"cut": null,
"cables": [
{
"position": 0,
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
},
"variant": {
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5"
}
},
{
"position": 1,
"cable": {
"slug": "nym-j-3x2-5",
"name": "NYM-J 3x2,5"
},
"variant": {
"id": "5a7c9e1b-3d5f-4a7c-8e0b-2d4f6a8c0e21",
"name": "3x2,5"
}
},
{
"position": 2,
"cable": {
"slug": "nym-j-5x1-5",
"name": "NYM-J 5x1,5"
},
"variant": {
"id": "7e9a1c3d-5f7b-4c9e-a1d3-5f7b9d1e3a42",
"name": "5x1,5"
}
}
],
"composition": "stairs",
"compositionView": "above",
"amount": {
"currency": "EUR",
"netCents": 1200,
"state": "authorised"
},
"files": [],
"createdAt": "2026-04-01T10:00:00.000Z",
"finishedAt": null
}Specs umwandeln
Mit dem Zugang für Entwickler und der Berechtigung Umwandeln machen Ihre Systeme aus der Spec eines Kabels ein 3D-Kabel: ein 3D-Modell fürs Web (GLB), die Schnittzeichnung (SVG) und einen Prüfbericht (JSON), auf Wunsch weitere Formate. Sie bezahlen nur, was geliefert wird.
Niemand von uns arbeitet daran: Der Generator prüft die Spec beim Aufruf und baut sie gleich danach. Das dauert normalerweise wenige Minuten.
- Ablauf: Preis abfragen, die Umwandlung mit der Spec und den Ausgaben starten, den Status abrufen (oder per Webhook conversion.completed und conversion.refused benachrichtigt werden), die Dateien herunterladen.
- Eine Umwandlung ist genau ein Kabel in einem Querschnitt. size benennt den Querschnitt (zum Beispiel 3G1,5); ohne size gilt der name der Spec.
- Jede Umwandlung braucht den Kopf Idempotency-Key. Derselbe Wert mit demselben Inhalt startet nie doppelt (die Antwort trägt dann Idempotent-Replay: true); mit anderem Inhalt wird er mit 409 abgelehnt.
- Beim Start wird der Preis in Ihrem Monatslimit reserviert; berechnet wird er mit der Lieferung, auf Ihrer Monatsrechnung. Wird abgelehnt oder storniert, geben wir die Reservierung frei. Ohne Rechnungsadresse oder bei erreichtem Monatslimit antwortet der Aufruf mit 402 und reason, bei zu vielen laufenden Umwandlungen mit 429.
- Stornieren geht, solange die Umwandlung wartet (queued); danach antwortet der Aufruf mit 409.
- Die Daten in der Spec müssen Ihnen gehören oder Sie müssen sie verwenden dürfen. Die gelieferten Dateien dürfen Sie in Ihrem eigenen Produkt nutzen.
- Aufbewahrung: die gelieferten Dateien 12 Monate nach der Lieferung (filesKeptUntil nennt den Tag). Das Kabel mit seiner Spec bleibt in Ihrem Zugang.
- Bilder Ihres Kabels: Eine gelieferte Umwandlung nennt ihr Kabel (cable.slug). Mit der Berechtigung Bestellen bestellen Sie dafür Bilder über POST /orders. Jedes neue Bild wird in Ihrem Monatslimit reserviert (402 und 429 wie oben) und mit der Lieferung berechnet; amount in der Antwort nennt den Preis in Euro. Ein Bild, das es schon gibt oder das gerade entsteht, kostet nicht noch einmal.
Die Spec als JSON
- spec ist das Spec-Format des Generators als JSON: eine Tabelle ist ein Objekt, ein Array von Tabellen ein Array, ein Bauschritt ein Objekt mit einem Schlüssel ({"conductor": {…}}). Längen in Millimetern.
- Erlaubt sind Zeichenketten, endliche Zahlen, true und false, Arrays und Objekte; Schlüssel aus Buchstaben, Ziffern, _ und -. null, unendliche Zahlen und Arrays von Arrays werden vor dem Generator abgelehnt (not_an_object, invalid_key, invalid_value, too_large ab 256 KB).
- Der Generator prüft die Spec wie cable check: Jeder Fehler kommt als eigenes Detail mit dem JSON-Pfad (spec.build[2].conductor.diameter), seinem Code und seinem Satz. Weicht der gebaute Außendurchmesser vom Ziel unter [datasheet] ab, ist das ebenfalls ein Fehler.
- Mit einem Testschlüssel wird die Spec genauso geprüft; nur die Lieferung ist ein Beispiel.
Preise (netto, in Euro)
- Umwandlung eines Querschnitts mit 3D-Modell fürs Web, Schnittzeichnung und Prüfbericht: 39,00 €
- Zusätzlich Detailmodell mit allen Drähten (GLB, outputs: glb_full): 5,00 €
- Zusätzlich OBJ mit Materialien (ZIP, outputs: obj): 5,00 €
- Zusätzlich STL (outputs: stl): 5,00 €
- Zusätzlich FBX für Blender, Unity und Unreal (outputs: fbx): 9,00 €
- Zusätzlich USDZ für Apple (outputs: usdz): 9,00 €
- Zusätzlich Schnittzeichnung (DXF, outputs: dxf): 5,00 €
Stände einer Umwandlung
queuedDie Spec ist geprüft; die Umwandlung wartet auf den Bau.readingNur bei Umwandlungen des früheren Datenblatt-Wegs: Das Datenblatt wurde gelesen.in_reviewNur bei Umwandlungen des früheren Datenblatt-Wegs: Der Aufbau wurde geprüft.buildingDie Dateien werden gebaut.completedGeliefert und berechnet; files enthält die Dateien.refusedNicht geliefert; refusal nennt Code und Satz, es wird nichts berechnet.cancelledVon Ihnen storniert; die Reservierung ist freigegeben.
Gründe einer Ablehnung (refusal.code)
unreadable_datasheetDas Datenblatt lässt sich nicht lesen (Scan, beschädigt, ohne brauchbaren Text).not_a_cableDas Dokument beschreibt kein Kabel, das wir bauen können.size_not_foundDas Datenblatt hat keinen Querschnitt mit dieser Bezeichnung.not_buildableDie Spec ließ sich nicht bauen.diameter_off_targetDer gebaute Aufbau weicht im Außendurchmesser vom Datenblatt ab.not_delivered_in_timeDie Umwandlung wurde nicht rechtzeitig fertig; die Reservierung wurde freigegeben.otherEin anderer Grund; refusal.message nennt ihn.
Webhooks
Statt Bestellungen und Kabel regelmäßig abzufragen, lassen Sie sich benachrichtigen. Inhaber richten die Endpunkte unter Einstellungen → Webhooks ein.
- Jedes Ereignis kommt als JSON per POST mit demselben Umschlag: id, type, version, createdAt und data. Die id eines Ereignisses bleibt bei jeder Wiederholung gleich – verwenden Sie sie, um doppelte Zustellungen zu erkennen.
- data enthält nur IDs und das, was die API Ihrem Schlüssel ohnehin zeigt. Bei render.finished ist es die Bestellung mit ihren Dateien; bei enquiry.received nur die ID der Anfrage und das Kabel – keine Angaben zur anfragenden Person. Die einzige Ausnahme sind die Ereignisse lead.*, siehe unten.
- Antworten Sie innerhalb von zehn Sekunden mit einem Status 2xx. Alles andere – auch eine Weiterleitung – gilt als fehlgeschlagen und wird wiederholt: nach 1, 4, 16 und 64 Minuten und nach gut 4 Stunden, insgesamt sechs Versuche.
- Schlägt die Zustellung drei Tage lang fehl, deaktivieren wir den Endpunkt und benachrichtigen die Inhaber per E-Mail.
- Die Adresse muss mit https:// beginnen und im öffentlichen Internet erreichbar sein.
Ereignisse
render.finishedEin bestelltes Bild wurde geliefert.render.failedEin bestelltes Bild ist endgültig fehlgeschlagen.cable.publishedEin Kabel wurde veröffentlicht.cable.updatedDie Daten eines veröffentlichten Kabels wurden geändert.cable.unpublishedEin Kabel wurde aus dem Katalog genommen.request.status_changedEin Kabelauftrag hat einen neuen Stand: jeder Schritt von eingegangen bis abgenommen.service_order.status_changedEin Auftrag für eine Leistung (Gestaltung) hat einen neuen Stand: jeder Schritt von eingegangen bis abgenommen.enquiry.receivedÜber den Katalog ist eine Anfrage eingegangen.lead.catalogue_enquiryEine Anfrage aus dem Katalog – mit Name, E-Mail, Firma und Nachricht der anfragenden Person.lead.expose_replyEine Antwort auf ein Exposé – mit Name, E-Mail und Nachricht der antwortenden Person und den angekreuzten Kabeln.conversion.completedEine Umwandlung wurde geliefert; ihre Dateien stehen bereit.conversion.refusedEine Umwandlung wurde abgelehnt; es wurde nichts abgebucht.
Beispiel einer Zustellung
{
"id": "evt_3f1d6c0a-9b2e-4c57-8d10-7a6b5c4d3e2f",
"type": "render.finished",
"version": 1,
"createdAt": "2026-04-01T10:04:13.000Z",
"data": {
"order": {
"id": "6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192",
"status": "delivered",
"source": "api",
"cable": {
"slug": "nym-j-3x1-5",
"name": "NYM-J 3x1,5"
},
"variant": {
"id": "3d0c7e52-6c1a-4a0e-9a57-0b6a4a3b7d10",
"name": "3x1,5"
},
"motif": "catalog-profile",
"kind": "image",
"format": "png",
"size": "web",
"video": null,
"scene": {
"kind": "colour",
"colour": "#ffffff"
},
"view": "profile",
"environment": "white",
"extraFormats": [],
"pose": null,
"cut": null,
"cables": null,
"composition": null,
"compositionView": null,
"amount": {
"currency": "EUR",
"netCents": 200,
"state": "captured"
},
"files": [
{
"id": "b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"name": "nym-j-3x1-5-catalog-profile.png",
"url": "https://kabel.example/api/v1/orders/6b1f0c9e-7a2d-4e53-9c10-4d5e6f708192/files/b6f0a4d2-93c4-4a6b-a1b5-2f1f6f3f9c22",
"mime": "image/png",
"bytes": 184320,
"width": 1600,
"height": 256,
"contentHash": "9f2c7d0b6a1e4c3f8b5d2a7e0c9f4b1d6e3a8c5f2b7d0e9a4c1f6b3d8e5a2c7f"
}
],
"createdAt": "2026-04-01T10:00:00.000Z",
"finishedAt": "2026-04-01T10:04:12.000Z"
}
}
}Kabelaufträge: request.status_changed
Das Ereignis kommt bei jedem Schritt eines Kabelauftrags. status und previousStatus sind der Status der Anfrage mit seinen vier Werten, wie ihn GET /requests zeigt. orderState und previousOrderState sagen genauer, wo der Auftrag steht, und actsNext, auf wen er wartet: customer, operator oder nobody. Bewegt sich nur der Auftrag – bei einer Rückfrage, einer Änderungsrunde oder der Abnahme –, sind status und previousStatus gleich. Ein Angebot und eine einfache Nachricht ändern keinen Stand und melden nichts.
Werte von orderState
submittedDer Auftrag ist eingegangen.in_progressWir arbeiten an dem Kabel.question_to_customerWir haben eine Rückfrage. Der Auftrag wartet auf Ihre Antwort.deliveredEine Fassung ist geliefert und wartet auf Ihre Abnahme.change_requestedSie haben Änderungen gewünscht. Wir arbeiten an der nächsten Fassung.acceptedDie Fassung ist abgenommen, durch Sie oder nach Ablauf der Abnahmefrist. Erst jetzt kann das Kabel veröffentlicht werden.rejectedWir haben den Auftrag abgelehnt.withdrawnSie haben den Auftrag zurückgezogen.
Beispiel: Eine Fassung wurde abgenommen
{
"id": "evt_8c2a41d7-5e0b-4f36-a9c1-2b3d4e5f6a70",
"type": "request.status_changed",
"version": 1,
"createdAt": "2026-04-08T09:15:02.000Z",
"data": {
"request": {
"id": "0c9d2f5a-1b3e-4c7d-8e9f-a1b2c3d4e5f6",
"status": "delivered",
"previousStatus": "delivered",
"orderState": "accepted",
"previousOrderState": "delivered",
"actsNext": "nobody"
}
}
}Signatur prüfen
Jede Zustellung trägt den Kopf Cable-Signature: t=<Zeitstempel>,v1=<Signatur>. Die Signatur ist der HMAC-SHA256 über „<Zeitstempel>.<unveränderter Body>“ mit Ihrem Signaturgeheimnis. Prüfen Sie sie über den rohen Body, vergleichen Sie in konstanter Zeit und lehnen Sie Zeitstempel ab, die älter als fünf Minuten sind.
import { createHmac, timingSafeEqual } from "node:crypto";
// header: the value of the Cable-Signature header
// rawBody: the request body exactly as it arrived (text, not parsed JSON)
export function isFromCablePlatform(rawBody, header, secret) {
const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? "");
if (match === null) return false;
const [, timestamp, signature] = match;
const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
if (ageSeconds > 300) return false;
const expected = createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
return timingSafeEqual(Buffer.from(signature, "hex"), Buffer.from(expected, "hex"));
}Seitenweise abrufen
- Listen liefern data und next. Ist next nicht null, holen Sie die nächste Seite mit ?cursor=<next>.
- Mit limit bestimmen Sie die Seitengröße: 1 bis 100, ohne Angabe 50.
- Der Cursor ist undurchsichtig: Bauen oder verändern Sie ihn nicht.
- Kommen während des Abrufs neue Einträge hinzu, wird kein Eintrag doppelt geliefert und keiner übersprungen.
Fehler
Fehler haben immer dieselbe Form. Werten Sie code aus, nicht den Text in message.
| Status | Code | Bedeutung |
|---|---|---|
| 401 | unauthorized | Der Schlüssel fehlt, ist unbekannt oder wurde widerrufen. |
| 403 | forbidden | Dem Schlüssel fehlt die Berechtigung für diesen Aufruf. |
| 404 | not_found | Unter diesem Namen gibt es nichts, was der Schlüssel sehen darf – auch nicht veröffentlichte Kabel antworten so. |
| 400 | validation_failed | Ein Parameter oder ein Feld wurde abgelehnt. details nennt jedes betroffene Feld mit einem Code. |
| 429 | rate_limited | Zu viele Anfragen. Retry-After nennt die Wartezeit in Sekunden. |
| 500 | internal | Fehler auf unserer Seite. Bitte später erneut versuchen. |
| 402 | spending_limit_reached | Die Bestellung überschreitet das monatliche Ausgabenlimit Ihrer Organisation. |
| 402 | budget_exceeded | Die Bestellung übersteigt das Budget des Schlüssels, des Gastes, dem er gehört, oder Ihr eigenes Monatslimit. |
| 402 | billing_blocked | Bestellungen sind für Ihre Organisation derzeit angehalten. Den Grund sehen Inhaber unter Abrechnung. |
| 409 | price_changed | Die Bestellung kostet etwas anderes als in expectedNetCents angegeben. Fragen Sie den Preis erneut ab. |
| 409 | idempotency_conflict | Dieser Idempotency-Key wurde schon für eine andere Bestellung verwendet. |
| 409 | not_cancellable | Die Bestellung steht nicht mehr in der Warteschlange. |
| 403 | plan_required | Der API-Zugang gehört nicht zum Tarif Ihrer Organisation. Der Schlüssel bleibt erhalten und funktioniert wieder, sobald der Tarif ihn enthält. Mit dem Grund storage_full (beim Bestellen): Der Speicher Ihrer Organisation ist voll; lesende Aufrufe funktionieren weiter. |
| 402 | payment_required | Es wurde nichts gestartet und nichts berechnet. reason ist invoice_address_required (für die Monatsrechnung fehlt noch die Rechnungsadresse) oder monthly_limit_reached (der Auftrag würde das monatliche Limit des Inhabers überschreiten). |
| 429 | too_many_jobs | Für die Organisation sind zu viele Umwandlungen in Arbeit. |
| 503 | service_unavailable | Der Zahlungsanbieter ist nicht erreichbar; es wurde nichts gestartet. |
Beispiele
Antwort (400)
{
"error": {
"code": "validation_failed",
"message": "The request is not valid. See `details`.",
"details": [
{
"field": "title",
"code": "required",
"message": "title is required."
},
{
"field": "construction",
"code": "no_number",
"message": "construction must contain a number."
}
]
}
}Antwort (401)
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid API key. Send it as `Authorization: Bearer <key>`."
}
}Antwort (403)
{
"error": {
"code": "forbidden",
"message": "This API key does not have the scope this call needs."
}
}Antwort (404)
{
"error": {
"code": "not_found",
"message": "Not found."
}
}Antwort (429)
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Wait for the time given in `Retry-After`."
}
}Antwort (402)
{
"error": {
"code": "spending_limit_reached",
"message": "This order exceeds the organization's monthly spending limit."
}
}Antwort (409)
{
"error": {
"code": "idempotency_conflict",
"message": "This `Idempotency-Key` was already used for another order. Use a new key for a new order."
}
}Antwort (402)
{
"error": {
"code": "payment_required",
"message": "This job would exceed the monthly limit, so nothing was started. Its owner can raise the limit under Usage & invoices.",
"reason": "monthly_limit_reached"
}
}Limits
- Pro Schlüssel sind 100 Anfragen in Folge erlaubt. Nach 10 Sekunden ohne Anfrage steht das volle Kontingent wieder bereit.
- Ist das Kontingent erschöpft, antwortet die API mit 429 und nennt in Retry-After die Wartezeit in Sekunden.
- Rufen Sie Daten nicht bei jedem Seitenaufruf Ihrer Website ab, sondern speichern Sie sie zwischen.