Bevor Sie beginnen
Die API funktioniert ohne Benutzerkonto über eine Gast-Sitzung. Die API liegt unter der eigenen Adresse der Website unter /api. Setzen Sie sie einmal:
API=https://dev.uliketechnology.com/api
F=board.zip
board.zip ist ein flaches Zip-Archiv mit Ihren Gerber- und Bohrdateien. Was hineingehört, steht unter Dateien für Fertigung und Bestückung. Die Beispiele brauchen curl und jq.
Jede Anfrage an die API nach der Gast-Sitzung nimmt Authorization: Bearer <token>. Jeder Fehler hat dieselbe Form:
{ "error": { "code": "VALIDATION_FAILED", "message": "…", "details": {}, "requestId": "…" } }
Verzweigen Sie nach code. Die message ist für Entwickler.
- Gast-Sitzung: das Token wird einmal angezeigt.
- Hochladen:
PUTdes Zip-Archivs an die Adresse, die die API nennt, mit den Headern, die sie nennt. - Abschließen, dann abfragen, bis die Analyse fertig ist.
- Der Bericht: Feststellungen, welche Prüfungen liefen und welche nicht.
- Die Preisvorschau.
Der Ablauf mit curl
Lesen Sie, was bestellt werden kann. Dafür ist kein Token nötig:
curl -s $API/v1/capabilities | jq '.options[].id'
Öffnen Sie eine Gast-Sitzung. Das Token wird einmal angezeigt und gilt 30 Tage:
T=$(curl -s -X POST $API/v1/guest-sessions | jq -r .token)
Melden Sie die Datei an. Die Antwort enthält uploadId, designId, uploadUrl und requiredHeaders:
J=$(curl -s -X POST $API/v1/uploads -H "authorization: Bearer $T" -H 'content-type: application/json' \
-d "{\"fileName\":\"board.zip\",\"sizeBytes\":$(stat -c %s $F),\"sha256\":\"$(sha256sum $F | cut -d' ' -f1)\",\"purpose\":\"design\"}")
Senden Sie die Datei an die Adresse, die die Antwort nennt, mit jedem Header in requiredHeaders (Content-Type, Länge und Prüfsumme; ohne sie wird der Upload mit 403 abgelehnt). Schließen Sie den Upload dann ab:
curl -s -X PUT --data-binary @$F \
$(echo $J | jq -r '.requiredHeaders | to_entries[] | "-H \(.key):\(.value)"') \
"$(echo $J | jq -r .uploadUrl)"
curl -s -X POST $API/v1/uploads/$(echo $J | jq -r .uploadId)/complete -H "authorization: Bearer $T" | jq .design.status
Der Status ist zuerst analysing. Lesen Sie das Design, bis er sich ändert. Wenn er ready ist, steht der Bericht in der Antwort:
D=$(echo $J | jq -r .designId)
curl -s $API/v1/designs/$D -H "authorization: Bearer $T" | jq '.design.status, .report.headline, .report.counts'
Die Überschrift ist no_problems_in_checks_run, problems_found oder could_not_check. Lesen Sie auch checksRun und checksNotRun: eine Prüfung, die nicht lief, ist nicht bestanden. Die anderen Status sind needs_mapping (setzen Sie die Lagen mit PUT /v1/designs/{designId}/layer-mapping), needs_engineer und rejected.
Fordern Sie eine Preisvorschau an. selection und destinationCountry sind erforderlich; eine leere selection nimmt die Standardwerte:
curl -s -X POST $API/v1/quote-previews -H "authorization: Bearer $T" -H 'content-type: application/json' \
-d "{\"designId\":\"$D\",\"quantities\":{\"boardsFabricated\":10,\"boardsAssembled\":0},\"selection\":{},\"destinationCountry\":\"DE\"}" \
| jq '.mode, .reviewReasons, .totalMinor'
mode ist instant (der Preis steht wie angezeigt) oder review (ein Ingenieur bestätigt ihn); reviewReasons sagt warum. totalMinor steht in Nebeneinheiten der currency der Antwort und fehlt, wenn ein Ingenieur den Auftrag bepreisen muss. Um ein Angebot zu speichern, nimmt POST /v1/quotes denselben Body.
Derselbe Ablauf mit dem JavaScript-Client
Der Client @ulike/sdk umhüllt diese Routen. Er ist noch nicht als Paket veröffentlicht; dies ist seine Form, damit Sie dieselben Aufrufe mit fetch schreiben können. Methodennamen:
import { createClient } from '@ulike/sdk';
let token;
const api = createClient({ baseUrl: 'https://dev.uliketechnology.com/api', token: () => token });
const caps = await api.capabilities();
token = (await api.createGuestSession()).token;
const started = await api.uploadDesign({ name: 'board.zip', bytes }); // announce, PUT, complete
const view = await api.waitForDesign(started.design.id); // polls getDesign
const preview = await api.previewQuote({
designId: view.design.id,
quantities: { boardsFabricated: 10, boardsAssembled: 0 },
selection: {},
destinationCountry: 'DE',
});
Die weiteren Methoden sind createUpload, completeUpload, getDesign, setLayerMapping, validateDesign, getValidation, waitForValidation, createQuote, getQuote und reviseQuote. Fehler werden als ApiClientError mit status und code geworfen.
Die Prüfung für eine Bestellung
Der Bericht, den Sie nach dem Hochladen erhalten, wird nur aus den Dateien erstellt. Um die Dateien gegen eine Bestellung zu prüfen, rufen Sie POST /v1/designs/{designId}/validations (validateDesign) mit order auf, das quantities und selection enthält. Die Antwort ist ein Zustand: running, failed oder done. Während running lesen Sie GET /v1/validations/{reportId} (getValidation) alle ein bis zwei Sekunden, bis er done ist.
- Laden Sie das Zip-Archiv hoch.
- Lesen Sie den Bericht.
- Korrigieren Sie und laden Sie als neues Design hoch. Stoppen Sie und fragen Sie die Person, wenn eine Korrektur die Funktion, den Preis oder die Lieferzeit ändert.
- Saubere Dateien: Führen Sie die Prüfung für die Bestellung aus.
Ein Angebot oder eine Vorschau mit Optionen, die andere Grenzwerte mit sich bringen (dickeres Kupfer, andere Dicke), braucht eine Prüfung für diese Auswahl. Wenn keine vorhanden ist, wird eine gestartet, und die Vorschau trägt den Prüfungsgrund file_check_pending und ein check mit seiner reportId. Der Preis wird sofort angezeigt, aber das Angebot bleibt in review, bis diese Prüfung fertig ist. Lesen Sie die Prüfung wie oben und fordern Sie die Vorschau dann erneut an.
Fehler, denen Sie begegnen werden
| Code | Status | Was es bedeutet | Was zu tun ist |
|---|---|---|---|
DESIGN_NOT_READY |
422 | Das Design wird noch gelesen (details.status sagt, in welchem Zustand), oder es hat noch keinen Bericht. |
Lesen Sie das Design, bis der Status nicht mehr analysing ist, dann fragen Sie erneut. |
VALIDATION_FAILED |
400 | Die Anfrage hat nicht die erwartete Form oder nennt eine Option oder einen Wert, den der Katalog nicht hat. details listet die Punkte oder Probleme. |
Korrigieren Sie das in details genannte Feld und senden Sie erneut. Nehmen Sie Options-IDs und Werte aus GET /v1/capabilities. |
NOT_MANUFACTURABLE |
422 | Die Auswahl ist etwas, das wir nicht fertigen. details.because trägt die Gründe. |
Ändern Sie die Auswahl; versuchen Sie dieselbe nicht erneut. Fragen Sie die Person, wenn die Änderung die Platine verändern würde. |
ANONYMOUS_BUDGET_SPENT |
429 | Das tägliche Kontingent ohne Benutzerkonto ist aufgebraucht. details.resetsOn ist das Datum. |
Stoppen Sie. Sagen Sie es der Person; sie kann sich anmelden oder bis zu diesem Datum warten. |
REVISION_CONFLICT |
409 | Eine Revision nannte eine Basis, die nicht mehr der Kopf des Angebots ist. details trägt beide Köpfe. |
Lesen Sie den Kopf mit GET /v1/quotes/{quoteId}, wenden Sie Ihre Änderung darauf an und senden Sie erneut. |
Möglich sind auch DESIGN_REJECTED (der Upload wurde abgelehnt; siehe details.reason), UNAUTHENTICATED für ein fehlendes oder falsches Token (ein falsches Token wird auch auf öffentlichen Routen abgelehnt) und FEATURE_DISABLED für eine Route, die noch nicht offen ist.
Das tägliche Kontingent ohne Benutzerkonto
Eine Gast-Sitzung hat ein tägliches Kontingent an Rechenzeit. Uploads und gestartete Prüfungen kosten mehr als ein einfaches Lesen, und das Öffnen vieler Gast-Sitzungen von einer Netzwerkadresse wird ebenfalls gezählt. Eine Prüfung, die die Website von sich aus für eine neue Auswahl startet, wird auf dasselbe Kontingent angerechnet. Wenn es aufgebraucht ist, erhalten Sie ANONYMOUS_BUDGET_SPENT mit dem Datum, an dem es zurückgesetzt wird. Angemeldete Aufrufer werden nicht so gezählt.
Was die API heute nicht kann: Bestellung, Zahlung, API-Schlüssel und Anmeldung für Agenten sind geplant und nicht verfügbar. Der geplante MCP-Server wird in Was MCP ist und wie Agenten bestellen beschrieben.