Claude Messages API Application and Usage

Anthropic Claude is a very powerful AI dialogue system that can generate smooth and natural replies in just a few seconds by inputting prompts. The Claude Messages API is the official native API format from Anthropic, which differs from the OpenAI compatible format (Chat Completion) by adopting Anthropic's own request and response structure, allowing better utilization of Claude's unique capabilities, such as multimodal content input, tool invocation, and advanced features like Extended Thinking.

This document mainly introduces the usage process of the Claude Messages API, allowing us to use the native interface consistent with Anthropic's official offerings to invoke Claude's dialogue capabilities.

Application Process

To use the Claude Messages API, first go to the 辰汐ai Console to obtain your API Token for backup.

If you are not logged in or registered, you will be automatically redirected to the login page inviting you to register and log in, after which you will be automatically returned to the current page.

One API Token can call all services on the platform without needing to apply separately for each service. The first application will grant a free quota for a trial experience; when the quota is insufficient, you can recharge the general balance in the console.

📘 Complete Documentation: Claude Messages API →

Basic Usage

The request path for the Claude Messages API is /v1/messages, consistent with the Anthropic official API. We need to provide at least three required parameters:

  • model: Choose the Claude model to use, such as claude-opus-4-20250514, claude-sonnet-4-20250514, etc.
  • messages: An array of input messages, each containing role (role) and content (content), where role supports user and assistant.
  • max_tokens: The maximum number of output tokens, used to limit the length of a single reply.

Common optional parameters:

  • system: System prompt used to set the model's behavior and role.
  • temperature: Generation randomness, between 0-1, with higher values resulting in more diverse replies.
  • stream: Whether to use streaming responses; set to true for a word-by-word return effect.
  • stop_sequences: Custom stop sequences; the model will stop generating when encountering these texts.
  • top_p: Nucleus sampling parameter, used with temperature to control generation randomness.
  • top_k: Sample only from the top K options with the highest probabilities.
  • tools: Tool definitions for allowing the model to invoke external functions.
  • tool_choice: Controls how the model uses the provided tools.
  • cache_control: Automatically creates cache breakpoints at the last cacheable content block of the request; can also be written on specific content blocks.

cURL Example

curl -X POST 'https://api.acedata.cloud/v1/messages' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "claude-opus-4-8",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": "Hello, Claude"
      }
    ]
  }'

Python Example

import requests

url = "https://api.acedata.cloud/v1/messages"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}

payload = {
    "model": "claude-opus-4-8",
    "max_tokens": 1024,
    "messages": [
        {"role": "user", "content": "Hello, Claude"}
    ]
}

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

After the call, the returned result is as follows:

{
  "id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Hi! My name is Claude. How can I help you today?"
    }
  ],
  "model": "claude-opus-4-8",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 12,
    "output_tokens": 15
  }
}

Returned result field descriptions:

  • id: The unique identifier for this message.
  • type: Always message.
  • role: Always assistant.
  • content: An array of reply content, with each element containing type (e.g., text) and corresponding content.
  • model: The name of the model processing the request.
  • stop_reason: The reason for stopping. Stable values include end_turn, max_tokens, stop_sequence, tool_use, pause_turn (which can return the current assistant content as is to continue), refusal, and model_context_window_exceeded.
  • stop_sequence: If stopped due to a custom stop sequence, displays the matching stop sequence text.
  • stop_details: When stop_reason is refusal, may include refusal category and explanation.
  • usage: Token usage statistics. input_tokens is uncached input; cache_creation_input_tokens and cache_read_input_tokens are for cache writing and reading, respectively; output_tokens is the number of output tokens. Non-streaming responses may also include cost recorded by 辰汐ai.

System Prompt

The Claude Messages API supports setting a system prompt through the system field to define the model's behavior, role, and context.

Python Example

import requests

url = "https://api.acedata.cloud/v1/messages"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}

payload = {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "system": "You are a professional Chinese translation assistant. Please translate the user's input from English to Chinese.",
    "messages": [
        {"role": "user", "content": "The quick brown fox jumps over the lazy dog."}
    ]
}

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

By setting the system prompt, you can precisely control Claude's role and behavior.

Streaming Response

This interface also supports streaming responses; setting the stream parameter to true will provide a step-by-step return effect, which is very suitable for implementing word-by-word display on web pages.

Python Example

import requests

url = "https://api.acedata.cloud/v1/messages"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}

payload = {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "stream": True,
    "messages": [
        {"role": "user", "content": "Hello, Claude"}
    ]
}

response = requests.post(url, json=payload, headers=headers, stream=True)
for line in response.iter_lines():
    if line:
        print(line.decode("utf-8"))

Streamed responses are returned in Server-Sent Events (SSE) format, with each line prefixed by event: and data:. The types of streamed events include:

  • message_start: Message start, containing basic information about the message and model name.
  • content_block_start: Content block start.
  • content_block_delta: Incremental update of the content block, containing newly generated text segments.
  • content_block_stop: Content block end.
  • message_delta: Message-level incremental update, containing stop_reason and final usage information.
  • message_stop: Message end.

The output looks like this:

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

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":"Hi"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"! My name is"}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Claude. How can I help you today?"}}

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":15}}

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

As can be seen, the content_block_delta events in the streamed response contain the progressively generated text content, and by concatenating all text_delta, the complete reply can be obtained.

JavaScript Example

const options = {
  method: "POST",
  headers: {
    accept: "application/json",
    authorization: "Bearer {token}",
    "content-type": "application/json",
  },
  body: JSON.stringify({
    model: "claude-sonnet-4-20250514",
    max_tokens: 1024,
    stream: true,
    messages: [{ role: "user", content: "Hello, Claude" }],
  }),
};

const response = await fetch("https://api.acedata.cloud/v1/messages", options);
const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(decoder.decode(value));
}

Multi-turn Conversations

If you want to integrate multi-turn conversation functionality, you need to alternate the messages of user and assistant roles in the messages array, passing in the previous conversation history as well.

Python Example

import requests

url = "https://api.acedata.cloud/v1/messages"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}

payload = {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "messages": [
        {"role": "user", "content": "Hello, my name is Alice."},
        {"role": "assistant", "content": "Hello Alice! Nice to meet you. How can I help you today?"},
        {"role": "user", "content": "What is my name?"}
    ]
}

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

The returned result is as follows:

{
  "id": "msg_01Y1wfQmd89g968TVbFu57Yc",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Your name is Alice, as you just told me!"
    }
  ],
  "model": "claude-sonnet-4-20250514",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 40,
    "output_tokens": 14
  }
}

By passing the complete conversation history in messages, Claude can provide accurate responses based on the context.

Deep Thinking Model

Claude's thinking and thinking summary are two different concepts: the model can perform internal reasoning, but the API does not return the raw thought chain. When the reasoning process needs to be displayed, the API returns a processed summary.

The current model recommends using adaptive thinking and controlling the overall reasoning effort through output_config.effort:

import requests

url = "https://api.acedata.cloud/v1/messages"
headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}
payload = {
    "model": "claude-opus-5",
    "max_tokens": 16000,
    "thinking": {
        "type": "adaptive",
        "display": "summarized"
    },
    "output_config": {
        "effort": "high"
    },
    "messages": [
        {"role": "user", "content": "What is the sine of 30 degrees?"}
    ]
}

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

The thinking block in the response looks like:

{
  "type": "thinking",
  "thinking": "The problem asks for a standard trigonometric value...",
  "signature": "opaque-signature"
}
  • display: "summarized" returns a readable summary of the thought; it is not the raw thought chain.
  • display: "omitted" returns thinking: "", but still retains the opaque signature to support subsequent conversations.
  • The default value for display in Fable 5, Opus 5, Sonnet 5, Opus 4.8, and Opus 4.7 is omitted; Opus 4.6, Sonnet 4.6, and earlier models that support thinking default to using summarized.
  • Display only affects the returned content and streaming delay, does not disable reasoning, nor reduce the billing of thinking tokens.
  • Whether thinking is enabled by default and the default value of display are two independent issues. Opus 5 and Sonnet 5 default to enabling adaptive thinking; Opus 4.8, 4.7, and 4.6 need to be explicitly enabled.
  • budget_tokens is only used for older models that still support fixed thinking budgets. New models should use thinking.type=adaptive and output_config.effort.
  • In multi-turn conversations and tool calls, the complete thinking block and signature returned by the assistant should be passed back unchanged; do not modify or generate the signature yourself.
  • Some compatible routes cannot handle redacted_thinking or explicitly disable thinking without loss, in which case a parameter error will be returned, rather than silently discarding or changing the request semantics.

In streamed requests, summarized will produce thinking_delta; omitted does not produce thinking_delta, only retaining the lifecycle of the thinking block and signature_delta.

Visual Model

Claude supports multimodal input and can handle both text and images simultaneously. In the Messages API, you can use visual capabilities by setting content to an array format and passing in image content blocks.

Using Base64 Encoded Images

import base64
import requests

url = "https://api.acedata.cloud/v1/messages"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}

# Read and encode image
with open("image.png", "rb") as f:
    image_data = base64.standard_b64encode(f.read()).decode("utf-8")

payload = {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/png",
                        "data": image_data
                    }
                },
                {
                    "type": "text",
                    "text": "What's in this image?"
                }
            ]
        }
    ]
}

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

Using URL Image

import requests

url = "https://api.acedata.cloud/v1/messages"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}

payload = {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "messages": [
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "url",
                        "url": "https://cdn.acedata.cloud/ueugot.png"
                    }
                },
                {
                    "type": "text",
                    "text": "What's in this image?"
                }
            ]
        }
    ]
}

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

cURL Example

curl -X POST 'https://api.acedata.cloud/v1/messages' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer {token}' \
  -H 'content-type: application/json' \
  -d '{
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "image",
            "source": {
              "type": "url",
              "url": "https://cdn.acedata.cloud/ueugot.png"
            }
          },
          {
            "type": "text",
            "text": "What'\''s in this image?"
          }
        ]
      }
    ]
  }'

Supported image formats include: image/jpeg, image/png, image/gif, image/webp.

Documents and PDF

PDF uses document content block, supporting both Base64 and URL stable sources. Base64 source must use application/pdf:

import base64

with open("report.pdf", "rb") as f:
    pdf_data = base64.standard_b64encode(f.read()).decode("utf-8")

payload = {
    "model": "claude-opus-4-8",
    "max_tokens": 1024,
    "messages": [{
        "role": "user",
        "content": [
            {
                "type": "document",
                "source": {
                    "type": "base64",
                    "media_type": "application/pdf",
                    "data": pdf_data
                },
                "title": "Quarterly report"
            },
            {"type": "text", "text": "Summarize this PDF."}
        ]
    }]
}

URL source is written as {"type":"url","url":"https://example.com/report.pdf"}. document also supports text/plain and content sources composed of text/image blocks; optional fields include title, context, and citations. The file_id source of the Files API is a separate beta feature and is not within the stable contract of this interface.

Prompt Caching

The top-level cache_control will automatically place the cache breakpoint at the last cacheable block:

payload = {
    "model": "claude-opus-4-8",
    "max_tokens": 1024,
    "cache_control": {"type": "ephemeral", "ttl": "5m"},
    "system": "You are an expert on this reference material.",
    "messages": [{"role": "user", "content": "Summarize the key points."}]
}

When precise control over the position is needed, the same cache_control can also be written on text, image, document, tool_use, tool_result content blocks or tool definitions. ttl supports 5m (default) and 1h; please check usage.cache_creation_input_tokens and usage.cache_read_input_tokens to determine cache writes and hits.

Example of return result:

{
  "id": "msg_01NCrxpZmV17bhQJJRQEFEb9",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "This image shows an API request configuration interface for what appears to be an AI chat completion service. The interface includes parameters for model selection, messages, stream mode, and max tokens settings."
    }
  ],
  "model": "claude-sonnet-4-20250514",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 1570,
    "output_tokens": 52
  }
}

Tool Invocation (Tool Use)

The Claude Messages API natively supports tool invocation functionality, allowing the model to call your predefined tools/functions when needed.

Python Example

import requests

url = "https://api.acedata.cloud/v1/messages"

headers = {
    "accept": "application/json",
    "authorization": "Bearer {token}",
    "content-type": "application/json"
}

payload = {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "tools": [
        {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    }
                },
                "required": ["location"]
            }
        }
    ],
    "messages": [
        {"role": "user", "content": "What's the weather like in San Francisco?"}
    ]
}

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

When the model decides to call a tool, the content in the return result will include a tool_use type content block:

{
  "id": "msg_01Aq9w938a90dw8q",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Let me check the weather in San Francisco for you."
    },
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lgs",
      "name": "get_weather",
      "input": {
        "location": "San Francisco, CA"
      }
    }
  ],
  "model": "claude-sonnet-4-20250514",
  "stop_reason": "tool_use",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 120,
    "output_tokens": 68
  }
}

Note that the stop_reason is tool_use, indicating that the model needs to call a tool. Upon receiving this result, you need to execute the tool function and return the result in the form of tool_result to the model:

payload = {
    "model": "claude-sonnet-4-20250514",
    "max_tokens": 1024,
    "tools": [
        {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    }
                },
                "required": ["location"]
            }
        }
    ],
    "messages": [
        {"role": "user", "content": "What's the weather like in San Francisco?"},
        {
            "role": "assistant",
            "content": [
                {"type": "text", "text": "Let me check the weather in San Francisco for you."},
                {"type": "tool_use", "id": "toolu_01A09q90qw90lq917835lgs", "name": "get_weather", "input": {"location": "San Francisco, CA"}}
            ]
        },
        {
            "role": "user",
            "content": [
                {
                    "type": "tool_result",
                    "tool_use_id": "toolu_01A09q90qw90lq917835lgs",
                    "content": "Sunny, 72°F"
                }
            ]
        }
    ]
}

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

The model will generate the final natural language reply based on the results returned by the tool.

Differences with Chat Completion API

辰汐ai provides two formats of the Claude API, with the main differences as follows:

The usage.input_tokens of the Messages API only represents uncached input, while cache_read_input_tokens and cache_creation_input_tokens are billed independently; all three will be calculated at their corresponding prices.

Feature Messages API (/v1/messages) Chat Completion API (/v1/chat/completions)
Format Anthropic native format OpenAI compatible format
System prompt Independent system field Passed through role: "system" in messages
Response structure content array (supports multiple types) choices array (contains message)
Streaming format SSE events (multiple event types) SSE data lines
Deep thinking Native thinking parameter Triggered by special model names (e.g., -thinking suffix)
Tool invocation Native tools + input_schema OpenAI compatible functions format
Token statistics input_tokens / output_tokens prompt_tokens / completion_tokens

If your system is already integrated with the OpenAI format API, you can use the Chat Completion API for a seamless switch. If you need to utilize all of Claude's native capabilities, it is recommended to use the Messages API.

Error Handling

The error responses from the public interface use the 辰汐ai platform envelope: error.code is a stable error code, error.message is an explanation, and trace_id is used for troubleshooting requests. Common HTTP statuses include:

  • 400: Invalid request parameters or protocol content.
  • 401: Invalid, missing, or expired authorization token.
  • 403: Forbidden access, insufficient balance, or quota limits.
  • 404: API or model does not exist.
  • 413: Request body too large.
  • 429: Too many requests.
  • 500 / 503 / 504: Service error, temporarily unavailable, or processing timeout.

Error Response Example

{
  "error": {
    "code": "api_error",
    "message": "fetch failed"
  },
  "trace_id": "2cf86e86-22a4-46e1-ac2f-032c0f2a4e89"
}

This error structure is the runtime contract of 辰汐ai and does not equate to the official Anthropic error envelope; please handle according to HTTP status and error.code.

Conclusion

Through this document, you have learned how to use the Claude Messages API to call Claude's conversational capabilities in the Anthropic native format. The Messages API supports a rich set of features including basic conversation, system prompts, streaming responses, multi-turn dialogues, deep thinking, visual understanding, PDF, prompt caching, and tool invocation. If you have any questions, please feel free to contact our technical support team.