> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# Claude Messages

POST https://direct.beatapi.io/v1/messages
Content-Type: application/json

BeatAPI 키 하나로 Anthropic Messages 엔드포인트에서 Claude Fable 5.2, Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 5.5를 호출합니다.- 현재 모든 Claude 모델이 엔드포인트 `POST /v1/messages` 하나를 사용합니다. `model`만 바꿔 전환하세요.
- 텍스트·이미지 입력, 텍스트 출력, 스트리밍, 도구 사용, 확장 사고, 프롬프트 캐싱.
- Anthropic SDK와 호환됩니다. 기본 URL을 `https://direct.beatapi.io`(`/v1` 제외)로 설정하고 BeatAPI 키를 사용하세요.
- Claude 모델은 Anthropic Messages에서만 응답합니다. `/v1/responses`를 호출하면 `400`이 반환됩니다.텍스트 요청의 기본 URL로는 `https://direct.beatapi.io`를 사용하세요. Cloudflare의 100초 제한을 받지 않으므로 스트리밍하지 않는 긴 요청도 끊기지 않습니다. `https://api.beatapi.io`도 동작하며, 네트워크에서 `direct.beatapi.io`에 접근할 수 없을 때의 대안입니다. 키, 모델, 가격은 양쪽이 같습니다. 이미지와 영상 API는 `https://api.beatapi.io`만 사용합니다.POST/v1/messages실행해 보기API Explorer에서 이 엔드포인트를 엽니다. BeatAPI API 키를 입력하고 전송하세요. 실제 호출이며 본인 잔액에서 과금됩니다.## 모델`model`에 다음 ID 중 하나를 보내세요. 각각 별개의 모델이며, 서로의 별칭으로 취급하지 마세요.| 모델 ID               | 컨텍스트(토큰)  | 최대 출력(토큰) | 포지셔닝                                                       | 입력, 1M 토큰당 USD | 출력, 1M 토큰당 USD | 참고                                                                                                                            |
| ------------------- | --------- | --------- | ---------------------------------------------------------- | -------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `claude-opus-5-5`   | 1,000,000 | 128,000   | 오래 실행되는 에이전트 코딩과 지식 작업을 위한 Claude Opus 모델. Opus 5보다 저렴     | \$2.00         | \$10.00        | 오래 실행되는 에이전트 코딩과 지식 작업.                                                                                                       |
| `claude-sonnet-5-5` | 1,000,000 | 128,000   | 1M 토큰 컨텍스트 창을 갖춘 코딩, 추론, 전문 업무용 Claude Sonnet 5.5.         | \$1.00         | \$5.00         | 일상적인 코딩, 추론, 전문 업무.                                                                                                           |
| `claude-haiku-5-5`  | 1,000,000 | 128,000   | 분류, 추출, 라우팅처럼 대량이고 지연에 민감한 작업을 위한 가장 빠른 Claude 모델          | \$0.05         | \$0.25         | 분류, 추출, 라우팅 같은 대량 작업을 위한 가장 빠른 Claude.                                                                                        |
| `claude-fable-5-2`  | 1,000,000 | 128,000   | 까다로운 추론과 장기 에이전트 작업을 위한 최신 Claude Fable 모델. Fable 5.1보다 저렴 | \$4.00         | \$20.00        | 가장 어려운 추론과 장기 에이전트 작업을 위한 최신 Fable. Fable 5.1보다 저렴합니다. 적응형 사고가 항상 켜져 있으므로 샘플링 파라미터를 생략하고, tool\_choice를 any나 특정 도구로 강제하지 마세요. |
| `claude-fable-5-1`  | 1,000,000 | 128,000   | 까다로운 추론과 장기 에이전트 작업을 위한 Claude 모델                          | \$5.00         | \$25.00        | 어조와 구조가 가장 중요한 장문 글쓰기와 작업.                                                                                                    |- 가격은 할인이 적용된 기본 등급입니다. 롱 컨텍스트 등급, 캐시 입력 요금, 캐시 쓰기는 이 표에 없습니다. [가격표](https://beatapi.io/pricing)를 참고하세요.
- `—`는 카탈로그에서 해당 수치를 공개하지 않는다는 뜻입니다.이 계열의 이전 ID도 계속 동작하며 [레거시 모델](/text-api/legacy-models)에 나와 있습니다.## 빠른 시작서버에 `anthropic` 패키지를 설치하고 키는 `BEATAPI_API_KEY`에 보관하세요. 브라우저 코드에는 절대 넣지 마세요. 아래는 요청 예시이며 실제로 기록된 모델 출력이 아닙니다.`content`의 `text` 블록에서 답변을 읽은 다음 `stop_reason`과 `usage`를 확인하세요. HTTP 200만으로는 답변이 작업 요구를 충족한다고 볼 수 없으니 애플리케이션에서 검증하세요. 텍스트 요청은 바로 반환되므로 `/v1/tasks`를 폴링하지 마세요.```bash title="cURL"
curl --request POST \
  --url https://direct.beatapi.io/v1/messages \
  --header "x-api-key: $BEATAPI_API_KEY" \
  --header 'anthropic-version: 2023-06-01' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": "Design a resilient webhook retry strategy for a payments API."
    }
  ]
}'
``````python title="Python"
import os
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["BEATAPI_API_KEY"], base_url="https://direct.beatapi.io")
message = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    messages=[
      {
        "role": "user",
        "content": "Design a resilient webhook retry strategy for a payments API."
      }
    ],
)
print(message.content[0].text)
``````javascript title="JavaScript"
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({ apiKey: process.env.BEATAPI_API_KEY, baseURL: "https://direct.beatapi.io" });
const message = await client.messages.create({
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": "Design a resilient webhook retry strategy for a payments API."
    }
  ]
});
console.log(message.content[0].text);
```## 엔드포인트와 인증`POST https://direct.beatapi.io/v1/messages`x-api-key
string
필수BeatAPI 키입니다. `Authorization: Bearer <BEATAPI_API_KEY>`도 받습니다.`anthropic-version` 헤더를 보내세요(예: `anthropic-version: 2023-06-01`). 키는 `x-api-key`나 `Authorization: Bearer <key>`에 넣으며 둘 다 동작하므로, 기존 Anthropic 클라이언트는 기본 URL만 바꾸면 됩니다.Claude 모델은 Anthropic Messages에서만 응답합니다. `/v1/responses`에서 호출하면 `400`이 반환됩니다.## 요청 파라미터표준 Anthropic Messages 필드를 받습니다. 요청 형식이 호환된다고 해서 모든 베타 기능이나 서버 도구가 지원되는 것은 아니므로, 사용하는 옵션은 직접 테스트하세요.model
string
필수정확한 모델 ID입니다.**허용 값**: `claude-fable-5-2`, `claude-fable-5-1`, `claude-opus-5-5`, `claude-sonnet-5-5`, `claude-haiku-5-5`- 계속 동작하는 이전 ID(`claude-opus-5`, `claude-sonnet-5`, `claude-haiku-4-5-20251001`)는 [레거시 모델](/text-api/legacy-models)에 있습니다.
- 키로 `GET /v1/models`를 호출해 사용 가능한 모델을 확인하세요.max_tokens
integer
필수생성 토큰의 상한이며, 사고 토큰을 포함합니다.- 항상 보내세요. 없거나 `0`이면 기본 한도가 적용되며, 이 기본값은 예상보다 낮을 수 있습니다.
- 허용되는 최댓값은 1,073,741,823이며, 그보다 크면 `400 bad_request`입니다. 위 표에 있는 모델의 최대 출력 이하로 설정하세요.
- `max_tokens`는 요청에 필요한 잔액을 추정하는 데도 쓰입니다. 실제 출력이 작더라도 값이 너무 크면 `402 insufficient_credits`로 거부될 수 있습니다. 필요한 만큼만 설정하세요.messages
object[]
필수대화 내용이며 오래된 메시지부터 나열합니다. 각 메시지에는 `role`(`user` 또는 `assistant`)와 `content`가 있습니다. `content`는 문자열이거나 콘텐츠 블록 배열입니다.- 사용할 블록 유형: `text`, `image`(base64 또는 URL 소스), `tool_use`(어시스턴트 메시지 안), `tool_result`(사용자 메시지 안).
- `messages` 배열이 비어 있거나 없으면 `400 bad_request`입니다.**예시**```json
[
  {
    "role": "user",
    "content": [
      { "type": "text", "text": "What is in this image?" },
      { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "<base64>" } }
    ]
  }
]
```system
string | object[]
선택시스템 프롬프트입니다. 문자열 또는 `text` 블록 배열입니다. 길고 변하지 않는 접두부를 캐시하려면 블록에 `cache_control`을 넣으세요.**예시**```json
[
  {
    "type": "text",
    "text": "<long, stable instructions>",
    "cache_control": { "type": "ephemeral" }
  }
]
```stream
boolean
선택기본값: false답변을 서버 전송 이벤트로 반환합니다. 아래 스트리밍 섹션을 참고하세요.**기본값**: `false`stop_sequences
string[]
선택생성을 멈추는 사용자 지정 문자열입니다. 이때 응답에는 `stop_reason: "stop_sequence"`가 있습니다.tools
object[]
선택모델이 호출할 수 있는 도구입니다. 각각 `name`, `description`, `input_schema`(JSON Schema)를 가집니다. 모델이 도구를 호출하면 답변에 `stop_reason: "tool_use"`가 있으니, 도구를 실행하고 그 결과를 이어지는 `tool_result` 블록으로 반환하세요.**예시**```json
[
  {
    "name": "get_weather",
    "description": "Get the current weather for a city.",
    "input_schema": {
      "type": "object",
      "properties": { "city": { "type": "string" } },
      "required": ["city"]
    }
  }
]
```tool_choice
object
선택모델이 `tools`를 사용해야 하는지, 어떻게 사용해야 하는지 정합니다.**허용 값**: `{"type":"auto"}`, `{"type":"any"}`, `{"type":"tool","name":"..."}`, `{"type":"none"}`- `auto`는 모델이 판단하고, `any`는 도구 중 하나를 강제하며, `tool`은 지정한 도구를 강제하고, `none`은 도구 사용을 금지합니다.**예시**```json
{ "type": "auto" }
{ "type": "tool", "name": "get_weather" }
```thinking
object
선택확장 사고입니다. `type`으로 켜고 끕니다. 사고 토큰은 `max_tokens`에 포함되며 출력 토큰으로 과금됩니다.**허용 값**: `adaptive`, `enabled`, `disabled`- `thinking.type`은 위 값 중 하나입니다. `enabled`는 `thinking.budget_tokens`(1,024 이상이고 `max_tokens`보다 작은 정수)를 받습니다.
- `thinking.display`는 `summarized` 또는 `omitted`입니다. 최신 모델은 `summarized`를 요청하지 않으면 사고 텍스트를 반환하지 않을 수 있습니다.
- 적응형 사고의 깊이는 `output_config.effort`로 설정하세요.**모델별**- `claude-fable-5-2`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. 적응형 사고가 항상 켜져 있으며, 끄거나 수동 `budget_tokens`를 설정할 수 없습니다.
- `claude-fable-5-1`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다.
- `claude-opus-5-5`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다.
- `claude-sonnet-5-5`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다.**예시**```json
{
  "thinking": { "type": "adaptive" },
  "output_config": { "effort": "high" }
}
```output_config.effort
string
선택모델이 추론하는 양입니다. `high`로 시작한 다음, 실제 워크로드에서 한 단계 낮은 값과 높은 값을 평가해 보세요.**허용 값**: `low`, `medium`, `high`, `xhigh`, `max`cache_control
object
선택프롬프트 캐싱입니다. `system`, `messages` 또는 `tools` 블록에 넣으면 그 블록까지 모두 캐시하며, 요청 최상위에 넣을 수도 있습니다. `ttl`은 `5m`(기본값) 또는 `1h`입니다.**허용 값**: `{"type":"ephemeral"}`- 캐시 읽기, 5분 캐시 쓰기, 1시간 캐시 쓰기는 따로 계량됩니다. 캐시된 접두부는 새 입력이 아니라 캐시 읽기로 과금됩니다.
- 캐시 적중 수는 `usage.cache_read_input_tokens`와 `usage.cache_creation_input_tokens`에 있습니다.**예시**```json
{ "type": "ephemeral" }
{ "type": "ephemeral", "ttl": "1h" }
```## 도구 사용 루프`stop_reason`이 `tool_use`이면 반환된 어시스턴트 메시지를 그대로 덧붙이고, 도구를 실행한 뒤 다음 `user` 메시지의 `tool_result` 블록으로 결과를 보내세요. 같은 `tools`를 다시 보내세요.```json
{
  "max_tokens": 1024,
  "messages": [
    { "role": "user", "content": "What is the weather in Paris?" },
    {
      "role": "assistant",
      "content": [
        { "type": "tool_use", "id": "toolu_example", "name": "get_weather", "input": { "city": "Paris" } }
      ]
    },
    {
      "role": "user",
      "content": [
        { "type": "tool_result", "tool_use_id": "toolu_example", "content": "18 C, light rain" }
      ]
    }
  ]
}
```## 응답스트리밍하지 않는 호출은 JSON 객체 하나를 반환합니다. 아래는 축약한 예시입니다.```json
{
  "id": "msg_example",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-5-5",
  "content": [
    {
      "type": "text",
      "text": "Retry with exponential backoff and jitter, and make every handler idempotent."
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 19,
    "output_tokens": 16
  }
}
```### 응답 필드| 필드                                  | 타입        | 설명                                                                                                 |
| ----------------------------------- | --------- | -------------------------------------------------------------------------------------------------- |
| `id`                                | `string`  | 메시지 ID입니다. 지원과 과금 감사를 위해 요청 ID와 함께 기록하세요.                                                          |
| `model`                             | `string`  | 응답한 모델입니다.                                                                                         |
| `content[].type`                    | `string`  | `text`, `tool_use`, 또는 사고 텍스트가 반환되면 `thinking`.                                                    |
| `content[].text`                    | `string`  | `text` 블록의 답변 텍스트입니다.                                                                              |
| `stop_reason`                       | `string`  | 완전한 답변이면 `end_turn`, `max_tokens`에 도달하면 `max_tokens`, `stop_sequence`, 모델이 도구를 호출하면 `tool_use`입니다. |
| `usage.input_tokens`                | `integer` | 캐시에서 제공되지 않은 입력 토큰입니다.                                                                             |
| `usage.output_tokens`               | `integer` | 출력 토큰이며, 사고 토큰을 포함합니다.                                                                             |
| `usage.cache_read_input_tokens`     | `integer` | 프롬프트 캐시에서 읽은 입력 토큰입니다.                                                                             |
| `usage.cache_creation_input_tokens` | `integer` | 프롬프트 캐시에 쓴 입력 토큰입니다.                                                                               |## 스트리밍`"stream": true`를 설정하세요. 응답은 Anthropic SDK와 호환되는 Anthropic 서버 전송 이벤트 스트림입니다.- 이벤트는 `message_start`, `ping`, `content_block_start`, `content_block_delta`, `content_block_stop`, `message_delta`, `message_stop`입니다.
- 텍스트는 `text_delta`로, 도구 입력은 `input_json_delta`로(조각을 이어 붙인 뒤 파싱), 사고 텍스트는 `thinking_delta`로 도착합니다.
- `stop_reason`과 최종 출력 토큰 수는 `message_delta`로 도착합니다.
- 응답은 `text/event-stream`이며, 스트리밍하지 않으면 `application/json`입니다. 모델 호출 전에 발생한 실패는 스트림 이벤트가 아니라 HTTP 상태와 함께 일반 JSON 오류로 반환됩니다.
- 명시적인 시간 제한을 설정하고, 스트리밍 응답은 안전하게 다시 연결하세요.```text
event: message_start
data: {"type":"message_start","message":{"id":"msg_example","type":"message","role":"assistant","model":"claude-sonnet-5-5","content":[],"stop_reason":null,"usage":{"input_tokens":19,"output_tokens":1}}}

event: ping
data: {"type":"ping"}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Retry"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" with backoff"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":16}}

event: message_stop
data: {"type":"message_stop"}
```## 오류| 오류 또는 증상                                           | 원인                                                                         | 해결 방법                                             |
| -------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------- |
| `400`: `messages`나 `model`이 없거나 `max_tokens`가 너무 큼 | `messages`가 비어 있거나 없음, `model`이 비어 있음, 또는 `max_tokens`가 1,073,741,823보다 큼. | 두 필드를 모두 보내고 `max_tokens`는 한도 안으로 설정하세요.          |
| `/v1/responses`에서 `400`                            | Claude 모델은 OpenAI Responses에서 제공되지 않습니다.                                   | `POST /v1/messages`를 호출하세요.                       |
| `thinking` 설정에 대한 `400`                            | 모델이 해당 설정을 받지 않습니다. 예: 적응형 사고를 쓰는 모델에 `budget_tokens`.                     | 위의 `thinking`에서 모델별로 안내한 설정을 사용하세요.               |
| `402 insufficient_credits`                         | 잔액이 요청 가격보다 적습니다. 대개 `max_tokens`가 너무 크기 때문입니다.                            | 충전하거나 `max_tokens`를 낮추세요.                         |
| `403 forbidden`                                    | 계정이 무료 크레딧 상태인데 모델이 무료 목록에 없거나, 모델이 키의 그룹 밖에 있습니다.                         | 충전하거나, 무료 모델을 쓰거나, 그룹에서 해당 모델에 접근할 수 있는 키를 사용하세요. |
| `404 not_found`                                    | 알 수 없는 모델 ID이거나 이 키에서 사용할 수 없습니다.                                          | `GET /v1/models`로 사용 가능한 모델을 확인하세요.               |
| `429 rate_limit_exceeded`                          | 계정 또는 무료 모델 한도에 도달했습니다.                                                    | `Retry-After`만큼 기다린 뒤 재시도하세요.                     |
| `stop_reason: "max_tokens"`와 함께 짧거나 빈 답변이 있는 `200` | 답변을 쓰기 전에 대개 사고 과정에서 `max_tokens`를 모두 써 버렸습니다.                             | `max_tokens`를 높이거나 `output_config.effort`를 낮추세요.  |### HTTP 오류 요약인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.| HTTP 상태 | 코드                                                         | 조치                                                             |
| ------- | ---------------------------------------------------------- | -------------------------------------------------------------- |
| 400     | `bad_request`, `content_policy_violation`                  | 요청이나 입력을 수정하세요. 그대로 다시 보내지 마세요.                                |
| 401     | `missing_api_key`, `invalid_api_key`                       | 키를 확인하세요. 재시도하지 마세요.                                           |
| 402     | `insufficient_credits`                                     | 충전하거나 키 한도를 높이세요. `max_tokens`가 너무 크면 발생할 수 있습니다.              |
| 403     | `forbidden`                                                | 모델이 키의 그룹이나 IP 허용 목록 밖에 있거나, 무료 크레딧으로 이 모델을 호출할 수 없습니다.        |
| 404     | `not_found`                                                | 알 수 없는 모델입니다. `GET /v1/models`로 사용 가능한 모델 목록을 확인하세요.           |
| 429     | `rate_limit_exceeded`                                      | `Retry-After` 또는 `retry_after_seconds`만큼 기다린 뒤 백오프를 두고 재시도하세요. |
| 500     | `internal_error`, `temporary_error`                        | 백오프를 적용해 한두 번 재시도하세요.                                          |
| 503     | `model_unavailable`, `upstream_timeout`, `temporary_error` | 백오프를 적용해 재시도하거나 다른 모델을 사용하세요.                                  |전체 코드 표와 재시도 정책: [오류](/errors#text-endpoints).## 참고- Claude 모델은 [OpenAI Responses](/text-api/gpt/responses)가 아니라 Anthropic Messages에서만 응답합니다.
- 사고 토큰은 출력 토큰으로 과금되며 `max_tokens`에 포함됩니다. 사고와 답변을 모두 담을 수 있도록 출력 한도를 넉넉히 잡으세요.
- API 키는 신뢰할 수 있는 서버에 두고, 응답의 요청 ID를 기록하며, `429`, `500`, `503`만 재시도하세요.

Reference: https://docs.beatapi.io/api-reference/text-api/claude-messages

## Authentication

- `Authorization` header (bearer token, required) — API 키를 `Authorization: Bearer <BEATAPI_API_KEY>`로 보내세요.

## Servers

- `https://direct.beatapi.io` (Direct, default)
- `https://api.beatapi.io` (API)

## Request

### Body (application/json)

This endpoint expects an object.

- `model` (enum, required) — 정확한 모델 ID입니다. 계속 동작하는 이전 ID(`claude-opus-5`, `claude-sonnet-5`, `claude-haiku-4-5-20251001`)는 [레거시 모델](/text-api/legacy-models)에 있습니다. 키로 `GET /v1/models`를 호출해 사용 가능한 모델을 확인하세요. `claude-fable-5-2`, `claude-fable-5-1`, `claude-opus-5-5`, `claude-sonnet-5-5`, `claude-haiku-5-5`
  - Allowed values: `claude-opus-5-5`, `claude-sonnet-5-5`, `claude-haiku-5-5`, `claude-fable-5-2`, `claude-fable-5-1`
- `max_tokens` (integer, required) — 생성 토큰의 상한이며, 사고 토큰을 포함합니다. 항상 보내세요. 없거나 `0`이면 기본 한도가 적용되며, 이 기본값은 예상보다 낮을 수 있습니다. 허용되는 최댓값은 1,073,741,823이며, 그보다 크면 `400 bad_request`입니다. 위 표에 있는 모델의 최대 출력 이하로 설정하세요. `max_tokens`는 요청에 필요한 잔액을 추정하는 데도 쓰입니다. 실제 출력이 작더라도 값이 너무 크면 `402 insufficient_credits`로 거부될 수 있습니다. 필요한 만큼만 설정하세요.
- `messages` (list of V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItems, required) — 대화 내용이며 오래된 메시지부터 나열합니다. 각 메시지에는 `role`(`user` 또는 `assistant`)와 `content`가 있습니다. `content`는 문자열이거나 콘텐츠 블록 배열입니다. 사용할 블록 유형: `text`, `image`(base64 또는 URL 소스), `tool_use`(어시스턴트 메시지 안), `tool_result`(사용자 메시지 안). `messages` 배열이 비어 있거나 없으면 `400 bad_request`입니다.
- `system` (V1MessagesPostRequestBodyContentApplicationJsonSchemaSystem, optional) — 시스템 프롬프트입니다. 문자열 또는 `text` 블록 배열입니다. 길고 변하지 않는 접두부를 캐시하려면 블록에 `cache_control`을 넣으세요.
- `stream` (boolean, optional, default: false) — 답변을 서버 전송 이벤트로 반환합니다. 아래 스트리밍 섹션을 참고하세요.
- `stop_sequences` (list of string, optional) — 생성을 멈추는 사용자 지정 문자열입니다. 이때 응답에는 `stop_reason: "stop_sequence"`가 있습니다.
- `tools` (list of V1MessagesPostRequestBodyContentApplicationJsonSchemaToolsItems, optional) — 모델이 호출할 수 있는 도구입니다. 각각 `name`, `description`, `input_schema`(JSON Schema)를 가집니다. 모델이 도구를 호출하면 답변에 `stop_reason: "tool_use"`가 있으니, 도구를 실행하고 그 결과를 이어지는 `tool_result` 블록으로 반환하세요.
- `tool_choice` (V1MessagesPostRequestBodyContentApplicationJsonSchemaToolChoice, optional) — 모델이 `tools`를 사용해야 하는지, 어떻게 사용해야 하는지 정합니다. `auto`는 모델이 판단하고, `any`는 도구 중 하나를 강제하며, `tool`은 지정한 도구를 강제하고, `none`은 도구 사용을 금지합니다. `{"type":"auto"}`, `{"type":"any"}`, `{"type":"tool","name":"..."}`, `{"type":"none"}`
- `thinking` (V1MessagesPostRequestBodyContentApplicationJsonSchemaThinking, optional) — 확장 사고입니다. `type`으로 켜고 끕니다. 사고 토큰은 `max_tokens`에 포함되며 출력 토큰으로 과금됩니다. `thinking.type`은 위 값 중 하나입니다. `enabled`는 `thinking.budget_tokens`(1,024 이상이고 `max_tokens`보다 작은 정수)를 받습니다. `thinking.display`는 `summarized` 또는 `omitted`입니다. 최신 모델은 `summarized`를 요청하지 않으면 사고 텍스트를 반환하지 않을 수 있습니다. 적응형 사고의 깊이는 `output_config.effort`로 설정하세요. `claude-fable-5-2`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. 적응형 사고가 항상 켜져 있으며, 끄거나 수동 `budget_tokens`를 설정할 수 없습니다. `claude-fable-5-1`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다. `claude-opus-5-5`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다. `claude-sonnet-5-5`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다. `adaptive`, `enabled`, `disabled`
- `output_config` (V1MessagesPostRequestBodyContentApplicationJsonSchemaOutputConfig, optional)
- `cache_control` (V1MessagesPostRequestBodyContentApplicationJsonSchemaCacheControl, optional) — 프롬프트 캐싱입니다. `system`, `messages` 또는 `tools` 블록에 넣으면 그 블록까지 모두 캐시하며, 요청 최상위에 넣을 수도 있습니다. `ttl`은 `5m`(기본값) 또는 `1h`입니다. 캐시 읽기, 5분 캐시 쓰기, 1시간 캐시 쓰기는 따로 계량됩니다. 캐시된 접두부는 새 입력이 아니라 캐시 읽기로 과금됩니다. 캐시 적중 수는 `usage.cache_read_input_tokens`와 `usage.cache_creation_input_tokens`에 있습니다. `{"type":"ephemeral"}`

## Response

### 200

스트리밍하지 않는 호출은 JSON 객체 하나를 반환합니다. 아래는 축약한 예시입니다.

- `id` (string, optional) — 메시지 ID입니다. 지원과 과금 감사를 위해 요청 ID와 함께 기록하세요.
- `model` (string, optional) — 응답한 모델입니다.
- `content` (list of V1MessagesPostResponsesContentApplicationJsonSchemaContentItems, optional)
- `stop_reason` (string, optional) — 완전한 답변이면 `end_turn`, `max_tokens`에 도달하면 `max_tokens`, `stop_sequence`, 모델이 도구를 호출하면 `tool_use`입니다.
- `usage` (V1MessagesPostResponsesContentApplicationJsonSchemaUsage, optional)

## Errors

### 400 Bad Request Error

`bad_request`, `content_policy_violation` 요청이나 입력을 수정하세요. 그대로 다시 보내지 마세요. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

### 401 Unauthorized Error

`missing_api_key`, `invalid_api_key` 키를 확인하세요. 재시도하지 마세요. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

### 402 Payment Required Error

`insufficient_credits` 충전하거나 키 한도를 높이세요. `max_tokens`가 너무 크면 발생할 수 있습니다. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

### 403 Forbidden Error

`forbidden` 모델이 키의 그룹이나 IP 허용 목록 밖에 있거나, 무료 크레딧으로 이 모델을 호출할 수 없습니다. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

### 404 Not Found Error

`not_found` 알 수 없는 모델입니다. `GET /v1/models`로 사용 가능한 모델 목록을 확인하세요. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

### 429 Too Many Requests Error

`rate_limit_exceeded` `Retry-After` 또는 `retry_after_seconds`만큼 기다린 뒤 백오프를 두고 재시도하세요. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

### 500 Internal Server Error

`internal_error`, `temporary_error` 백오프를 적용해 한두 번 재시도하세요. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

### 503 Service Unavailable Error

`model_unavailable`, `upstream_timeout`, `temporary_error` 백오프를 적용해 재시도하거나 다른 모델을 사용하세요. 인증, 라우팅, 요청 속도 제한, 알 수 없는 모델 실패는 모델 호출 전에 BeatAPI 오류 형식(`error.code`, `error.message`, `retryable`, `request_id`)으로 응답합니다. 그 밖의 모든 실패는 Anthropic 형식 `{"type": "error", "error": {"type", "message"}}`를 유지하며, 코드는 `error.type`에 있고 요청 id는 `message`로 끝납니다. [오류](/errors#text-endpoints)를 참고하세요.

- `map from string to any`

## Types

### V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItems

- `role` (string, required)
- `content` (V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContent, required)

### V1MessagesPostRequestBodyContentApplicationJsonSchemaSystem

시스템 프롬프트입니다. 문자열 또는 `text` 블록 배열입니다. 길고 변하지 않는 접두부를 캐시하려면 블록에 `cache_control`을 넣으세요.

- string
- list of V1MessagesPostRequestBodyContentApplicationJsonSchemaSystemOneOf1Items

### V1MessagesPostRequestBodyContentApplicationJsonSchemaToolsItems

### V1MessagesPostRequestBodyContentApplicationJsonSchemaToolChoice

모델이 `tools`를 사용해야 하는지, 어떻게 사용해야 하는지 정합니다. `auto`는 모델이 판단하고, `any`는 도구 중 하나를 강제하며, `tool`은 지정한 도구를 강제하고, `none`은 도구 사용을 금지합니다. `{"type":"auto"}`, `{"type":"any"}`, `{"type":"tool","name":"..."}`, `{"type":"none"}`

### V1MessagesPostRequestBodyContentApplicationJsonSchemaThinking

확장 사고입니다. `type`으로 켜고 끕니다. 사고 토큰은 `max_tokens`에 포함되며 출력 토큰으로 과금됩니다. `thinking.type`은 위 값 중 하나입니다. `enabled`는 `thinking.budget_tokens`(1,024 이상이고 `max_tokens`보다 작은 정수)를 받습니다. `thinking.display`는 `summarized` 또는 `omitted`입니다. 최신 모델은 `summarized`를 요청하지 않으면 사고 텍스트를 반환하지 않을 수 있습니다. 적응형 사고의 깊이는 `output_config.effort`로 설정하세요. `claude-fable-5-2`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. 적응형 사고가 항상 켜져 있으며, 끄거나 수동 `budget_tokens`를 설정할 수 없습니다. `claude-fable-5-1`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다. `claude-opus-5-5`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다. `claude-sonnet-5-5`: `{"type":"adaptive"}`를 사용하고 `output_config.effort`로 깊이를 설정하세요. `budget_tokens`는 거부됩니다. `adaptive`, `enabled`, `disabled`

- `type` (enum, optional)
  - Allowed values: `adaptive`, `enabled`, `disabled`

### V1MessagesPostRequestBodyContentApplicationJsonSchemaOutputConfig

- `effort` (enum, optional) — 모델이 추론하는 양입니다. `high`로 시작한 다음, 실제 워크로드에서 한 단계 낮은 값과 높은 값을 평가해 보세요. `low`, `medium`, `high`, `xhigh`, `max`
  - Allowed values: `low`, `medium`, `high`, `xhigh`, `max`

### V1MessagesPostRequestBodyContentApplicationJsonSchemaCacheControl

프롬프트 캐싱입니다. `system`, `messages` 또는 `tools` 블록에 넣으면 그 블록까지 모두 캐시하며, 요청 최상위에 넣을 수도 있습니다. `ttl`은 `5m`(기본값) 또는 `1h`입니다. 캐시 읽기, 5분 캐시 쓰기, 1시간 캐시 쓰기는 따로 계량됩니다. 캐시된 접두부는 새 입력이 아니라 캐시 읽기로 과금됩니다. 캐시 적중 수는 `usage.cache_read_input_tokens`와 `usage.cache_creation_input_tokens`에 있습니다. `{"type":"ephemeral"}`

### V1MessagesPostResponsesContentApplicationJsonSchemaContentItems

- `type` (string, optional) — `text`, `tool_use`, 또는 사고 텍스트가 반환되면 `thinking`.
- `text` (string, optional) — `text` 블록의 답변 텍스트입니다.

### V1MessagesPostResponsesContentApplicationJsonSchemaUsage

- `input_tokens` (integer, optional) — 캐시에서 제공되지 않은 입력 토큰입니다.
- `output_tokens` (integer, optional) — 출력 토큰이며, 사고 토큰을 포함합니다.
- `cache_read_input_tokens` (integer, optional) — 프롬프트 캐시에서 읽은 입력 토큰입니다.
- `cache_creation_input_tokens` (integer, optional) — 프롬프트 캐시에 쓴 입력 토큰입니다.

### V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContent

- string
- list of V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1Items

### V1MessagesPostRequestBodyContentApplicationJsonSchemaSystemOneOf1Items

### V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1Items

- `type` (string, optional)
- `text` (string, optional)
- `image_url` (V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1ItemsImageUrl, optional)
- `source` (V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1ItemsSource, optional)

### V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1ItemsImageUrl

- string
- V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1ItemsImageUrl1

### V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1ItemsSource

- `type` (string, optional)
- `media_type` (string, optional)
- `data` (string, optional)
- `url` (string, optional)

### V1MessagesPostRequestBodyContentApplicationJsonSchemaMessagesItemsContentOneOf1ItemsImageUrl1

- `url` (string, optional)
- `detail` (string, optional)

## Examples

**Request**

```json
{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": "Design a resilient webhook retry strategy for a payments API."
    }
  ]
}
```

**Response**

```json
{
  "id": "msg_example",
  "model": "claude-sonnet-5-5",
  "content": [
    {
      "type": "text",
      "text": "Retry with exponential backoff and jitter, and make every handler idempotent."
    }
  ],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 19,
    "output_tokens": 16
  },
  "role": "assistant",
  "stop_sequence": null,
  "type": "message"
}
```

**SDK Code**

```python 빠른 시작
import requests

url = "https://direct.beatapi.io/v1/messages"

payload = {
    "model": "claude-sonnet-5-5",
    "max_tokens": 1024,
    "messages": [
        {
            "role": "user",
            "content": "Design a resilient webhook retry strategy for a payments API."
        }
    ]
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript 빠른 시작
const url = 'https://direct.beatapi.io/v1/messages';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"model":"claude-sonnet-5-5","max_tokens":1024,"messages":[{"role":"user","content":"Design a resilient webhook retry strategy for a payments API."}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go 빠른 시작
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://direct.beatapi.io/v1/messages"

	payload := strings.NewReader("{\n  \"model\": \"claude-sonnet-5-5\",\n  \"max_tokens\": 1024,\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Design a resilient webhook retry strategy for a payments API.\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby 빠른 시작
require 'uri'
require 'net/http'

url = URI("https://direct.beatapi.io/v1/messages")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"model\": \"claude-sonnet-5-5\",\n  \"max_tokens\": 1024,\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Design a resilient webhook retry strategy for a payments API.\"\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java 빠른 시작
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://direct.beatapi.io/v1/messages")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"model\": \"claude-sonnet-5-5\",\n  \"max_tokens\": 1024,\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Design a resilient webhook retry strategy for a payments API.\"\n    }\n  ]\n}")
  .asString();
```

```php 빠른 시작
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://direct.beatapi.io/v1/messages', [
  'body' => '{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": "Design a resilient webhook retry strategy for a payments API."
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp 빠른 시작
using RestSharp;

var client = new RestClient("https://direct.beatapi.io/v1/messages");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"model\": \"claude-sonnet-5-5\",\n  \"max_tokens\": 1024,\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"Design a resilient webhook retry strategy for a payments API.\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift 빠른 시작
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "messages": [
    [
      "role": "user",
      "content": "Design a resilient webhook retry strategy for a payments API."
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://direct.beatapi.io/v1/messages")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```