Перш ніж Ви почнете
API працює без облікового запису через гостьову сесію. API перебуває за власною адресою сайту, у шляху /api. Установіть його один раз:
API=https://dev.uliketechnology.com/api
F=board.zip
board.zip — це плоский zip із Вашими файлами Gerber і файлом свердління. Що в нього входить, див. у статті Файли для виготовлення та монтажу. Прикладам потрібні curl і jq.
Кожен запит до API після гостьової сесії приймає Authorization: Bearer <token>. Кожна помилка має однакову форму:
{ "error": { "code": "VALIDATION_FAILED", "message": "…", "details": {}, "requestId": "…" } }
Гілкуйтеся за code. Поле message — для розробників.
- Гостьова сесія: токен показується один раз.
- Завантаження: надішліть zip методом
PUTна адресу, яку називає API, із заголовками, які він називає. - Завершення, потім опитування, доки аналіз не буде готовий.
- Звіт: зауваження, які перевірки виконано, а які ні.
- Попередній розрахунок вартості.
Процес із curl
Прочитайте, що можна замовити. Для цього токен не потрібен:
curl -s $API/v1/capabilities | jq '.options[].id'
Відкрийте гостьову сесію. Токен показується один раз і діє 30 днів:
T=$(curl -s -X POST $API/v1/guest-sessions | jq -r .token)
Оголосіть файл. У відповіді є uploadId, designId, uploadUrl і 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\"}")
Надішліть файл на адресу, яку називає відповідь, із кожним заголовком із requiredHeaders (тип умісту, довжина та контрольна сума; без них завантаження відхиляється з кодом 403). Потім завершіть завантаження:
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
Статус спочатку analysing. Читайте проєкт, доки він не зміниться. Коли він буде ready, звіт міститься у відповіді:
D=$(echo $J | jq -r .designId)
curl -s $API/v1/designs/$D -H "authorization: Bearer $T" | jq '.design.status, .report.headline, .report.counts'
Заголовок — no_problems_in_checks_run, problems_found або could_not_check. Прочитайте також checksRun і checksNotRun: перевірка, яка не виконалася, — не пройдена. Інші статуси — needs_mapping (установіть шари викликом PUT /v1/designs/{designId}/layer-mapping), needs_engineer і rejected.
Запросіть попередню ціну. Поля selection і destinationCountry обов’язкові; порожнє selection бере значення за замовчуванням:
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 — instant (ціна діє як показано) або review (інженер її підтверджує); поле reviewReasons каже чому. Поле totalMinor — у молодших одиницях валюти currency відповіді та відсутнє, коли інженер має оцінити роботу. Щоб зберегти розрахунок вартості, виклик POST /v1/quotes приймає те саме тіло.
Той самий процес із JavaScript-клієнтом
Клієнт @ulike/sdk обгортає ці маршрути. Його ще не опубліковано як пакет; це його форма, щоб Ви могли написати ті самі виклики за допомогою fetch. Імена методів:
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',
});
Інші методи — createUpload, completeUpload, getDesign, setLayerMapping, validateDesign, getValidation, waitForValidation, createQuote, getQuote і reviseQuote. Помилки викидаються як ApiClientError із полями status і code.
Перевірка для замовлення
Звіт, який Ви отримуєте після завантаження, зроблено лише за файлами. Щоб перевірити файли проти замовлення, викличте POST /v1/designs/{designId}/validations (validateDesign) із полем order, що містить quantities і selection. Відповідь — стан: running, failed або done. Доки running, читайте GET /v1/validations/{reportId} (getValidation) кожну секунду або дві, доки не буде done.
- Завантаження zip.
- Читання звіту.
- Виправлення та завантаження як новий проєкт. Зупиніться й запитайте людину, коли виправлення змінює функцію, ціну або термін постачання.
- Чисті файли: запустіть перевірку для замовлення.
Розрахунок вартості або попередній розрахунок з опціями, які приносять інші обмеження (товстіша мідь, інша товщина), потребує перевірки для цього вибору. Якщо такої нема, одна запускається, і попередній розрахунок несе причину перевірки file_check_pending і поле check із його reportId. Ціна показується одразу, але розрахунок вартості залишається в review, доки ця перевірка не буде готова. Прочитайте перевірку, як вище, потім запросіть попередній розрахунок знову.
Помилки, які Ви зустрінете
| Код | Статус | Що це означає | Що робити |
|---|---|---|---|
DESIGN_NOT_READY |
422 | Проєкт ще читається (details.status каже, який стан), або в нього ще нема звіту. |
Читайте проєкт, доки статус не перестане бути analysing, потім запитайте знову. |
VALIDATION_FAILED |
400 | Запит не має очікуваної форми або називає опцію чи значення, яких нема в каталозі. Поле details перелічує проблеми. |
Виправте поле, назване в details, і надішліть знову. Ідентифікатори опцій і значення беріть із GET /v1/capabilities. |
NOT_MANUFACTURABLE |
422 | Вибір — те, що ми не виготовляємо. Поле details.because несе причини. |
Змініть вибір; не повторюйте той самий. Запитайте людину, чи змінить зміна плату. |
ANONYMOUS_BUDGET_SPENT |
429 | Денний ліміт без облікового запису вичерпано. Поле details.resetsOn — дата. |
Зупиніться. Скажіть людині; вона може увійти або зачекати до цієї дати. |
REVISION_CONFLICT |
409 | Ревізія назвала базу, яка більше не голова розрахунку вартості. Поле details несе обидві голови. |
Прочитайте голову викликом GET /v1/quotes/{quoteId}, повторно застосуйте зміну на ній і надішліть знову. |
Також можливі коди DESIGN_REJECTED (завантаження було відхилено; див. details.reason), UNAUTHENTICATED за відсутнього або невірного токена (невірний токен відхиляється навіть на публічних маршрутах) і FEATURE_DISABLED для маршруту, який ще не відкрито.
Денний ліміт без облікового запису
Гостьова сесія має денний ліміт обчислень. Завантаження та запущені перевірки коштують більше за просте читання, а відкриття багатьох гостьових сесій з однієї мережевої адреси також рахується. Перевірка, яку сайт запускає сам для нового вибору, списується на той самий ліміт. Коли його вичерпано, Ви отримуєте ANONYMOUS_BUDGET_SPENT із датою його скидання. Користувачі, які увійшли, так не рахуються.
Що API не може сьогодні: замовлення, оплата, ключі API та вхід для агентів заплановано й недоступно. Запланований сервер MCP описано у статті Що таке MCP і як замовляють агенти.