본문으로 건너뛰기

Messages (Anthropic)

Anthropic Messages 형식 어댑터. base URL만 바꾸면 Claude Code · Anthropic SDK를 그대로 붙일 수 있습니다.

POST/v1/messages
POST/v1/messages/count_tokens

PleumRouter는 Anthropic Messages 형식의 인바운드 요청을 받아 내부에서 라우팅합니다. 기존 Anthropic SDK나 Claude Code는 코드를 고칠 필요 없이 base URL만 PleumRouter로 바꾸면 그대로 동작합니다. 요청·응답은 모두 Anthropic Messages 스키마를 따르며, 내부적으로 OpenAI 형식으로 변환되어 처리됩니다.

연결하기#

Anthropic SDK는 base_url을 루트 URL https://apirouter.pleum.ai로 설정하세요. SDK가 여기에 /v1/messages를 덧붙입니다.

messages.ts

Anthropic Messages API

import Anthropic from "@anthropic-ai/sdk";

const anthropic = new Anthropic({
  apiKey: "plm_xxxxxxxxxxxxxxxx",
  // Root origin — the SDK appends /v1/messages
  baseURL: "https://apirouter.pleum.ai",
});

const message = await anthropic.messages.create({
  model: "claude-sonnet-4-6",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Why is the sky blue?" }],
});

console.log(message.content);
Anthropic SDK (Python)
from anthropic import Anthropic

client = Anthropic(
    api_key="plm_...",
    base_url="https://apirouter.pleum.ai",  # 루트 — SDK가 /v1/messages를 덧붙임
)

message = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
)
print(message.content[0].text)

Claude Code는 ANTHROPIC_BASE_URL을 /v1 없이 루트로 설정하고 ANTHROPIC_API_KEY에 plm_ 키를 넣으세요.

Claude Code
export ANTHROPIC_BASE_URL="https://apirouter.pleum.ai"
export ANTHROPIC_API_KEY="plm_..."
claude
base URL에 /v1을 붙이지 마세요. SDK가 다시 /v1/messages를 덧붙여 /v1/v1/messages가 되어 요청이 실패합니다. 반드시 루트인 https://apirouter.pleum.ai만 지정하세요.

인증은 plm_ API 키를 Authorization: Bearer 또는 x-api-key 헤더로 전달합니다. Claude Code는 두 헤더를 모두 보내며, 둘 중 어느 쪽이든 동작합니다.

메시지 생성#

파라미터타입필수설명
thinkingobject선택enabled | adaptive | disabled native union. enabled는 budget_tokens(1,024~32,000)를 요구합니다.
modelstring필수모델 ID. GET /v1/models에서 전체 목록 확인.
messagesarray필수{role, content} 배열. content는 문자열 또는 블록 배열(text / image / tool_use / tool_result)입니다.
max_tokensinteger선택생성할 최대 토큰 수. 기본값 4096.
systemstring | array선택시스템 프롬프트. 문자열 또는 블록 배열.
temperaturenumber선택샘플링 온도.
top_pnumber선택누적 확률 기반 샘플링(nucleus).
stop_sequencesarray선택중지 문자열 배열. 내부적으로 stop으로 매핑됩니다.
streamboolean선택true면 Anthropic SSE 스트리밍 응답.
toolsarray선택Anthropic 형식의 도구 {name, description, input_schema}. 내부에서 OpenAI 형식으로 변환됩니다.
tool_choiceobject선택{type: any | none | tool} 형식으로 도구 사용 방식을 지정합니다.
output_configobject선택effort(low·medium·high·xhigh·max)만 읽어 선택한 모델의 추론 강도 설정으로 전달합니다. 다른 키는 무시됩니다.
metadataobject선택허용되지만 프로바이더로 전달되지는 않습니다.
modelstring필수
messagesAnthropicMessage[]필수
rolestring필수

user | assistant

contentstring | ContentBlock[]필수
content[]object선택

text / image / tool_use / tool_result blocks (dict, not a closed model).

text

typeliteral필수

example: text

textstring선택

tool_use

typeliteral필수

example: tool_use

idstring선택
namestring선택
inputobject선택

tool_result

typeliteral필수

example: tool_result

tool_use_idstring선택
contentstring | object[]선택
max_tokensinteger선택

default: 4096

range: 1–128000

systemstring | object[]선택
temperaturenumber선택
top_pnumber선택
stop_sequencesstring[]선택
streamboolean선택

default: false

toolsobject[]선택

Anthropic tool dicts.

tool_choiceobject선택
metadataobject선택
thinkingobject선택

enabled

typeliteral필수

example: enabled

budget_tokensinteger필수

range: 1024–32000

displaystring선택

enum: omitted

adaptive

typeliteral필수

example: adaptive

displaystring선택

enum: omitted

disabled

typeliteral필수

example: disabled

thinking이 활성화되면 PleumRouter는 항상 display: "omitted"로 upstream에 요청합니다. tools를 함께 쓸 때 tool_choice는 auto 또는 none만 허용합니다. required·특정 도구 강제와 마지막 assistant 메시지 prefill은 크레딧 hold 전에 400으로 거절됩니다.

request
curl https://apirouter.pleum.ai/v1/messages \
  -H "x-api-key: plm_..." \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 1024,
    "thinking": {"type": "adaptive", "display": "omitted"},
    "system": "You are a helpful assistant.",
    "messages": [
      {"role": "user", "content": "Hello"}
    ]
  }'

응답은 Anthropic Messages 스키마를 따릅니다. content는 블록 배열이며, 토큰 사용량은 usage.input_tokens / usage.output_tokens로 반환됩니다. native thinking은 {type:"thinking", thinking:"", signature} 또는 {type:"redacted_thinking", data}의 opaque 블록으로만 반환되며, 평문 사고는 노출되지 않습니다. tool continuation에는 해당 블록과 _pleum_source_model 확장이 있다면 함께 원문 그대로 되돌려 보내세요.

stop_reason은 내부 종료 사유에서 매핑됩니다 — stop → end_turn, length → max_tokens, tool_calls → tool_use.

200 OK
{
  "id": "msg_01abc...",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-4-6",
  "content": [
    {"type": "thinking", "thinking": "", "signature": "<opaque>"},
    {"type": "text", "text": "Hello! How can I help you?"}
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 12,
    "output_tokens": 5
  }
}

스트리밍#

stream: true로 요청하면 Anthropic SSE 이벤트 시퀀스가 전송됩니다 — message_start → content_block_start / content_block_delta(text_delta) / content_block_stop → message_delta → message_stop. omitted thinking은 빈 thinking 블록 뒤 signature_delta, stop 순서로만 전송되며 thinking_delta나 평문 사고는 전송하지 않습니다. redacted 블록은 start/stop만 사용합니다. 스트리밍 모드에서는 비용 헤더가 포함되지 않습니다.

SSE stream
event: message_start
data: {"type":"message_start","message":{"id":"msg_01abc","type":"message","role":"assistant","model":"claude-sonnet-4-6","content":[],"stop_reason":null,"usage":{"input_tokens":12,"output_tokens":0}}}

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

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"signature_delta","signature":"<opaque>"}}

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

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

event: content_block_delta
data: {"type":"content_block_delta","index":1,"delta":{"type":"text_delta","text":"Hello! How can I help you?"}}

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

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

event: message_stop
data: {"type":"message_stop"}

토큰 수 세기#

/v1/messages와 동일한 본문을 받아 {"input_tokens": <int>}를 반환합니다. 이 값은 휴리스틱 추정치이며 실제 토크나이저 결과가 아닙니다.

request
curl https://apirouter.pleum.ai/v1/messages/count_tokens \
  -H "x-api-key: plm_..." \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "messages": [
      {"role": "user", "content": "Hello"}
    ]
  }'
200 OK
{
  "input_tokens": 12
}

과금 방식#

비용은 응답 본문에 포함되지 않습니다. 대신 응답 헤더 X-Cost-Krw(정수)와 X-Cost-Usd(소수), 그리고 x-request-id로 반환됩니다. 청구량은 오직 usage.output_tokens이며 thinking 세부값은 별도 청구·재가산되지 않습니다.