> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryvox.co/llms.txt
> Use this file to discover all available pages before exploring further.

# 유닛 테스트 실행

> 실행 계획의 모든 실행을 한 번에 접수하고 바로 돌려줍니다. 한 요청의 실행 수 합계는 100건까지이며 넘으면 전체를 거절합니다. 같은 요청을 안전하게 다시 보내려면 처음부터 `Idempotency-Key`를 붙여야 합니다. 같은 키와 본문은 24시간 동안 처음 접수 결과를 돌려주고 다시 실행하지 않습니다. `EVAL_SUBMIT_FAILED`는 실행이 시작 단계로 전달되지 않았다는 뜻이라 새 `Idempotency-Key`를 붙여 새 요청으로 다시 접수해도 안전합니다. `EVAL_SUBMIT_UNCONFIRMED`는 실행이 시작됐는지 알 수 없다는 뜻이니 `details.batch_id`로 배치를 조회해 확인한 뒤 다시 접수해야 합니다.



## OpenAPI

````yaml /api-reference/v3/openapi.json post /evals/unit/batches
openapi: 3.1.0
info:
  title: vox.ai API
  description: >
    vox.ai API v3


    ### v3 공개 계약 규칙


    - 인증은 `Authorization: Bearer <token>` 헤더를 사용합니다. 워크스페이스 API 키를 Bearer 토큰으로
    전달합니다.

    - 요청과 응답 필드는 기본적으로 `snake_case`를 사용합니다.

    - `agent.data`는 에이전트 레지스트리와 호환되어야 하므로 `callSettings`, `toolIds`,
    `builtInTools`, `presetDynamicVariables` 같은 camelCase 필드를 유지합니다.

    - `_at`으로 끝나는 타임스탬프는 unix milliseconds입니다. 일부 입력값은 호환성을 위해 10~11자리 unix
    seconds도 허용하고 milliseconds로 정규화합니다.

    - 대량 발신 통화 가능 시간은 분 단위 정수(`start_min` / `end_min`)를 사용합니다. 알림 스케줄은 `HH:MM`
    문자열(`start_time` / `end_time`)을 사용합니다.

    - 응답 객체 자신의 식별자는 `id`입니다. 다른 리소스를 참조하는 필드와 path parameter는 `agent_id`,
    `call_id`, `telephone_line_id`처럼 명시적인 이름을 사용합니다.

    - 실패 응답은 `{ "error": { "code", "message", "details" } }` 형태입니다. 가능한 경우
    `details.field`, `details.reason`, `details.allowed_values`를 함께 제공합니다.
  version: 3.0.0
servers:
  - url: https://client-api.tryvox.co/v3
    description: 운영
security: []
paths:
  /evals/unit/batches:
    post:
      tags:
        - Evals
      summary: 유닛 테스트 실행
      description: >-
        실행 계획의 모든 실행을 한 번에 접수하고 바로 돌려줍니다. 한 요청의 실행 수 합계는 100건까지이며 넘으면 전체를 거절합니다.
        같은 요청을 안전하게 다시 보내려면 처음부터 `Idempotency-Key`를 붙여야 합니다. 같은 키와 본문은 24시간 동안
        처음 접수 결과를 돌려주고 다시 실행하지 않습니다. `EVAL_SUBMIT_FAILED`는 실행이 시작 단계로 전달되지 않았다는
        뜻이라 새 `Idempotency-Key`를 붙여 새 요청으로 다시 접수해도 안전합니다.
        `EVAL_SUBMIT_UNCONFIRMED`는 실행이 시작됐는지 알 수 없다는 뜻이니 `details.batch_id`로 배치를
        조회해 확인한 뒤 다시 접수해야 합니다.
      operationId: createUnitTestBatch
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            description: >-
              같은 POST 요청을 24시간 동안 안전하게 재시도하기 위한 선택적 멱등성 키입니다. 지정할 경우 비어 있으면 안 되며
              최대 255자까지 허용합니다.
            title: Idempotency-Key
          description: >-
            같은 POST 요청을 24시간 동안 안전하게 재시도하기 위한 선택적 멱등성 키입니다. 지정할 경우 비어 있으면 안 되며
            최대 255자까지 허용합니다.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUnitTestBatchRequest'
        description: 이 엔드포인트의 요청 데이터입니다.
      responses:
        '201':
          description: 성공 응답
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EvalBatchReceipt'
              example:
                id: 3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f
                status: queued
                runs:
                  - id: 6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d
                    test_id: 0f9c2b1e-3d4a-4b5c-8d6e-7f8091a2b3c4
                    status: queued
        '400':
          description: 요청 검증 오류
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                validationError:
                  summary: 요청 검증 오류
                  value:
                    error:
                      code: VALIDATION_ERROR
                      message: Request validation failed.
                      details:
                        field: name
                        reason: must not be blank
        '401':
          description: 인증이 필요합니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                unauthorized:
                  summary: Bearer 토큰 누락 또는 오류
                  value:
                    error:
                      code: UNAUTHORIZED
                      message: Authentication is required.
                      details: {}
        '403':
          description: 권한이 없습니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                forbidden:
                  summary: 권한이 없습니다.
                  value:
                    error:
                      code: FORBIDDEN
                      message: Permission denied.
                      details: {}
        '404':
          description: 리소스를 찾을 수 없습니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                notFound:
                  summary: 리소스를 찾을 수 없습니다.
                  value:
                    error:
                      code: RESOURCE_NOT_FOUND
                      message: Resource not found.
                      details:
                        resource: agent
        '409':
          description: 충돌이 발생했습니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                conflict:
                  summary: 상태 충돌이 발생했습니다.
                  value:
                    error:
                      code: CONFLICT
                      message: The requested operation conflicts with current state.
                      details:
                        current_status: draft
        '429':
          description: >-
            요청 한도를 초과했습니다. API 키 트래픽은 기본값으로 워크스페이스당 초당 5회·분당 120회, Supabase JWT
            트래픽은 기본값으로 사용자당 초당 10회·분당 240회로 제한되며, 워크스페이스 대시보드에는 기본 분당 2,400회의
            백스톱 한도가 적용됩니다. 한도는 운영자가 조정할 수 있고, 초과한 버킷의 실제 한도와 윈도우는 429 응답의
            X-RateLimit-Limit·X-RateLimit-Window 헤더로 알려 줍니다. 개별 경로 자체 리미터가 만든
            429 응답에는 이 헤더가 없을 수 있습니다.
          headers:
            Retry-After:
              description: >-
                초과한 공용 v3 인증 주체(auth-principal) 리미터 윈도우가 초기화될 때까지 남은 시간입니다. 단위는
                초입니다. 개별 경로 자체 리미터가 만든 429 응답에는 이 헤더가 없을 수 있습니다.
              schema:
                type: integer
                minimum: 1
            X-RateLimit-Limit:
              description: >-
                초과한 공용 v3 인증 주체(auth-principal) 리미터 윈도우의 최대 요청 수입니다. 개별 경로 자체
                리미터가 만든 429 응답에는 이 헤더가 없을 수 있습니다.
              schema:
                type: integer
                minimum: 1
            X-RateLimit-Window:
              description: >-
                초과한 공용 v3 인증 주체(auth-principal) 리미터 윈도우의 길이입니다. 단위는 초입니다. 개별 경로
                자체 리미터가 만든 429 응답에는 이 헤더가 없을 수 있습니다.
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                rateLimited:
                  summary: 요청 한도를 초과했습니다.
                  value:
                    error:
                      code: RATE_LIMIT_EXCEEDED
                      message: Too many requests.
                      details:
                        limit: 10
                        window_seconds: 1
                        scope: user
        '500':
          description: 서버 내부 오류가 발생했습니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                internalError:
                  summary: 서버 내부 오류가 발생했습니다.
                  value:
                    error:
                      code: INTERNAL_ERROR
                      message: Internal server error.
                      details: {}
        '503':
          description: 서비스를 일시적으로 사용할 수 없습니다.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                serviceUnavailable:
                  summary: 서비스를 일시적으로 사용할 수 없습니다.
                  value:
                    error:
                      code: SERVICE_UNAVAILABLE
                      message: Service temporarily unavailable.
                      details: {}
      security:
        - BearerAuth: []
components:
  schemas:
    CreateUnitTestBatchRequest:
      properties:
        runs:
          items:
            $ref: '#/components/schemas/UnitTestRunPlan'
          type: array
          minItems: 1
          title: Runs
          description: >-
            실행 계획 목록입니다. 한 건만 실행해도 배열로 보냅니다. 한 요청의 실행 수 합계(각 `count`의 합)는
            100건까지입니다.
      type: object
      required:
        - runs
      title: CreateUnitTestBatchRequest
    EvalBatchReceipt:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: 배치 id입니다.
        status:
          type: string
          const: queued
          title: Status
          description: 접수 직후 상태입니다. 현재 상태는 배치 조회로 확인합니다.
          default: queued
        runs:
          items:
            $ref: '#/components/schemas/EvalRunReceipt'
          type: array
          title: Runs
          description: 이 요청으로 접수한 실행 목록입니다.
      type: object
      required:
        - id
        - runs
      title: EvalBatchReceipt
      examples:
        - id: 3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f
          runs:
            - id: 6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d
              status: queued
              test_id: 0f9c2b1e-3d4a-4b5c-8d6e-7f8091a2b3c4
          status: queued
    ErrorResponse:
      type: object
      required:
        - error
      title: ErrorResponse
      description: 모든 실패 응답에서 사용하는 v3 error envelope입니다.
      examples:
        - error:
            code: VALIDATION_ERROR
            message: Request validation failed.
            details:
              field: name
              reason: must not be blank
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
          description: 오류 payload입니다.
    UnitTestRunPlan:
      properties:
        test_id:
          type: string
          format: uuid
          title: Test Id
          description: 실행할 유닛 테스트 id입니다. GET /v3/evals/unit 응답의 id를 사용합니다.
        agent:
          $ref: '#/components/schemas/AgentMapping'
          description: 실행할 에이전트와 버전입니다. `agent_version`을 생략하면 편집 중인 현재 설정으로 실행합니다.
        count:
          type: integer
          maximum: 10
          minimum: 1
          title: Count
          description: 같은 유닛 테스트를 반복 실행할 횟수입니다. 1~10의 정수입니다.
          default: 1
        metadata:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Metadata
          description: 이 실행 계획으로 만든 실행마다 붙여 두는 사용자 정의 정보입니다.
      type: object
      required:
        - test_id
        - agent
      title: UnitTestRunPlan
    EvalRunReceipt:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: 실행 id입니다.
        test_id:
          type: string
          format: uuid
          title: Test Id
          description: 실행한 테스트 id입니다.
        status:
          type: string
          const: queued
          title: Status
          description: 접수 직후 상태입니다. 현재 상태는 실행 조회로 확인합니다.
          default: queued
      type: object
      required:
        - id
        - test_id
      title: EvalRunReceipt
      examples:
        - id: 6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d
          status: queued
          test_id: 0f9c2b1e-3d4a-4b5c-8d6e-7f8091a2b3c4
    ErrorDetail:
      type: object
      required:
        - code
        - message
        - details
      title: ErrorDetail
      description: 기계가 읽을 수 있는 v3 오류 상세 정보입니다.
      examples:
        - code: VALIDATION_ERROR
          message: Request validation failed.
          details:
            field: name
            reason: must not be blank
      properties:
        code:
          type: string
          title: Code
          description: 기계가 읽을 수 있는 오류 code입니다. message parsing 대신 이 값을 사용합니다.
          examples:
            - VALIDATION_ERROR
        message:
          type: string
          title: Message
          description: 사용자에게 표시할 수 있는 오류 메시지입니다. 프로그램 처리는 `code`를 사용합니다.
          examples:
            - Request validation failed.
        details:
          type: object
          title: Details
          additionalProperties: true
          description: 구조화된 context입니다. 주로 `field`, `reason`, `allowed_values`를 포함합니다.
    AgentMapping:
      additionalProperties: false
      description: >-
        `agent_id`와 `agent_version` 매핑입니다.


        요청·응답 모두에서 에이전트 매핑이 필요한 경우 이 타입을 사용합니다. version 지정이 필요 없는 엔드포인트는 flat
        `agent_id: UUID`를 직접 받고 `AgentMapping`을 사용하지 않습니다.
      properties:
        agent_id:
          description: 에이전트 UUID입니다.
          format: uuid
          title: Agent Id
          type: string
          x-vox-effect: wiring
        agent_version:
          default: current
          description: >-
            에이전트 버전입니다. 허용값은 "current", "production", "v{n}"(n≥1)입니다. 보내지 않으면
            "current"로 처리합니다. null 전송은 거부합니다.
          title: Agent Version
          type: string
          x-vox-effect: wiring
          pattern: ^(current|production|v[1-9][0-9]*)$
          examples:
            - current
            - production
            - v1
      required:
        - agent_id
      title: AgentMapping
      type: object
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Organization API key
      description: '워크스페이스 API 키를 `Authorization: Bearer <token>` 형식으로 보냅니다.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.