{"openapi":"3.1.0","info":{"title":"XenoCI agent API","version":"1","description":"Rent dedicated Mac mini M4 VMs and build on them with one API key. Money: order endpoints return a pay_url; a person opens it, agrees and pays. Errors: send XenoCI-Error-Format: 2 for the full envelope; act on error.code, error.retryable and error.next. Guide: https://xenoci.com/llms.txt"},"servers":[{"url":"https://xenoci.com/api/ci/v1"}],"security":[{"apiKey":[]}],"paths":{"/me":{"get":{"summary":"이 API 키의 계정·키 이름·권한(scopes)·한도(limits)·남은 요청 수(remaining). /account도 같음","operationId":"getMe","x-scope":"read","x-mcp-tool":"account","x-cli":"xenoci whoami","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/account":{"get":{"summary":"/me와 같음","operationId":"getAccount","x-scope":"read","x-mcp-tool":"account","x-cli":"xenoci whoami","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/catalog":{"get":{"summary":"상품별 24시간 가격(원, VAT 포함)·사양·Xcode·지금 배정 가능한 대수(available_now)·sales_open·내 재입고 알림","operationId":"getCatalog","x-scope":"read","x-mcp-tool":"catalog","x-cli":"xenoci catalog","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/quote":{"post":{"summary":"새 임대 견적(부작용 없음)","operationId":"postQuote","x-scope":"read","x-mcp-tool":"quote","x-cli":"xenoci order --tier ID --hours 24 --quote","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tier":{"type":"string"},"units":{"type":"integer","minimum":1},"hours":{"type":"integer","minimum":24,"multipleOf":24,"description":"24-hour passes × 24"}},"required":["tier","hours"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/orders":{"post":{"summary":"주문 생성 → 201 + pay_url(30분 유효). 사람이 같은 계정으로 열어 동의·결제. API는 동의·결제를 하지 않음","operationId":"postOrders","x-scope":"manage","x-mcp-tool":"create_order","x-cli":"xenoci order --tier ID --hours 24","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tier":{"type":"string"},"units":{"type":"integer","minimum":1},"hours":{"type":"integer","minimum":24,"multipleOf":24,"description":"24-hour passes × 24"},"start":{"type":"string","description":"\"now\" or ISO time"},"setup":{"type":"object","properties":{"xcode":{"type":"string"}},"required":[]}},"required":["tier","hours"]}}}},"responses":{"201":{"description":"Order with pay_url. Show it to a person; only a person can pay.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"get":{"summary":"주문 목록(?status=awaiting_payment 등)","operationId":"getOrders","x-scope":"read","x-mcp-tool":"order_status","x-cli":"xenoci orders","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/orders/{order_no}":{"get":{"summary":"주문 상태(awaiting_payment·paid·provisioning·ready·expired·canceled)·pay_url·rental_ids","operationId":"getOrdersByOrderNo","x-scope":"read","x-mcp-tool":"order_status","x-cli":"xenoci order RT-…","parameters":[{"name":"order_no","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/orders/{order_no}/wait":{"get":{"summary":"상태가 바뀌거나 ready·expired·canceled가 될 때까지 최대 60초 롱폴(timeout=초)","operationId":"getOrdersByOrderNoWait","x-scope":"read","x-mcp-tool":"wait_order","x-cli":"xenoci wait RT-…","parameters":[{"name":"order_no","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals":{"get":{"summary":"빌린 맥(남은 시간·연장 가능 여부·현재 빌드)과 빌드 대기열","operationId":"getRentals","x-scope":"read","x-mcp-tool":"list_macs","x-cli":"xenoci macs","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/{rental_id}":{"get":{"summary":"맥 한 대 상세. mac_state(preparing·ready·building·resetting·updating), setup, setup_options(바꿀 수 있는 Xcode·runtimes·tools), op(마지막 작업)","operationId":"getRentalsByRentalId","x-scope":"read","x-mcp-tool":"list_macs","x-cli":"xenoci macs","parameters":[{"name":"rental_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"patch":{"summary":"Mac 한 대의 Xcode·시뮬레이터 런타임·도구·캐시 유지 설정 변경. 값은 rentals/{id}의 setup_options(카탈로그)에 있는 것만. 아니면 400 invalid_setup + options","operationId":"patchRentalsByRentalId","x-scope":"manage","x-mcp-tool":"update_mac","x-cli":"xenoci setup rt_… --xcode 26.6 --runtimes \"iOS 26.6\" --tools fastlane,cocoapods","parameters":[{"name":"rental_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"같은 키·같은 요청은 24시간 동안 첫 응답을 다시 줌(Idempotent-Replayed: true). 같은 키·다른 요청은 409 idempotency_conflict"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"xcode":{"type":"string"},"runtimes":{"type":"array","items":{"type":"string"}},"tools":{"type":"array","items":{"type":"string"}},"keep_cache":{"type":"boolean"},"when":{"type":"string","enum":["after_build","now"]}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/{rental_id}/extend/quote":{"post":{"summary":"연장 견적","operationId":"postRentalsByRentalIdExtendQuote","x-scope":"read","x-mcp-tool":"extend (quote_only)","x-cli":"xenoci extend rt_… --hours 24 --quote","parameters":[{"name":"rental_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hours":{"type":"integer","minimum":24,"multipleOf":24,"description":"24-hour passes × 24"}},"required":["hours"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/{rental_id}/extend":{"post":{"summary":"한 대 연장 주문 → pay_url","operationId":"postRentalsByRentalIdExtend","x-scope":"manage","x-mcp-tool":"extend","x-cli":"xenoci extend rt_… --hours 24","parameters":[{"name":"rental_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"hours":{"type":"integer","minimum":24,"multipleOf":24,"description":"24-hour passes × 24"}},"required":["hours"]}}}},"responses":{"201":{"description":"Order with pay_url. Show it to a person; only a person can pay.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/extend":{"post":{"summary":"여러 대 한 번에 연장 → pay_url 하나. 하나라도 불가면 409 extension_unavailable + items","operationId":"postRentalsExtend","x-scope":"manage","x-mcp-tool":"extend","x-cli":"xenoci extend rt_1 rt_2 --hours 24","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rental_ids":{"type":"array","items":{"type":"string"}},"hours":{"type":"integer","minimum":24,"multipleOf":24,"description":"24-hour passes × 24"}},"required":["rental_ids","hours"]}}}},"responses":{"201":{"description":"Order with pay_url. Show it to a person; only a person can pay.","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/reset":{"post":{"summary":"내 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(빌드 취소 후)","operationId":"postRentalsReset","x-scope":"manage","x-mcp-tool":"reset_macs","x-cli":"xenoci reset --all [--keep-cache]","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"같은 키·같은 요청은 24시간 동안 첫 응답을 다시 줌(Idempotent-Replayed: true). 같은 키·다른 요청은 409 idempotency_conflict"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"all":{"type":"boolean"},"ids":{"type":"array","items":{"type":"string"}},"keep_cache":{"type":"boolean"},"when":{"type":"string","enum":["after_build","now"]}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/{rental_id}/reset":{"post":{"summary":"Mac 한 대 VM 재설정 → 202 {rental_id, result, job_id}. 진행은 GET /jobs/{job_id}","operationId":"postRentalsByRentalIdReset","x-scope":"manage","x-mcp-tool":"reset_macs","x-cli":"xenoci reset rt_… [--keep-cache]","parameters":[{"name":"rental_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"같은 키·같은 요청은 24시간 동안 첫 응답을 다시 줌(Idempotent-Replayed: true). 같은 키·다른 요청은 409 idempotency_conflict"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keep_cache":{"type":"boolean"},"when":{"type":"string","enum":["after_build","now"]}},"required":[]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/xcode":{"post":{"summary":"내 Mac 전체(all: true) 또는 일부(ids)의 Xcode를 바꿈. 그 등급에서 고를 수 없는 Mac만 rejected(reason xcode_not_available, detail.options)","operationId":"postRentalsXcode","x-scope":"manage","x-mcp-tool":"set_xcode","x-cli":"xenoci xcode --all --version 27.0","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"같은 키·같은 요청은 24시간 동안 첫 응답을 다시 줌(Idempotent-Replayed: true). 같은 키·다른 요청은 409 idempotency_conflict"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"all":{"type":"boolean"},"ids":{"type":"array","items":{"type":"string"}},"version":{"type":"string"},"when":{"type":"string","enum":["after_build","now"]}},"required":["version"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/{rental_id}/xcode":{"post":{"summary":"Mac 한 대 Xcode 변경 → 202 {rental_id, result, job_id}. 이미 그 버전이면 200 status: unchanged","operationId":"postRentalsByRentalIdXcode","x-scope":"manage","x-mcp-tool":"set_xcode","x-cli":"xenoci xcode rt_… --version 27.0","parameters":[{"name":"rental_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"같은 키·같은 요청은 24시간 동안 첫 응답을 다시 줌(Idempotent-Replayed: true). 같은 키·다른 요청은 409 idempotency_conflict"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"version":{"type":"string"},"when":{"type":"string","enum":["after_build","now"]}},"required":["version"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/jobs/{job_id}":{"get":{"summary":"리셋·Xcode·설정 작업 상태: queued(빌드가 끝나기를 기다림)·running·done·failed, error·message. Mac의 mac_state는 작업 중 resetting(리셋)·updating(Xcode·설정)","operationId":"getJobsByJobId","x-scope":"read","x-mcp-tool":"job_status","x-cli":"xenoci job op_…","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/rentals/batch":{"post":{"summary":"콘솔용 일괄 작업({action: xcode|reset, rental_ids}). API에서는 /rentals/reset·/rentals/xcode를 쓰세요","operationId":"postRentalsBatch","x-scope":"manage","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":200},"description":"같은 키·같은 요청은 24시간 동안 첫 응답을 다시 줌(Idempotent-Replayed: true). 같은 키·다른 요청은 409 idempotency_conflict"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["xcode","reset"]},"rental_ids":{"type":"array","items":{"type":"string"}},"xcode":{"type":"string"},"keep_cache":{"type":"boolean"},"when":{"type":"string","enum":["after_build","now"]}},"required":["action","rental_ids"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/waitlist":{"get":{"summary":"재입고 알림 신청 목록","operationId":"getWaitlist","x-scope":"read","x-mcp-tool":"join_waitlist","x-cli":"xenoci waitlist","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"post":{"summary":"재입고 알림 신청","operationId":"postWaitlist","x-scope":"manage","x-mcp-tool":"join_waitlist","x-cli":"xenoci waitlist --tier ID","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tier":{"type":"string"},"units":{"type":"integer","minimum":1}},"required":["tier"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/waitlist/{id}":{"delete":{"summary":"재입고 알림 취소","operationId":"deleteWaitlistById","x-scope":"manage","x-mcp-tool":"join_waitlist (leave)","x-cli":"xenoci waitlist --leave ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/pool":{"get":{"summary":"빈 자리와 대기열","operationId":"getPool","x-scope":"read","x-mcp-tool":"list_macs","x-cli":"xenoci pool","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/uploads":{"post":{"summary":"폴더 업로드: gzip 매니페스트 → 서버에 없는 파일 목록","operationId":"postUploads","x-scope":"build","x-mcp-tool":"build","x-cli":"xenoci build","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/uploads/{id}/blobs":{"post":{"summary":"빠진 파일 묶음(gzip) 전송","operationId":"postUploadsByIdBlobs","x-scope":"build","x-mcp-tool":"build","x-cli":"xenoci build","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/uploads/tar":{"post":{"summary":"CLI 없이 tar.gz 한 번에 업로드(curl·PowerShell)","operationId":"postUploadsTar","x-scope":"build","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/builds":{"post":{"summary":"빌드 제출. 소스는 upload_id·repo_url·repo 중 하나, rental_id로 맥 지정, queue_until_rental: true면 맥이 생길 때까지 대기. Idempotency-Key 지원","operationId":"postBuilds","x-scope":"build","x-mcp-tool":"build","x-cli":"xenoci build --script ./ci.sh","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"script":{"type":"string"},"upload_id":{"type":"string"},"repo_url":{"type":"string"},"repo":{"type":"string"},"ref":{"type":"string"},"xcode":{"type":"string"},"rental_id":{"type":"string"},"timeout_min":{"type":"integer","minimum":1,"maximum":360},"priority":{"type":"integer"},"clean_tree":{"type":"boolean"},"queue_until_rental":{"type":"boolean"},"pr":{"type":"integer","minimum":1,"example":42},"commit":{"type":"string","pattern":"^[a-fA-F0-9]{7,40}$","example":"abcdef0123456789abcdef0123456789abcdef01"}},"required":["script"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"get":{"x-scope":"read","parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"repo","in":"query","schema":{"type":"string"}},{"name":"pr","in":"query","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Account-scoped result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBuildList"},"example":{"builds":[{"id":"rb_example","status":"queued","state":"queued","repo":"example/app","ref":"main","pr":42,"commit":"abcdef0123456789abcdef0123456789abcdef01","commit_sha":"abcdef0123456789abcdef0123456789abcdef01","rental_public_id":null,"exit_code":null,"queue_position":1,"fifo_position":1,"estimated_wait_s":null,"estimated_start_at":null,"timings":{"created_at":"2026-10-08T00:00:00.000Z","started_at":null,"ended_at":null,"queue_s":0,"run_s":null},"failure":null}],"next_before":null}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/builds/{build_id}":{"get":{"summary":"빌드 상태·대기 순번(queue_position)·estimated_start_at·종료 코드·실패 요약(failure)","operationId":"getBuildsByBuildId","x-scope":"read","x-mcp-tool":"build_status","x-cli":"xenoci status rb_…","parameters":[{"name":"build_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Account-scoped result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBuild"},"example":{"id":"rb_example","status":"queued","state":"queued","repo":"example/app","ref":"main","pr":42,"commit":"abcdef0123456789abcdef0123456789abcdef01","commit_sha":"abcdef0123456789abcdef0123456789abcdef01","rental_public_id":null,"exit_code":null,"queue_position":1,"fifo_position":1,"estimated_wait_s":null,"estimated_start_at":null,"timings":{"created_at":"2026-10-08T00:00:00.000Z","started_at":null,"ended_at":null,"queue_s":0,"run_s":null},"failure":null}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/builds/{build_id}/wait":{"get":{"summary":"빌드가 끝날 때까지 최대 60초 롱폴","operationId":"getBuildsByBuildIdWait","x-scope":"read","x-mcp-tool":"wait_build","x-cli":"xenoci wait rb_…","parameters":[{"name":"build_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/builds/{build_id}/log":{"get":{"summary":"로그. offset=N이면 JSON 구간, format=text&wait=S면 텍스트 스트림","operationId":"getBuildsByBuildIdLog","x-scope":"read","x-mcp-tool":"build_log","x-cli":"xenoci logs rb_… [--failure | --tail N]","parameters":[{"name":"build_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"tail","in":"query","schema":{"type":"integer","minimum":0,"maximum":10000}}],"responses":{"200":{"description":"Text document","content":{"text/plain":{"schema":{"type":"string"},"example":"Sources/Main.swift:9: error: cannot find value missing in scope\n"}}},"4XX":{"$ref":"#/components/responses/Error"}}}},"/builds/{build_id}/cancel":{"post":{"summary":"빌드 취소","operationId":"postBuildsByBuildIdCancel","x-scope":"build","x-mcp-tool":"cancel_build","x-cli":"xenoci cancel rb_…","parameters":[{"name":"build_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/secrets":{"get":{"summary":"빌드 시크릿 이름 목록(값은 돌려주지 않음)","operationId":"getSecrets","x-scope":"read","x-mcp-tool":"secrets (list)","x-cli":"xenoci secrets","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/secrets/{name}":{"put":{"summary":"시크릿 저장. 빌드에 환경 변수로 들어가고 로그에서 가려짐","operationId":"putSecretsByName","x-scope":"manage","x-mcp-tool":"secrets (put)","x-cli":"xenoci secrets put NAME < 값","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"value":{"type":"string"}},"required":["value"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"시크릿 삭제","operationId":"deleteSecretsByName","x-scope":"manage","x-mcp-tool":"secrets (delete)","x-cli":"xenoci secrets delete NAME","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/errors":{"get":{"summary":"내 계정 최근 API 오류와 실패 빌드(?fault=&code=&kind=api|build&since=&key=self)","operationId":"getErrors","x-scope":"read","x-mcp-tool":"list_errors","x-cli":"xenoci errors","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}}},"/v1/status":{"get":{"x-scope":"read","parameters":[],"responses":{"200":{"description":"Account-scoped result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentStatus"},"example":{"account":{"id":1,"name":"Example","slug":"example","status":"active"},"plan":{"kind":"daily_rental","active_macs":1,"tiers":["standard"]},"macs":[{"rental_id":"rt_example","tier":"standard","xcode":"27.0","state":"ready","starts_at":"2026-10-07T23:00:00.000Z","ends_at":"2026-10-08T23:00:00.000Z","remaining_s":82800,"can_extend":true,"max_extend_days":29}],"advice":[{"kind":"extend_recommended","rental_id":"rt_example","remaining_s":82800,"reason":"less_than_24_hours","quote_hint":{"days":1,"amount_won":14900}}],"queue":{"running_count":0,"queued_count":1,"estimate_basis":"timeout_budget","running":[],"queued":[{"id":"rb_example","status":"queued","state":"queued","repo":"example/app","ref":"main","pr":42,"commit":"abcdef0123456789abcdef0123456789abcdef01","commit_sha":"abcdef0123456789abcdef0123456789abcdef01","rental_public_id":null,"exit_code":null,"queue_position":1,"fifo_position":1,"estimated_wait_s":null,"estimated_start_at":null,"timings":{"created_at":"2026-10-08T00:00:00.000Z","started_at":null,"ended_at":null,"queue_s":0,"run_s":null},"failure":null}]},"last_builds":[{"id":"rb_example","status":"queued","state":"queued","repo":"example/app","ref":"main","pr":42,"commit":"abcdef0123456789abcdef0123456789abcdef01","commit_sha":"abcdef0123456789abcdef0123456789abcdef01","rental_public_id":null,"exit_code":null,"queue_position":1,"fifo_position":1,"estimated_wait_s":null,"estimated_start_at":null,"timings":{"created_at":"2026-10-08T00:00:00.000Z","started_at":null,"ended_at":null,"queue_s":0,"run_s":null},"failure":null}]}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"servers":[{"url":"https://xenoci.com/api/ci"}]},"/v1/queue":{"get":{"x-scope":"read","parameters":[],"responses":{"200":{"description":"Account-scoped result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentQueue"},"example":{"running_count":0,"queued_count":1,"estimate_basis":"timeout_budget","running":[],"queued":[{"id":"rb_example","status":"queued","state":"queued","repo":"example/app","ref":"main","pr":42,"commit":"abcdef0123456789abcdef0123456789abcdef01","commit_sha":"abcdef0123456789abcdef0123456789abcdef01","rental_public_id":null,"exit_code":null,"queue_position":1,"fifo_position":1,"estimated_wait_s":null,"estimated_start_at":null,"timings":{"created_at":"2026-10-08T00:00:00.000Z","started_at":null,"ended_at":null,"queue_s":0,"run_s":null},"failure":null}]}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"servers":[{"url":"https://xenoci.com/api/ci"}]},"/v1/builds":{"get":{"x-scope":"read","parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"repo","in":"query","schema":{"type":"string"}},{"name":"pr","in":"query","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Account-scoped result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBuildList"},"example":{"builds":[{"id":"rb_example","status":"queued","state":"queued","repo":"example/app","ref":"main","pr":42,"commit":"abcdef0123456789abcdef0123456789abcdef01","commit_sha":"abcdef0123456789abcdef0123456789abcdef01","rental_public_id":null,"exit_code":null,"queue_position":1,"fifo_position":1,"estimated_wait_s":null,"estimated_start_at":null,"timings":{"created_at":"2026-10-08T00:00:00.000Z","started_at":null,"ended_at":null,"queue_s":0,"run_s":null},"failure":null}],"next_before":null}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"servers":[{"url":"https://xenoci.com/api/ci"}]},"/v1/builds/{id}":{"get":{"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Account-scoped result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentBuild"},"example":{"id":"rb_example","status":"queued","state":"queued","repo":"example/app","ref":"main","pr":42,"commit":"abcdef0123456789abcdef0123456789abcdef01","commit_sha":"abcdef0123456789abcdef0123456789abcdef01","rental_public_id":null,"exit_code":null,"queue_position":1,"fifo_position":1,"estimated_wait_s":null,"estimated_start_at":null,"timings":{"created_at":"2026-10-08T00:00:00.000Z","started_at":null,"ended_at":null,"queue_s":0,"run_s":null},"failure":null}}}},"4XX":{"$ref":"#/components/responses/Error"},"5XX":{"$ref":"#/components/responses/Error"}}},"servers":[{"url":"https://xenoci.com/api/ci"}]},"/v1/builds/{id}/log":{"servers":[{"url":"https://xenoci.com/api/ci"}],"get":{"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"tail","in":"query","schema":{"type":"integer","minimum":0,"maximum":10000}}],"responses":{"200":{"description":"Text document","content":{"text/plain":{"schema":{"type":"string"},"example":"Sources/Main.swift:9: error: cannot find value missing in scope\n"}}},"4XX":{"$ref":"#/components/responses/Error"}}}},"/v1/agent/start":{"servers":[{"url":"https://xenoci.com/api/ci"}],"get":{"x-scope":"read","parameters":[],"responses":{"200":{"description":"Text document","content":{"text/markdown":{"schema":{"type":"string"},"example":"# XenoCI agent start\n"}}},"4XX":{"$ref":"#/components/responses/Error"}}}},"/agent-start.md":{"servers":[{"url":"https://xenoci.com"}],"get":{"security":[],"parameters":[],"responses":{"200":{"description":"Text document","content":{"text/markdown":{"schema":{"type":"string"},"example":"# XenoCI agent start\n"}}},"4XX":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"xeno_ci_… key from https://xenoci.com/app/api-keys"}},"responses":{"Error":{"description":"Error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code"],"properties":{"code":{"type":"string","enum":["api_key_required","invalid_api_key","organization_suspended","ip_not_allowed","insufficient_scope","forbidden","api_key_read_only","api_key_write_only","organization_required","account_blocked","rate_limited","too_many_pending_orders","too_many_concurrent_builds","queue_full","no_capacity","sales_closed","available_now","waitlist_exists","order_not_found","order_expired","order_not_payable","payment_mismatch","consent_required","rental_not_found","rental_not_active","extension_deadline","extension_pending","extension_unavailable","rental_duration_limit","reservation_conflict","invalid_period","invalid_tier","no_active_rental","build_not_found","build_not_queued","invalid_script","upload_incomplete","upload_not_found","uploads_unavailable","gzip_required","manifest_too_large","upload_too_large","blob_not_in_manifest","invalid_offset","invalid_secret_name","secret_not_found","waitlist_not_found","waitlist_not_cancellable","invalid_waitlist","reset_limit","job_in_progress","job_not_found","invalid_setup","invalid_target","invalid_when","invalid_idempotency_key","idempotency_conflict","xcode_not_available","endpoint_removed","reset_failed","rental_busy","rental_only","internal_error"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"retry_after_s":{"type":["number","null"]},"fault":{"type":"string","enum":["client","platform","payment","capacity"]},"failure":{"$ref":"#/components/schemas/Failure"},"docs":{"type":"string"},"request_id":{"type":"string"},"next":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string"},"method":{"type":"string"},"path":{"type":"string"},"body":{"type":"object"}}}}}}}},"Failure":{"type":"object","description":"On a failed build (GET /builds/{id}): why it failed and where to look.","properties":{"fault":{"type":"string","enum":["customer","platform","unknown"]},"reason_code":{"type":"string"},"summary":{"type":"string"},"suggestion":{"type":"string"},"log_excerpt_lines":{"type":["array","null"],"items":{"type":"integer"},"description":"1-based inclusive line range in the full log"},"location":{"type":"object","properties":{"file":{"type":"string"},"line":{"type":"integer"},"message":{"type":"string"}}}}},"AgentFailure":{"type":"object","properties":{"category":{"type":"string","enum":["customer","platform","unknown"]},"fault":{"type":"string"},"step":{"type":"string"},"summary":{"type":"string","maxLength":600},"log_url":{"type":"string"},"reason_code":{"type":"string"},"suggestion":{"type":"string"}},"required":["category","step","summary","log_url"]},"AgentBuild":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","succeeded","failed","expired","cancelled"]},"state":{"type":"string"},"repo":{"type":["string","null"]},"repo_url":{"type":["string","null"]},"ref":{"type":["string","null"]},"pr":{"type":["integer","null"],"minimum":1},"commit":{"type":["string","null"]},"commit_sha":{"type":["string","null"]},"rental_public_id":{"type":["string","null"]},"exit_code":{"type":["integer","null"]},"queue_position":{"type":["integer","null"]},"fifo_position":{"type":"integer","minimum":0},"estimated_wait_s":{"type":["number","null"]},"estimated_start_at":{"type":["string","null"]},"timings":{"type":"object","properties":{"created_at":{"type":"string"},"started_at":{"type":["string","null"]},"ended_at":{"type":["string","null"]},"queue_s":{"type":"integer","minimum":0},"run_s":{"type":["number","null"]}}},"failure":{"anyOf":[{"$ref":"#/components/schemas/AgentFailure"},{"type":"null"}]}},"required":["id","status","pr","commit","timings","failure"]},"AgentBuildList":{"type":"object","properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/AgentBuild"}},"next_before":{"type":["string","null"]}}},"AgentQueue":{"type":"object","properties":{"running_count":{"type":"integer","minimum":0},"queued_count":{"type":"integer","minimum":0},"estimate_basis":{"const":"timeout_budget"},"running":{"type":"array","items":{"$ref":"#/components/schemas/AgentBuild"}},"queued":{"type":"array","items":{"$ref":"#/components/schemas/AgentBuild"}}},"description":"Account only. queue_position follows scheduler priority/requeue order; fifo_position uses creation order. Estimates use timeout budgets, account for pinned Mac/Xcode/expiry and are null when readiness is unknown."},"AgentMac":{"type":"object","properties":{"rental_id":{"type":"string"},"tier":{"type":"string"},"xcode":{"type":["string","null"]},"state":{"type":"string","enum":["reserved","preparing","ready","building","resetting"]},"starts_at":{"type":["string","null"]},"ends_at":{"type":["string","null"]},"remaining_s":{"type":"integer","minimum":0},"can_extend":{"type":"boolean"},"max_extend_days":{"type":"integer","minimum":0},"quote_hint":{"type":"object","properties":{"days":{"const":1},"amount_won":{"type":"integer","minimum":0}}}},"description":"Preparing rentals keep the purchased duration; their provisional end time does not consume remaining_s. Extension eligibility uses the live rental rules."},"AgentAdvice":{"type":"object","properties":{"kind":{"type":"string","enum":["extend_recommended","expiring_soon","queue_backlog","no_active_mac"]},"rental_id":{"type":"string"},"remaining_s":{"type":"integer","minimum":0},"reason":{"type":"string"},"quote_hint":{"type":"object","properties":{"days":{"const":1},"amount_won":{"type":"integer","minimum":0}}},"queued_count":{"type":"integer","minimum":0},"active_macs":{"type":"integer","minimum":0},"next":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string"},"method":{"type":"string"},"path":{"type":"string"}}}}}},"AgentStatus":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"integer","minimum":0},"name":{"type":["string","null"]},"slug":{"type":["string","null"]},"status":{"type":"string"}}},"plan":{"type":"object","properties":{"kind":{"const":"daily_rental"},"active_macs":{"type":"integer","minimum":0},"tiers":{"type":"array","items":{"type":"string"}}}},"macs":{"type":"array","items":{"$ref":"#/components/schemas/AgentMac"}},"advice":{"type":"array","items":{"$ref":"#/components/schemas/AgentAdvice"}},"queue":{"$ref":"#/components/schemas/AgentQueue"},"last_builds":{"type":"array","items":{"$ref":"#/components/schemas/AgentBuild"},"maxItems":10}}}}}}