# XenoCI Mac mini M4 단독 대여 · 24시간 이용권 · 최대 30일 · 국내 원화 카드 · VAT 포함 · 자동결제·자동연장 없음 - Mac mini M4 16GB · 512GB: 14,900원 / 24시간 (부가세 포함) · 8코어 · 14GB 전용 VM 임대 - Mac mini M4 16GB · 256GB: 9,900원 / 24시간 (부가세 포함) · 8코어 · 14GB 전용 VM 임대 - 상품은 24시간 이용권 하나입니다. 24시간 × N, 연장도 24시간 단위입니다. - 맥 한 대 최대 30일 · 24시간은 시작 시각부터 셈 - API 키 하나로 대여한 여러 대에 빌드가 자동 분배됩니다. - 빌드 전용 · SSH/화면 접속 없음 - GitHub Actions: `uses: xeno-ci/build@v1` · CLI: `npx github:xeno-ci/build build` - 환불: 시작 전 취소: 결제 금액 전액 환불 - 환불: 시작된 24시간 이용권: 단순 변심 환불 불가(1분만 사용해도 그 24시간 이용권은 사용한 것으로 봄) · 24시간 이용권 1개 결제는 시작 후 단순 변심 환불 불가 - 환불: 아직 시작하지 않은 24시간 이용권: 결제일 또는 이용 시작일 중 늦은 날부터 7일 안에 요청하면 결제 당시 24시간 가격으로 환불 - 환불: 24시간 이용권은 시작 시각부터 24시간 단위로 셈 - 환불: 회사 장애(맥·VM 장애, 준비 실패, 약속한 사양 미제공): 사용하지 못한 시간만큼 이용 시간을 연장(연장할 수 없을 때만 그 시간만큼 환불) - 환불: 빌드 스크립트 실패, 코드·설정 문제는 회사 장애가 아니며 환불 사유가 아님 - 환불: 서비스가 표시·광고와 다르면 안 날부터 30일, 이용 시작일부터 3개월 안에 환불 요청 가능 - 환불: 카드사 이의제기(차지백)나 회사가 하지 않은 결제 취소가 접수되면 계정 이용이 정지되고 진행 중인 임대가 끝남 - [시작하기](https://dev.xenoci.com/rental) - [시작 가이드](https://dev.xenoci.com/docs/getting-started) - [환불 규정](https://dev.xenoci.com/refund) - [전체 문서](https://dev.xenoci.com/llms-full.txt) ## AI 에이전트로 쓰기 XenoCI는 AI 에이전트가 API 키 하나로 맥을 빌리고 빌드하는 서비스입니다. 사람은 가입, API 키 발급, AI가 보여 준 결제 링크에서 동의·결제만 합니다. 시작 3단계: 1. https://dev.xenoci.com/app/api-keys 에서 API 키를 만듭니다. 2. AI 도구에 MCP 서버를 추가합니다: `claude mcp add xenoci --env XENOCI_API_KEY=키 -- npx -y -p github:xeno-ci/build xenoci-mcp` (Codex는 `codex mcp add` 같은 형식). 3. AI에게 이렇게 말합니다: "XenoCI MCP 도구로 맥이 있는지 보고, 없으면 24시간 1대를 주문해서 결제 링크를 나한테 보여 줘. 결제가 끝나면 이 폴더를 빌드하고, 실패하면 로그에서 원인을 찾아 고친 뒤 다시 빌드해 줘. https://xenoci.com/llms.txt 를 먼저 읽어." - 흐름: catalog → create_order → pay_url을 사람에게 → wait_order → build → 실패하면 build_log mode=failure → 고치고 build → list_macs로 남은 시간 → extend(pay_url) - 오류: 모든 4xx·5xx는 `{"error":{"code","message","retryable","retry_after_s","fault","next","docs","request_id"}}`. `next`에 다음 요청이 들어 있습니다. 요청 헤더 `XenoCI-Error-Format: 2`. - Mac 관리(manage 권한): 전체 리셋 `POST /rentals/reset {all:true}`, 한 대 리셋 `POST /rentals/{id}/reset`, 전체 Xcode `POST /rentals/xcode {all:true, version}`, 한 대 설정 `PATCH /rentals/{id} {xcode, runtimes, tools}`. 일부만은 `ids:[...]`. Mac마다 `result`(accepted|rejected)·`reason`·`job_id`. 진행은 `GET /jobs/{job_id}`, Mac의 `mac_state`는 resetting·updating. 빌드 중이면 `when: "after_build"` 또는 `"now"`. 같은 Mac에 겹치면 409 `job_in_progress`. `Idempotency-Key` 헤더 지원. - 권한: read(보기) · build(빌드) · manage(관리: Mac 관리·연장 주문·시크릿). - 돈: API는 결제하지 않습니다. 주문·연장은 pay_url만 돌려줍니다. 환불은 API로 할 수 없습니다. 임대는 시간이 끝나면 자동 종료됩니다. - [OpenAPI 3.1](https://dev.xenoci.com/openapi.json) · [오류 코드 표](https://dev.xenoci.com/docs/errors) · [AI 시작 안내](https://dev.xenoci.com/docs/ai/start) · [에이전트 시나리오](https://dev.xenoci.com/docs/ai/scenario) · [API 목록](https://dev.xenoci.com/docs/api) ### 엔드포인트 (Authorization: Bearer 키, 기본 주소 https://dev.xenoci.com/api/ci/v1) - `GET /me` [read] · MCP `account` · CLI `xenoci whoami`: 이 API 키의 계정·키 이름·권한(scopes)·한도(limits)·남은 요청 수(remaining). /account도 같음 - `GET /account` [read] · MCP `account` · CLI `xenoci whoami`: /me와 같음 - `GET /catalog` [read] · MCP `catalog` · CLI `xenoci catalog`: 상품별 24시간 가격(원, VAT 포함)·사양·Xcode·지금 배정 가능한 대수(available_now)·sales_open·내 재입고 알림 - `POST /quote` [read] · MCP `quote` · CLI `xenoci order --tier ID --hours 24 --quote`: 새 임대 견적(부작용 없음) - `POST /orders` [manage] · MCP `create_order` · CLI `xenoci order --tier ID --hours 24`: 주문 생성 → 201 + pay_url(30분 유효). 사람이 같은 계정으로 열어 동의·결제. API는 동의·결제를 하지 않음 - `GET /orders` [read] · MCP `order_status` · CLI `xenoci orders`: 주문 목록(?status=awaiting_payment 등) - `GET /orders/{order_no}` [read] · MCP `order_status` · CLI `xenoci order RT-…`: 주문 상태(awaiting_payment·paid·provisioning·ready·expired·canceled)·pay_url·rental_ids - `GET /orders/{order_no}/wait` [read] · MCP `wait_order` · CLI `xenoci wait RT-…`: 상태가 바뀌거나 ready·expired·canceled가 될 때까지 최대 60초 롱폴(timeout=초) - `GET /rentals` [read] · MCP `list_macs` · CLI `xenoci macs`: 빌린 맥(남은 시간·연장 가능 여부·현재 빌드)과 빌드 대기열 - `GET /rentals/{rental_id}` [read] · MCP `list_macs` · CLI `xenoci macs`: 맥 한 대 상세. mac_state(preparing·ready·building·resetting·updating), setup, setup_options(바꿀 수 있는 Xcode·runtimes·tools), op(마지막 작업) - `POST /rentals/{rental_id}/extend/quote` [read] · MCP `extend (quote_only)` · CLI `xenoci extend rt_… --hours 24 --quote`: 연장 견적 - `POST /rentals/extend/quote` [read] · CLI `xenoci extend rt_1 rt_2 --hours 24 --quote`: 여러 대 연장 견적(부작용 없음). Mac마다 ok·amount_won 또는 reason. extension_unavailable이면 여기서 이유 확인 - `POST /rentals/{rental_id}/extend` [manage] · MCP `extend` · CLI `xenoci extend rt_… --hours 24`: 한 대 연장 주문 → pay_url - `POST /rentals/extend` [manage] · MCP `extend` · CLI `xenoci extend rt_1 rt_2 --hours 24`: 여러 대 한 번에 연장 → pay_url 하나. 하나라도 불가면 409 extension_unavailable + items - `POST /rentals/reset` [manage] · MCP `reset_macs` · CLI `xenoci reset --all [--keep-cache]`: 내 Mac 전체(all: true) 또는 일부(ids)의 VM을 재설정 → Mac마다 {rental_id, result: accepted|rejected, reason, job_id}. keep_cache: true는 작업 폴더만 비움(캐시 유지), false(기본)는 새 VM(10분에 1번·하루 20번). 빌드 중인 Mac은 when: after_build(끝난 뒤) 또는 now(빌드 취소 후) - `POST /rentals/{rental_id}/reset` [manage] · MCP `reset_macs` · CLI `xenoci reset rt_… [--keep-cache]`: Mac 한 대 VM 재설정 → 202 {rental_id, result, job_id}. 진행은 GET /jobs/{job_id} - `POST /rentals/xcode` [manage] · MCP `set_xcode` · CLI `xenoci xcode --all --version 27.0`: 내 Mac 전체(all: true) 또는 일부(ids)의 Xcode를 바꿈. 그 등급에서 고를 수 없는 Mac만 rejected(reason xcode_not_available, detail.options) - `POST /rentals/{rental_id}/xcode` [manage] · MCP `set_xcode` · CLI `xenoci xcode rt_… --version 27.0`: Mac 한 대 Xcode 변경 → 202 {rental_id, result, job_id}. 이미 그 버전이면 200 status: unchanged - `PATCH /rentals/{rental_id}` [manage] · MCP `update_mac` · CLI `xenoci setup rt_… --xcode 26.6 --runtimes "iOS 26.6" --tools fastlane,cocoapods`: Mac 한 대의 Xcode·시뮬레이터 런타임·도구·캐시 유지 설정 변경. 값은 rentals/{id}의 setup_options(카탈로그)에 있는 것만. 아니면 400 invalid_setup + options - `GET /jobs/{job_id}` [read] · MCP `job_status` · CLI `xenoci job op_…`: 리셋·Xcode·설정 작업 상태: queued(빌드가 끝나기를 기다림)·running·done·failed, error·message. Mac의 mac_state는 작업 중 resetting(리셋)·updating(Xcode·설정) - `POST /rentals/batch` [manage]: 콘솔용 일괄 작업({action: xcode|reset, rental_ids}). API에서는 /rentals/reset·/rentals/xcode를 쓰세요 - `GET /waitlist` [read] · MCP `join_waitlist` · CLI `xenoci waitlist`: 재입고 알림 신청 목록 - `POST /waitlist` [manage] · MCP `join_waitlist` · CLI `xenoci waitlist --tier ID`: 재입고 알림 신청 - `DELETE /waitlist/{id}` [manage] · MCP `join_waitlist (leave)` · CLI `xenoci waitlist --leave ID`: 재입고 알림 취소 - `GET /pool` [read] · MCP `list_macs` · CLI `xenoci pool`: 빈 자리와 대기열 - `POST /uploads` [build] · MCP `build` · CLI `xenoci build`: 폴더 업로드: gzip 매니페스트 → 서버에 없는 파일 목록(missing). 빠진 파일은 /uploads/{id}/blobs로 보냄 - `POST /uploads/{id}/blobs` [build] · MCP `build` · CLI `xenoci build`: 빠진 파일 묶음(gzip) 전송. 각 레코드는 " \n" - `GET /uploads/{id}` [read]: 업로드 상태: 아직 필요한 파일(missing)과 ready. upload_incomplete이면 여기서 빠진 파일을 확인 - `POST /uploads/tar` [build]: CLI 없이 tar.gz 한 번에 업로드(curl·PowerShell) → 바로 빌드할 수 있는 upload_id - `POST /builds` [build] · MCP `build` · CLI `xenoci build --script ./ci.sh`: 빌드 제출. 소스는 upload_id·repo_url·repo 중 하나, rental_id로 맥 지정, queue_until_rental: true면 맥이 생길 때까지 대기. Idempotency-Key 지원 - `GET /builds` [read]: 빌드 목록(rental·state·from·to·q·before·limit) - `GET /builds/{build_id}` [read] · MCP `build_status` · CLI `xenoci status rb_…`: 빌드 상태·대기 순번(queue_position)·estimated_start_at·종료 코드·실패 요약(failure) - `GET /builds/{build_id}/wait` [read] · MCP `wait_build` · CLI `xenoci wait rb_…`: 빌드가 끝날 때까지 최대 60초 롱폴 - `GET /builds/{build_id}/log` [read] · MCP `build_log` · CLI `xenoci logs rb_… [--failure | --tail N]`: 로그. offset=N이면 JSON 구간, format=text&wait=S면 텍스트 스트림 - `PATCH /builds/{build_id}` [build]: 대기 중인 빌드의 우선순위 변경(priority 0|1). 대기 중이 아니면 409 build_not_queued - `POST /builds/{build_id}/cancel` [build] · MCP `cancel_build` · CLI `xenoci cancel rb_…`: 빌드 취소 - `GET /secrets` [read] · MCP `secrets (list)` · CLI `xenoci secrets`: 빌드 시크릿 이름 목록(값은 돌려주지 않음) - `PUT /secrets/{name}` [manage] · MCP `secrets (put)` · CLI `xenoci secrets put NAME < 값`: 시크릿 저장. 빌드에 환경 변수로 들어가고 로그에서 가려짐 - `DELETE /secrets/{name}` [manage] · MCP `secrets (delete)` · CLI `xenoci secrets delete NAME`: 시크릿 삭제 - `GET /errors` [read] · MCP `list_errors` · CLI `xenoci errors`: 내 계정 최근 API 오류와 실패 빌드(?fault=&code=&kind=api|build&since=&key=self) ### 오류 코드 - `api_key_required` (HTTP 401, client, 재시도 안 함): Authorization 헤더가 없거나 형식이 틀림 → Authorization: Bearer xeno_ci_… 헤더를 붙임. 키가 없으면 사람에게 /app/api-keys 에서 만들어 달라고 요청 - `invalid_api_key` (HTTP 401, client, 재시도 안 함): 없는·폐기된·만료된 키이거나 계정이 비활성 → 사람에게 새 키를 받아 달라고 요청 - `organization_suspended` (HTTP 403, client, 재시도 안 함): 계정 정지 → 멈추고 사람에게 알림 - `ip_not_allowed` (HTTP 403, client, 재시도 안 함): 키에 허용된 IP(CIDR) 밖에서 호출 → 허용된 곳에서 호출하거나 사람에게 키의 허용 IP 변경을 요청 - `insufficient_scope` (HTTP 403, client, 재시도 안 함): 키에 이 요청 권한이 없음. error_detail.required_level(read·build·manage), required_scope, key_levels 포함 → 사람에게 required_level 권한이 켜진 키를 요청 - `forbidden` (HTTP 403, client, 재시도 안 함): 그 밖의 권한 없음 → 키와 계정을 확인. 재시도하지 않음 - `api_key_read_only` (HTTP 403, client, 재시도 안 함): 읽기 전용 키로 쓰기 요청 → build·order 권한이 있는 키를 사용 - `api_key_write_only` (HTTP 403, client, 재시도 안 함): 쓰기 전용 키로 읽기 요청 → read 권한이 있는 키를 사용 - `organization_required` (HTTP 403, client, 재시도 안 함): 키가 계정에 연결되어 있지 않음 → 사람에게 키를 다시 만들어 달라고 요청 - `account_blocked` (HTTP 403, payment, 재시도 안 함): 결제 분쟁 등으로 계정의 결제가 막힘 → 멈추고 사람에게 알림 - `rate_limited` (HTTP 429, client, 재시도 가능): 1분 요청 수 한도 초과. retry_after_s 포함 → retry_after_s(또는 Retry-After)만큼 기다린 뒤 같은 요청 - `too_many_pending_orders` (HTTP 429, client, 재시도 가능): 이 키의 결제 대기 주문 수 한도 → GET /orders?status=awaiting_payment 로 기존 주문을 확인해 결제를 요청하거나 결제 링크가 만료되기를 기다림 - `too_many_concurrent_builds` (HTTP 429, client, 재시도 가능): 이 키의 동시 빌드 수 한도 → GET /builds?state=running 으로 확인하고 끝나기를 기다린 뒤 다시 제출 - `queue_full` (HTTP 429, capacity, 재시도 가능): 계정 빌드 대기열이 가득 참 → GET /builds?state=queued 로 확인하고 진행 중인 빌드가 끝난 뒤 다시 제출 - `no_capacity` (HTTP 409, capacity, 재시도 가능): 고른 상품에 지금 빈 맥이 없음 → next의 POST /waitlist로 재입고 알림을 신청하거나 catalog에서 다른 상품을 고름 - `sales_closed` (HTTP 409, capacity, 재시도 가능): 지금은 판매를 받지 않음 → GET /catalog 로 sales_open을 다시 확인하고 사람에게 알림 - `available_now` (HTTP 409, client, 재시도 안 함): 재고가 있어 재입고 알림 대신 바로 주문할 수 있음 → POST /orders 로 주문 - `waitlist_exists` (HTTP 409, client, 재시도 안 함): 같은 상품 재입고 알림이 이미 있음 → 그대로 둠(GET /waitlist) - `order_not_found` (HTTP 404, client, 재시도 안 함): 없는 주문이거나 다른 계정의 주문 → GET /orders 로 번호 확인 - `order_expired` (HTTP 409, client, 재시도 안 함): 결제 링크나 자리 보류가 만료됨 → POST /orders 로 새로 주문하고 새 pay_url을 사람에게 보여 줌 - `order_not_payable` (HTTP 409, client, 재시도 안 함): 이미 결제되었거나 취소된 주문 → GET /orders/{order_no} 로 상태 확인 - `payment_mismatch` (HTTP 400, payment, 재시도 안 함): 결제 검증 불일치(결제 화면 전용) → 사람에게 알림 - `consent_required` (HTTP 400, client, 재시도 안 함): 사람의 동의가 없음(결제 화면 전용, API 주문에서는 나오지 않음) → pay_url을 사람에게 보여 줌. 동의는 사람이 결제 화면에서 함 - `rental_not_found` (HTTP 404, client, 재시도 안 함): 없는 맥이거나 다른 계정의 맥 → GET /rentals 로 ID 확인 - `rental_not_active` (HTTP 409, client, 재시도 안 함): 맥이 사용 중 상태가 아님 → GET /rentals/{id} 로 상태 확인 - `extension_deadline` (HTTP 409, client, 재시도 안 함): 종료 10분 전이 지나 연장할 수 없음 → 새 맥을 주문하고 빌드를 옮김 - `extension_pending` (HTTP 409, client, 재시도 가능): 같은 맥의 연장 결제가 진행 중 → GET /orders?status=awaiting_payment 의 pay_url을 사람에게 다시 보여 줌 - `extension_unavailable` (HTTP 409, client, 재시도 안 함): 일괄 연장 중 연장할 수 없는 맥이 있음(items에 맥별 reason) → POST /rentals/extend/quote 로 확인하고 가능한 맥만 다시 주문 - `rental_duration_limit` (HTTP 422, client, 재시도 안 함): 같은 맥 30일 상한을 넘김 → hours를 줄이거나(max_extend_days) 새 맥을 주문 - `reservation_conflict` (HTTP 409, capacity, 재시도 안 함): 다음 예약과 겹침 → hours를 줄이거나 다른 맥을 주문 - `invalid_period` (HTTP 422, client, 재시도 안 함): hours가 24의 배수가 아니거나 범위를 벗어남 → GET /catalog 의 기간 규칙대로 24, 48, 72 … - `invalid_tier` (HTTP 400, client, 재시도 안 함): 주문·견적 입력 오류(invalid_setup, invalid_quote, invalid_order, invalid_start, invalid_hours, invalid_rentals도 같음) → GET /catalog 를 보고 입력을 고침 - `no_active_rental` (HTTP 409, client, 재시도 안 함): 빌드할 맥이 없음 → GET /catalog → POST /orders 로 맥을 빌리거나, queue_until_rental: true 로 빌드를 대기시킴 - `build_not_found` (HTTP 404, client, 재시도 안 함): 없는 빌드이거나 다른 계정의 빌드 → GET /builds 로 ID 확인 - `build_not_queued` (HTTP 409, client, 재시도 안 함): 대기 중인 빌드가 아님(우선순위 변경 불가) → 그대로 둠 - `invalid_script` (HTTP 400, client, 재시도 안 함): 빌드 입력 오류(invalid_build, invalid_xcode, one_source_only, invalid_repo_url, repo_host_not_allowed, invalid_ref 등도 같음) → 입력을 고쳐 다시 제출. xcode는 catalog의 목록에서 - `upload_incomplete` (HTTP 409, client, 재시도 가능): 업로드한 파일이 아직 다 오지 않음 → GET /uploads/{id} 로 빠진 파일을 보내고 다시 제출 - `upload_not_found` (HTTP 404, client, 재시도 안 함): 업로드가 없거나 만료됨 → 폴더를 다시 업로드(build 도구는 자동) - `uploads_unavailable` (HTTP 503, platform, 재시도 가능): 업로드 저장소 문제(우리 쪽) → retry_after_s 뒤에 다시 - `gzip_required` (HTTP 415, client, 재시도 안 함): 업로드는 gzip이어야 함 → Content-Type: application/gzip - `manifest_too_large` (HTTP 413, client, 재시도 안 함): 업로드 매니페스트가 너무 큼 → .gitignore로 파일 수를 줄임 - `upload_too_large` (HTTP 400, client, 재시도 안 함): 업로드 입력 오류(invalid_gzip, invalid_manifest, invalid_tar, too_many_files, empty_upload 등도 같음) → .gitignore로 빌드 산출물·의존성 폴더를 빼고 다시 업로드 - `blob_not_in_manifest` (HTTP 409, client, 재시도 안 함): 매니페스트에 없는 파일을 보냄 → 업로드를 처음부터 다시 - `invalid_offset` (HTTP 400, client, 재시도 안 함): 조회 파라미터 오류(invalid_wait, invalid_timeout, invalid_time, invalid_from, invalid_to도 같음) → 파라미터를 고침 - `invalid_secret_name` (HTTP 400, client, 재시도 안 함): 시크릿 입력 오류(invalid_secret_value, secrets_limit도 같음) → 이름은 대문자·숫자·_ (예: MATCH_PASSWORD) - `secret_not_found` (HTTP 404, client, 재시도 안 함): 그런 이름의 시크릿이 없음 → GET /secrets 로 이름 확인 - `waitlist_not_found` (HTTP 404, client, 재시도 안 함): 재입고 알림 신청이 없음 → GET /waitlist 로 ID 확인 - `waitlist_not_cancellable` (HTTP 409, client, 재시도 안 함): 이미 처리된 재입고 알림 → 그대로 둠 - `invalid_waitlist` (HTTP 400, client, 재시도 안 함): 재입고 알림 입력 오류 → GET /catalog 의 tier로 다시 - `reset_limit` (HTTP 429, client, 재시도 가능): VM 재설정(새 VM)은 10분에 1번, 하루 20번까지 → 잠시 뒤 다시 하거나 keep_cache: true(작업 폴더만 비움)로 진행 - `job_in_progress` (HTTP 409, client, 재시도 가능): 이 Mac에 리셋·Xcode·설정 작업이 이미 대기 중이거나 진행 중. error_detail.job_id → next의 GET /jobs/{job_id}가 done·failed가 된 뒤 다시 - `job_not_found` (HTTP 404, client, 재시도 안 함): 이 계정에 그런 작업이 없음 → job_id 확인(op_…) - `invalid_setup` (HTTP 400, client, 재시도 안 함): 카탈로그에 없는 Xcode·runtimes·tools 값, 또는 바꿀 값이 없음. error_detail.field, options → options 중에서 다시 - `invalid_target` (HTTP 400, client, 재시도 안 함): all: true와 ids 중 하나만 보내야 함 → 둘 중 하나로 다시 - `invalid_when` (HTTP 400, client, 재시도 안 함): when은 after_build 또는 now → 둘 중 하나로 다시 - `invalid_idempotency_key` (HTTP 400, client, 재시도 안 함): Idempotency-Key는 보이는 ASCII 1~200자 → 새 키로 다시 - `idempotency_conflict` (HTTP 409, client, 재시도 안 함): 같은 Idempotency-Key를 다른 요청에 썼음 → 새 키로 다시. 같은 요청을 다시 보내면 첫 응답이 그대로 옴(Idempotent-Replayed: true) - `xcode_not_available` (HTTP 400, client, 재시도 안 함): 이 맥 등급에서 고를 수 없는 Xcode 버전. error_detail.options에 고를 수 있는 목록 → options 중 하나로 다시 - `endpoint_removed` (HTTP 410, client, 재시도 안 함): 없어진 엔드포인트(결제 전 주문 취소 등) → 결제하지 않은 주문은 결제 링크가 만료되면 자동으로 풀림. 그대로 둠 - `reset_failed` (HTTP 409, platform, 재시도 가능): 맥 초기화 실패(우리 쪽) → 잠시 뒤 다시. 자동으로 XenoCI에 보고됨 - `rental_busy` (HTTP 409, client, 재시도 가능): 빌드 실행 중이라 바로 Xcode 변경·재설정을 할 수 없음 → when: "after_build"(빌드가 끝난 뒤) 또는 when: "now"(빌드를 취소하고 바로)를 붙여 다시 - `rental_only` (HTTP 410, client, 재시도 안 함): /jobs는 폐기됨 → POST /builds 사용 - `internal_error` (HTTP 500, platform, 재시도 가능): 우리 쪽 오류. 자동으로 XenoCI에 보고됨 → 잠시 뒤 같은 요청을 한 번 재시도. 계속되면 request_id를 사람에게 전달 ## Agent API - 기본 주소: https://dev.xenoci.com/api/ci/v1. 아래 조회는 모두 read 권한으로 가능하며 기존 인증·요청 한도·오류 봉투를 사용합니다. - GET /status: 계정·하루권·모든 Mac 상태와 남은 시간·연장 가능 일수·조언·내 큐·최근 빌드 10개. - 조언: 24시간 미만이고 연장 가능하면 extend_recommended(1일 견적), 3시간 미만이면 expiring_soon. queue_backlog와 no_active_mac은 다음 행동을 안내합니다. - GET /queue: 실행 중 Mac, 대기 순번(queue_position), 생성 순서(fifo_position), 타임아웃 기준 예상 대기 초. 준비 시간이나 배정 가능 여부를 알 수 없으면 예상값은 null입니다. - GET /builds?status=&state=&repo=&pr=&rental_id=&from=&to=&q=&before=&limit=: 내 빌드 필터(최대 200개). 다음 페이지는 응답의 next_before를 before로 전달합니다. POST /builds에 선택 pr(양의 정수), commit(7~40자리 SHA)을 저장할 수 있습니다. - GET /builds/{id}: 저장소·ref·커밋·PR·소요 시간·종료 코드. failure.category는 customer|platform|unknown, step·600자 이내 결정적 오류 summary·log_url을 함께 반환합니다. - GET /builds/{id}/log?tail=N: 마지막 N줄 원문(0~10000), 기존 offset·wait·download도 유지합니다. - GET /agent/start: 인증된 Markdown 시작 안내. 공개 안내: https://dev.xenoci.com/agent-start.md