본문으로 건너뛰기

API 레퍼런스 개요

XenoCI 러너 API의 엔드포인트, 인증, 클라이언트, 요청과 응답 형식, 페이지네이션, 속도 제한과 가용성

XenoCI 러너 API는 잡 단위 macOS CI 러너를 HTTP로 다루는 REST API입니다, xenocast CLI, MCP 서버, GitHub Action이 모두 이 API를 씁니다

사전 요구 사항

  • XenoCI 콘솔 계정(Google 로그인)
  • 콘솔에서 만든 API 키, 키는 사람이 자기 터미널 환경 변수 XENOCI_API_KEY나 xenocast login으로 넣습니다
  • 잡을 돌릴 크레딧, 충전과 결제는 콘솔에서 사람이 합니다

단계별 설정은 빠른 시작을 보세요

사용 가능한 API

기본 주소는 https://xenoci.com/api/runner이고 경로는 모두 /v1/…입니다, 예를 들어 GET /v1/me는 https://xenoci.com/api/runner/v1/me입니다

아래 목록은 계약 파일 docs/runner2/api-contract.openapi.json에서 그대로 만들어집니다, 계약에 연산이 추가되면 이 목록과 사이드바, 엔드포인트 페이지가 함께 늘어납니다

신원

메서드경로설명키
GET/v1/me호출자 확인read

잡

메서드경로설명키
POST/v1/uploads소스 업로드run
GET/v1/jobs잡 목록read
POST/v1/jobs잡 제출run
GET/v1/jobs/{job_id}잡 조회read
POST/v1/jobs/{job_id}/cancel잡 취소run
GET/v1/jobs/{job_id}/logs잡 로그read
GET/v1/jobs/{job_id}/artifacts결과물 목록read
GET/v1/jobs/{job_id}/artifacts/{artifact_id}결과물 내려받기read

러너

메서드경로설명키
GET/v1/runners러너 목록read

크레딧

메서드경로설명키
GET/v1/balance잔액 조회read
GET/v1/organizations/{org_id}/credit/lots충전 건 목록콘솔 전용
GET/v1/organizations/{org_id}/credit/ledger크레딧 원장콘솔 전용

사용량

메서드경로설명키
GET/v1/usage사용량 조회read
GET/v1/usage/export.csv사용량 CSVread

충전

메서드경로설명키
GET/v1/fx-rates/today오늘 환율콘솔 전용
GET/v1/organizations/{org_id}/topups충전 주문 목록콘솔 전용
POST/v1/organizations/{org_id}/topups충전 주문 생성콘솔 전용
GET/v1/organizations/{org_id}/topups/{order_id}충전 주문 조회콘솔 전용
POST/v1/organizations/{org_id}/topups/{order_id}/confirm충전 결제 확인콘솔 전용
POST/v1/organizations/{org_id}/topups/{order_id}/withdraw충전 청약철회콘솔 전용

조직

메서드경로설명키
GET/v1/organizations조직 목록콘솔 전용
POST/v1/organizations조직 만들기콘솔 전용
GET/v1/organizations/{org_id}조직 조회콘솔 전용
PATCH/v1/organizations/{org_id}조직 이름 바꾸기콘솔 전용
POST/v1/organizations/{org_id}/deletion조직 삭제 예약(owner, 콘솔에서 두 단계 확인)콘솔 전용
GET/v1/client-ip이 브라우저가 서버에 닿는 주소(IP 허용 목록 편집용)콘솔 전용

티어

메서드경로설명키
GET/v1/organizations/{org_id}/tier조직 티어 조회콘솔 전용
GET/v1/tiers티어 표read

멤버

메서드경로설명키
GET/v1/organizations/{org_id}/members멤버 목록콘솔 전용
PATCH/v1/organizations/{org_id}/members/{user_id}멤버 역할 바꾸기콘솔 전용
DELETE/v1/organizations/{org_id}/members/{user_id}멤버 내보내기콘솔 전용
GET/v1/organizations/{org_id}/invites초대 목록콘솔 전용
POST/v1/organizations/{org_id}/invites초대 보내기콘솔 전용
DELETE/v1/organizations/{org_id}/invites/{invite_id}초대 취소콘솔 전용
POST/v1/invites/accept초대 수락콘솔 전용

워크스페이스

메서드경로설명키
GET/v1/organizations/{org_id}/workspaces워크스페이스 목록콘솔 전용
POST/v1/organizations/{org_id}/workspaces워크스페이스 만들기콘솔 전용
GET/v1/organizations/{org_id}/workspaces/{workspace_id}워크스페이스 조회콘솔 전용
PATCH/v1/organizations/{org_id}/workspaces/{workspace_id}워크스페이스 수정콘솔 전용
POST/v1/organizations/{org_id}/workspaces/{workspace_id}/archive워크스페이스 보관콘솔 전용
GET/v1/organizations/{org_id}/workspaces/{workspace_id}/members워크스페이스 멤버 목록콘솔 전용
PUT/v1/organizations/{org_id}/workspaces/{workspace_id}/members/{user_id}워크스페이스 멤버 추가콘솔 전용
DELETE/v1/organizations/{org_id}/workspaces/{workspace_id}/members/{user_id}워크스페이스 멤버 빼기콘솔 전용

API 키

메서드경로설명키
POST/v1/organizations/{org_id}/workspaces/{workspace_id}/api-keysAPI 키 발급콘솔 전용
GET/v1/organizations/{org_id}/api-keysAPI 키 목록콘솔 전용
PATCH/v1/organizations/{org_id}/api-keys/{key_id}API 키 이름 바꾸기콘솔 전용
POST/v1/organizations/{org_id}/api-keys/{key_id}/revokeAPI 키 폐기콘솔 전용
POST/v1/organizations/{org_id}/api-keys/{key_id}/disable키 끄기(다시 켤 수 있음), 꺼진 키로 보낸 요청은 401 invalid_api_key콘솔 전용
POST/v1/organizations/{org_id}/api-keys/{key_id}/enable꺼진 키 다시 켜기, 폐기된 키는 409 conflict콘솔 전용

분석

메서드경로설명키
GET/v1/cost비용 조회read
GET/v1/cost/export.csv비용 CSVread
GET/v1/logs로그 목록read
GET/v1/usage/prepare준비 시간read
GET/v1/limits한도 조회read

대시보드

메서드경로설명키
GET/v1/dashboard대시보드read

배치

메서드경로설명키
GET/v1/batches배치 목록read
POST/v1/batches배치 제출run
GET/v1/batches/{batch_id}배치 조회read
POST/v1/batches/{batch_id}/cancel배치 취소run

레시피

메서드경로설명키
GET/v1/recipes레시피 목록read
POST/v1/recipes레시피 만들기run
GET/v1/recipes/{recipe_id}레시피 조회read
PATCH/v1/recipes/{recipe_id}레시피 수정run
DELETE/v1/recipes/{recipe_id}레시피 삭제run

환경

메서드경로설명키
GET/v1/environments환경 목록read
PUT/v1/organizations/{org_id}/workspaces/{workspace_id}/environment워크스페이스 기본 환경콘솔 전용

파일

메서드경로설명키
GET/v1/files파일 목록read
DELETE/v1/files/{file_id}파일 삭제run

플레이그라운드

메서드경로설명키
POST/v1/organizations/{org_id}/workspaces/{workspace_id}/playground/runs플레이그라운드 실행콘솔 전용

알림

메서드경로설명키
GET/v1/organizations/{org_id}/notifications알림 목록콘솔 전용
GET/v1/organizations/{org_id}/notification-settings알림 설정 조회콘솔 전용
PUT/v1/organizations/{org_id}/notification-settings알림 설정 변경콘솔 전용

인증

방식헤더누가 쓰는가할 수 있는 일
API 키Authorization: Bearer xci_live_…CLI, MCP, GitHub Action, 직접 호출키 권한이 run이면 잡 제출과 취소, 조회, read면 조회만, 워크스페이스 하나에 묶입니다
콘솔 세션쿠키 xci_console웹 콘솔(Google 로그인)조직 역할(owner, admin, developer)에 따라 결제, 멤버, 워크스페이스, 키 관리까지
  • API 키는 어떤 권한이든 결제, 충전, 키 발급, 멤버와 워크스페이스 관리를 할 수 없습니다, 그런 엔드포인트를 키로 부르면 403 console_only입니다
  • 키 형식은 xci_live_ + 43자 + _ + 6자(CRC32 체크섬)입니다, 옛 xeno_ 접두사 키는 401 invalid_api_key입니다
  • 콘솔 세션으로 상태를 바꾸는 요청(POST, PUT, PATCH, DELETE)은 같은 출처의 Origin 헤더가 있어야 합니다
  • 각 엔드포인트 페이지 맨 위에 필요한 키 권한과 허용 역할이 있습니다

클라이언트

직접 HTTP를 부르지 않아도 됩니다, 세 클라이언트가 모두 이 API를 씁니다

클라이언트쓰는 곳문서
xenocast CLI터미널, 스크립트CLI
xenocast MCP 서버Claude Code, Codex 같은 AI 에이전트MCP
GitHub Action Xeno-CI/buildGitHub Actions 워크플로GitHub Actions

엔드포인트 페이지의 오른쪽 예시에서 cURL, CLI, MCP를 골라 같은 요청을 볼 수 있습니다

요청과 응답 형식

요청과 응답 본문은 JSON(Content-Type: application/json)입니다, 소스 업로드만 압축 파일 원문(application/octet-stream)을 받고 로그는 텍스트, 사용량과 비용 내보내기는 CSV입니다

요청 크기 제한

요청최대 크기
JSON 본문(잡 제출, 배치, 레시피 등)64 KB
잡 script 필드65,536자
소스 업로드(POST /v1/uploads)2 GB, 넘으면 413
결과물잡당 20개, 합계 2 GB
잡 로그5 MB, 넘는 부분은 잘리고 끝에 표시가 붙습니다

큰 저장소는 JSON에 넣지 말고 업로드하거나 공개 git 주소(source.git_url)로 넘기세요

응답 헤더

헤더뜻
X-Request-Id요청마다 붙는 req_… ID, 요청에 X-Request-Id: req_…를 넣으면 그 값을 그대로 씁니다, 문의할 때 알려 주세요
Cache-Control항상 private, no-store
Retry-After429와 일부 503에서 다시 시도할 때까지의 초
X-Log-Next-Offset, X-Log-Complete잡 로그 조회에서 다음 offset과 로그가 끝났는지

금액 필드

같은 금액을 두 필드로 항상 함께 줍니다

필드뜻예
<이름>_micro_usd정수 µUSD, 1 USD = 1,000,000, 계산과 비교는 이 값으로80000
<이름>_usd같은 값의 USD 문자열, 센트 단위 소수 2자리(분당 요율만 4자리)"0.08"
<이름>_krw원화 정수(원), 충전 주문에만28775
*_krw_per_usd환율 문자열, 소수 2자리"1438.71"
  • 잡 요금은 초 단위로 계산하고 최소 1분이며 센트 단위로 반올림합니다, 그래서 금액은 항상 센트로 떨어집니다(US$0.08 = 80000)
  • 입력은 USD 정수(usd, monthly_limit_usd)만 받습니다, 소수나 문자열이나 지수 표기는 400 invalid_amount 또는 invalid_request입니다
  • 분당 요율은 부가세 포함입니다, 런칭가 US$0.0396, 정가 US$0.078
  • 오류 message는 한국어입니다, 프로그램은 code로 분기하세요
  • 시각은 RFC 3339 UTC(2026-10-12T03:11:05Z)이고 일별 집계와 월 한도는 UTC 기준입니다, 환율 day만 KST 영업일입니다

ID 접두사

접두사자원
org_조직
wrk_워크스페이스
usr_사용자
key_API 키
job_잡
lot_크레딧 로트
inv_초대
upl_업로드
art_결과물
bat_배치
rcp_레시피
ntf_알림
req_API 요청 로그

충전 주문 order_id는 [A-Za-z0-9_-]{6,64}이고 PortOne paymentId로 그대로 쓰입니다

멱등

쓰기 연산은 Idempotency-Key 헤더(1~255자)를 받습니다, 24시간 안에 같은 키로 다시 보내면 처음 응답을 그대로 돌려주고, 같은 키에 다른 본문이면 409 idempotency_conflict입니다, 네트워크가 끊겨 잡 제출 결과를 못 받았을 때 같은 키로 다시 보내면 잡이 두 번 만들어지지 않습니다

오류 봉투

모든 오류는 같은 모양의 JSON을 돌려줍니다

{
  "error": {
    "code": "insufficient_credit",
    "message": "사용 가능 잔액이 1분 요금보다 적습니다",
    "retryable": false,
    "retry_after_s": null,
    "fault": "payment",
    "request_id": "req_7Hq3Zk9Lm2",
    "docs_url": "https://xenoci.com/docs/errors#insufficient_credit",
    "details": {
      "balance_micro_usd": 10000,
      "balance_usd": "0.01",
      "required_micro_usd": 40000,
      "required_usd": "0.04",
      "topup_url": "https://xenoci.com/console/topup?org=org_7Kq2m9ZtP3"
    }
  }
}

fault는 client(요청 쪽), payment(잔액이나 한도), platform(XenoCI 쪽) 중 하나입니다, 전체 코드 표는 오류 코드에 있습니다

페이지네이션

목록 응답은 data 배열과 next_cursor를 돌려줍니다, limit(기본 20, 최대 100)으로 크기를 정하고 next_cursor가 null이 아니면 그 값을 cursor에 넣어 다음 페이지를 받습니다, 목록은 최신순입니다

속도 제한과 가용성

속도 제한

  • 동시에 실행되는 잡 수는 조직 티어의 동시 실행 한도를 따릅니다, 넘는 잡은 거절하지 않고 대기열에 넣고(queued_reason=tier_concurrency_limit) 대기열까지 차면 429 tier_concurrency_limit입니다, 자세한 수치는 속도 제한과 티어에 있습니다
  • API 키 요청 수는 아직 막지 않습니다, 한 키가 10분에 1,000건을 넘으면 소유자와 관리자에게 급증 메일이 갑니다
  • 로그인 요청은 이메일당 15분에 5번, IP당 20번까지이고 넘으면 429 rate_limited와 Retry-After입니다
  • 월 지출 한도와 티어 월 한도에 닿으면 새 잡은 402로 거절되고 실행 중인 잡은 주기 검사에서 멈춥니다, 검사 주기 때문에 한도를 조금 넘을 수 있습니다

가용성

  • 잡은 새 macOS VM에서 돌고 끝나면 VM을 지웁니다, 빈 VM이 없으면 잡은 대기열에서 기다립니다(queued_reason=capacity)
  • 판매 용량이 하나도 없으면 503 capacity_unavailable로 잡을 받지 않습니다, 요금이 나가지 않습니다
  • 서비스 상태는 상태 페이지에서 봅니다
  • 내부 경로 /api/runner/downloads/{token}(결과물 바이트), /api/runner/agent/*(맥 호스트 전용, 잡별 1회용 토큰)는 고객이 직접 부르지 않습니다

다음 단계