> ## 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.

# 대량 문자 발신 생성

> 발신번호 하나로 여러 수신번호에 문자를 보내는 대량 문자 발신(`sms_batch`)을 생성합니다. 진행 상황은 `GET /v3/sms-batches/{batch_id}`, 문자별 결과는 `GET /v3/sms?batch_id=`로 확인합니다.



## OpenAPI

````yaml /api-reference/v3/openapi.json post /sms-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:
  /sms-batches:
    post:
      tags:
        - SMS
      summary: 대량 문자 발신 생성
      description: >-
        발신번호 하나로 여러 수신번호에 문자를 보내는 대량 문자 발신(`sms_batch`)을 생성합니다. 진행 상황은 `GET
        /v3/sms-batches/{batch_id}`, 문자별 결과는 `GET /v3/sms?batch_id=`로 확인합니다.
      operationId: createSmsBatch
      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/SmsBatchCreateRequest'
            examples:
              minimal:
                summary: 즉시 발신
                value:
                  name: 5월 공지 발신
                  from_number: '07011112222'
                  items:
                    - to_number: '01012345678'
                      message: 예약 확인 안내드립니다.
              scheduled_with_window:
                summary: 예약 발신 + 발신 허용 시간대 + 항목 메타데이터
                value:
                  name: 재방문 안내
                  from_number: '07011112222'
                  scheduled_at: 1776470400000
                  send_time_window:
                    windows:
                      - start_min: 540
                        end_min: 1080
                        days:
                          - Monday
                          - Tuesday
                          - Wednesday
                          - Thursday
                          - Friday
                    timezone: Asia/Seoul
                    auto_resume: true
                  items:
                    - to_number: '01012345678'
                      title: 재방문 안내
                      message: 다음 방문 일정을 확인해 주세요.
                      metadata:
                        row_id: r1
        description: >-
          대량 문자 발신 생성 요청 본문입니다. `items`에는 수신자가 들어가며, `scheduled_at`과
          `send_time_window`를 모두 만족해야 메시지를 발신합니다.
      responses:
        '201':
          description: 성공 응답
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SmsBatchResponse'
              example:
                id: 7c9e6679-7425-40de-944b-e07fc1f90ae7
                name: 5월 공지 발신
                status: pending
                from_number: '07011112222'
                total_count: 3
                success_count: 0
                failure_count: 0
                pending_count: 3
                blocked_count: 0
                canceled_count: 0
                created_at: 1793051400000
        '400':
          description: >-
            요청이 올바르지 않습니다. 최종 본문이나 제목에 EUC-KR로 바꿀 수 없는 글자가 있으면 항목을 하나도 등록하지 않고
            요청 전체를 `SMS_UNSUPPORTED_CHARSET`으로 거부하며, `details.index`에 0부터 센 항목
            위치를 담습니다.
          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:
                idempotencyKeyConflict:
                  summary: 다른 요청에 다시 쓴 Idempotency-Key
                  value:
                    error:
                      code: IDEMPOTENCY_KEY_CONFLICT
                      message: 동일한 Idempotency-Key가 다른 요청 또는 실행 주체에 사용되었습니다.
                      details:
                        idempotency_key: sms-20260526-001
                idempotencyKeyInProgress:
                  summary: 같은 Idempotency-Key의 요청을 처리하는 중
                  value:
                    error:
                      code: IDEMPOTENCY_KEY_IN_PROGRESS
                      message: 이 Idempotency-Key는 현재 처리 중입니다. 잠시 후 다시 시도해 주세요.
                      details:
                        idempotency_key: sms-20260526-001
        '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:
    SmsBatchCreateRequest:
      properties:
        name:
          type: string
          maxLength: 255
          minLength: 1
          title: Name
          description: 대량 문자 발신 이름입니다. 앞뒤 공백을 지운 뒤 1~255자여야 하며 공백만으로는 만들 수 없습니다.
          examples:
            - 5월 공지 발신
        from_number:
          type: string
          title: From Number
          description: 대량 문자 발신 전체가 공유하는 발신번호입니다. 인증된 워크스페이스가 소유하고 문자 발신이 켜진 번호여야 합니다.
          examples:
            - '07011112222'
        items:
          items:
            $ref: '#/components/schemas/SMSBatchItem'
          type: array
          maxItems: 3000
          minItems: 1
          title: Items
          description: >-
            문자를 받을 수신 항목 목록입니다(1건 이상). 요청당 최대 3000건까지 담을 수 있고, 워크스페이스당 분당 최대
            6000건까지 등록할 수 있습니다. 한도를 넘으면 RATE_LIMIT_EXCEEDED(429)로 거절됩니다.
        scheduled_at:
          anyOf:
            - type: integer
            - type: 'null'
          title: Scheduled At
          description: 예약 실행 시각입니다. unix milliseconds 형식입니다.
        send_time_window:
          anyOf:
            - $ref: '#/components/schemas/SMSBatchSendTimeWindow'
            - type: 'null'
          description: >-
            발신 허용 시간대입니다. 생략하면 24시간 매일 발신할 수 있습니다. 허용 시간대 밖이면 발신을 멈추고,
            auto_resume이 true이면 다음 허용 시간대에 이어서 발신합니다.
        reseller_code:
          anyOf:
            - type: string
              pattern: ^\d{9}$
            - type: 'null'
          title: Reseller Code
          description: >-
            특수유형 부가통신사업자 식별코드입니다(숫자 9자리). 문자중계·재판매사업자가 아니면 생략합니다. 허용된 워크스페이스에서만
            전송됩니다.
      additionalProperties: false
      type: object
      required:
        - name
        - from_number
        - items
      title: SmsBatchCreateRequest
      description: '`POST /v3/sms-batches` 요청 본문입니다.'
    SmsBatchResponse:
      properties:
        id:
          type: string
          title: Id
          description: 대량 문자 발신의 고유 식별자입니다(UUID).
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
          description: 대량 문자 발신 이름입니다. 이름 없이 만든 이전 대량 문자 발신은 null입니다.
        status:
          type: string
          enum:
            - draft
            - pending
            - ongoing
            - paused
            - success
            - fail
            - canceled
          title: Status
          description: >-
            대량 문자 발신 상태입니다. canceled는 취소됨, paused는 일시정지 중, draft는 예약 시각 전의 대기
            상태입니다. 그 외에는 pending(발신 전), ongoing(발신 중이거나 발신이 끝난 뒤 통신사 결과를 기다리는
            중), success(모든 결과가 정해졌거나 마지막 발신 후 10분이 지나 끝남, 실패·차단 항목이 있을 수 있음),
            fail(접수된 항목 없이 끝남)입니다.
        from_number:
          type: string
          title: From Number
          description: 대량 문자 발신 전체가 공유하는 발신번호입니다.
        total_count:
          type: integer
          minimum: 0
          title: Total Count
          description: 이 대량 문자 발신에 담은 전체 문자 수입니다.
        success_count:
          type: integer
          minimum: 0
          title: Success Count
          description: 요금이 부과되는 성공(sent) 항목 수입니다.
        failure_count:
          type: integer
          minimum: 0
          title: Failure Count
          description: 발신에 실패한(failed) 항목 수입니다.
        pending_count:
          type: integer
          minimum: 0
          title: Pending Count
          description: >-
            아직 결과가 정해지지 않은 문자 수입니다. 발신하지 않은 pending 문자와 통신사의 최종 결과를 기다리는 queued
            문자를 합한 값이며, success_count + failure_count + pending_count +
            blocked_count + canceled_count가 total_count와 같습니다. 문자별 결과는 GET
            /v3/sms?batch_id= 로 조회합니다.
        blocked_count:
          type: integer
          minimum: 0
          title: Blocked Count
          description: 제한된 내용이 포함되어 발신하지 않은(blocked) 항목 수입니다.
        canceled_count:
          type: integer
          minimum: 0
          title: Canceled Count
          description: 대량 문자 발신 취소로 발신하지 않은(canceled) 항목 수입니다.
        send_time_window:
          anyOf:
            - $ref: '#/components/schemas/SMSBatchSendTimeWindow'
            - type: 'null'
          description: 발신 허용 시간대입니다. 시간대를 정하지 않고 만든 이전 대량 문자 발신은 null입니다.
        scheduled_at:
          anyOf:
            - type: integer
            - type: 'null'
          title: Scheduled At
          description: 예약 실행 시각입니다. unix milliseconds 형식입니다.
        paused_at:
          anyOf:
            - type: integer
            - type: 'null'
          title: Paused At
          description: 일시정지한 시각입니다(unix ms). 일시정지 중이 아니면 null입니다.
        canceled_at:
          anyOf:
            - type: integer
            - type: 'null'
          title: Canceled At
          description: 취소한 시각입니다(unix ms). 취소하지 않았으면 null입니다.
        created_at:
          type: integer
          title: Created At
          description: 리소스 생성 시각입니다. unix milliseconds 형식입니다.
        finished_at:
          anyOf:
            - type: integer
            - type: 'null'
          title: Finished At
          description: 대량 문자 발신이 끝난 시각입니다(unix ms). 끝나지 않았으면 null입니다.
        sheet_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Sheet Id
          description: 대량 문자 발신 생성에 사용한 시트 식별자입니다. 시트를 거치지 않았으면 null입니다.
      type: object
      required:
        - id
        - name
        - status
        - from_number
        - total_count
        - success_count
        - failure_count
        - pending_count
        - blocked_count
        - canceled_count
        - send_time_window
        - scheduled_at
        - paused_at
        - canceled_at
        - created_at
        - finished_at
        - sheet_id
      title: SmsBatchResponse
      description: 대량 문자 발신 한 건입니다. 문자별 결과는 GET /v3/sms?batch_id= 로 조회합니다.
    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입니다.
    SMSBatchItem:
      properties:
        to_number:
          type: string
          title: To Number
          description: '수신번호입니다. 하이픈 없는 국내 번호입니다(예: ''01012345678'').'
          examples:
            - '01012345678'
        message:
          type: string
          title: Message
          description: >-
            문자 본문입니다. EUC-KR 기준 90바이트 이하이고 제목과 이미지가 없으면 SMS, 90바이트를 넘기거나 제목이 있으면
            LMS, 이미지를 첨부하면 MMS로 발신됩니다. 본문과 제목에 EUC-KR로 표현할 수 없는 문자(예: 이모지)가 있으면
            SMS_UNSUPPORTED_CHARSET(400)으로 거절됩니다.
          examples:
            - 예약 확인 안내드립니다.
        title:
          anyOf:
            - type: string
            - type: 'null'
          title: Title
          description: 선택 제목입니다. 지정하면 LMS 또는 MMS로 발신됩니다.
          examples:
            - 예약 안내
        image_file_keys:
          anyOf:
            - items:
                type: string
              type: array
              maxItems: 3
            - type: 'null'
          title: Image File Keys
          description: >-
            이미지 첨부 파일 키입니다. 파일 업로드 API에 purpose=sms_attachment로 올린 파일의
            file_key이며 최대 3개까지 지정할 수 있습니다. 업로드 규격은 JPEG·PNG·WebP는 원본 2MB
            이하(JPEG로 변환한 결과 1MB 이하), GIF는 2MB 이하입니다. 텍스트만 보내면 생략하거나 null 또는 빈
            배열을 전달합니다.
          examples:
            - - file_abc123
        metadata:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Metadata
          description: '항목과 대응시키기 위한 선택 메타데이터입니다(예: 시트 행 식별용 row_id). 조회 응답에 그대로 포함됩니다.'
          examples:
            - row_id: r1
      additionalProperties: false
      type: object
      required:
        - to_number
        - message
      title: SMSBatchItem
      description: 대량 문자 발신에 담는 수신 항목 한 건입니다. 발신번호는 대량 문자 발신 전체가 공유합니다.
    SMSBatchSendTimeWindow:
      properties:
        windows:
          items:
            $ref: '#/components/schemas/SMSBatchTimeWindowItem'
          type: array
          minItems: 1
          title: Windows
          description: 허용 시간대 목록입니다(최소 1개).
        timezone:
          type: string
          title: Timezone
          description: 'IANA timezone 이름입니다. 예: `Asia/Seoul`.'
          default: Asia/Seoul
        auto_resume:
          type: boolean
          title: Auto Resume
          description: 허용 시간대에 다시 들어서면 자동으로 이어서 발신할지 여부입니다. 기본값은 true입니다.
          default: true
      additionalProperties: false
      type: object
      required:
        - windows
      title: SMSBatchSendTimeWindow
      description: 대량 문자 발신의 발신 허용 시간대 설정입니다.
    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`를 포함합니다.
    SMSBatchTimeWindowItem:
      properties:
        start_min:
          type: integer
          exclusiveMaximum: 1440
          minimum: 0
          title: Start Min
          description: 시작 시각입니다(자정 기준 분, 0~1439).
        end_min:
          type: integer
          maximum: 1440
          exclusiveMinimum: 0
          title: End Min
          description: 종료 시각입니다(자정 기준 분, 1~1440).
        days:
          items:
            type: string
            enum:
              - Monday
              - Tuesday
              - Wednesday
              - Thursday
              - Friday
              - Saturday
              - Sunday
          type: array
          minItems: 1
          title: Days
          description: 요일 이름입니다. Monday부터 Sunday까지의 영문 값을 사용합니다.
      additionalProperties: false
      type: object
      required:
        - start_min
        - end_min
        - days
      title: SMSBatchTimeWindowItem
      description: 대량 문자 발신의 발신 허용 시간대 한 구간입니다.
  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.