모든 가이드

AI 어시스턴트

API 빠른 시작: 업로드, 검사, 견적

기판 파일을 파일 검사 보고서와 가격 미리보기로 연결하는 호출을 curl과 JavaScript 클라이언트로 설명하고, 발생할 수 있는 오류를 다룹니다.

AI 어시스턴트용2026-11-10 업데이트읽는 시간 4분AI 어시스턴트용 원시 Markdown

시작하기 전에

API는 비회원 세션을 통해 계정 없이 동작합니다. API는 사이트 자체 주소의 /api 아래에 있습니다. 한 번만 설정하십시오:

API=https://dev.uliketechnology.com/api
F=board.zip

board.zip은 Gerber 파일과 드릴 파일을 평면 구조로 담은 zip 파일입니다. zip에 넣을 파일은 제조와 조립을 위한 파일을 참조하십시오. 예제에는 curl과 jq가 필요합니다.

비회원 세션 이후 API에 대한 모든 요청에는 Authorization: Bearer <token>가 필요합니다. 모든 오류는 같은 형식을 갖습니다:

{ "error": { "code": "VALIDATION_FAILED", "message": "…", "details": {}, "requestId": "…" } }

code를 기준으로 분기하십시오. message는 개발자를 위한 것입니다.

순서대로 다섯 개의 작은 그림: 열쇠, 업로드 주소로 이동하는 파일, 모래시계, 발견 사항이 있는 보고서 페이지, 가격표
  1. 비회원 세션: 토큰은 한 번만 표시됩니다.
  2. 업로드: API가 지정한 주소로, API가 지정한 헤더를 사용하여 zip을 PUT합니다.
  3. 완료, 분석이 끝날 때까지 폴링합니다.
  4. 보고서: 발견 사항, 실행된 검사와 실행되지 않은 검사입니다.
  5. 견적 미리보기.

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입니다. 오류는 status와 code를 가진 ApiClientError로 던져집니다.

주문에 대한 검사

업로드 후 받는 보고서는 파일만으로 작성됩니다. 주문과 비교하여 파일을 검사하려면 order에 quantities와 selection을 담아 POST /v1/designs/{designId}/validations(validateDesign)를 호출하십시오. 응답은 running, failed, done 중 하나의 상태입니다. running인 동안에는 done이 될 때까지 1~2초마다 GET /v1/validations/{reportId}(getValidation)를 읽으십시오.

세 단계의 반복: 파일을 업로드하고, 보고서를 읽고, 수정하여 다시 업로드합니다. 파일이 깨끗해지면 반복을 벗어나 체크 표시로 향하는 화살표가 있습니다
  1. 업로드 zip을 업로드합니다.
  2. 보고서 읽기.
  3. 수정하여 새 설계로 업로드합니다. 수정이 기능, 가격 또는 납기를 변경할 경우 중단하고 담당자에게 문의하십시오.
  4. 깨끗한 파일: 주문에 대한 검사를 실행합니다.

다른 제한 사항(더 두꺼운 동박, 다른 두께)을 가져오는 옵션이 있는 견적이나 미리보기에는 해당 선택에 대한 검사가 필요합니다. 검사가 없으면 검사가 시작됩니다. 미리보기에는 검토 사유 file_check_pending와 reportId를 가진 check가 포함됩니다. 가격은 즉시 표시됩니다. 그러나 해당 검사가 완료될 때까지 견적은 review 상태로 유지됩니다. 위와 같은 방법으로 검사를 읽은 다음 미리보기를 다시 요청하십시오.

발생할 수 있는 오류

코드 상태 의미 조치
DESIGN_NOT_READY 422 설계를 아직 읽고 있는 중이거나(details.status가 어떤 상태인지 알려줍니다), 아직 보고서가 없습니다. 상태가 analysing이 아닐 때까지 설계를 반복해서 읽은 다음 다시 요청하십시오.
VALIDATION_FAILED 400 요청 형식이 예상과 다르거나, 카탈로그에 없는 옵션이나 값을 지정했습니다. details에 이슈나 문제가 나열됩니다. details에 이름이 지정된 필드를 수정하여 다시 전송하십시오. 옵션 id와 값은 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란 무엇이며 에이전트는 어떻게 주문하는가에 설명되어 있습니다.

실제 기판으로 해보기

기판을 업로드하고 25건의 검사를 확인하십시오.

기판 업로드