Messages
curl --request POST \
--url https://openp.ai/v1/messagesimport requests
url = "https://openp.ai/v1/messages"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://openp.ai/v1/messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://openp.ai/v1/messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://openp.ai/v1/messages"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openp.ai/v1/messages")
.asString();require 'uri'
require 'net/http'
url = URI("https://openp.ai/v1/messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyClaude Messages
Messages
POST /v1/messages — the Claude native protocol endpoint
POST
/
v1
/
messages
Messages
curl --request POST \
--url https://openp.ai/v1/messagesimport requests
url = "https://openp.ai/v1/messages"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://openp.ai/v1/messages', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://openp.ai/v1/messages",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://openp.ai/v1/messages"
req, _ := http.NewRequest("POST", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://openp.ai/v1/messages")
.asString();require 'uri'
require 'net/http'
url = URI("https://openp.ai/v1/messages")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_bodyThe Claude native protocol endpoint, fully compatible with Anthropic’s official API, with advanced features not in the OpenAI protocol such as
The response includes an extra
See Reasoning & thinking.
See Cache billing.
Or base64:
The assistant content in the response includes a
Return the execution result via a user message:
cache_control and thinking.
Request
curl https://openp.ai/v1/messages \
-H "x-api-key: $OPENPAI_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4-8",
"max_tokens": 1024,
"system": "You are a Python engineer",
"messages": [
{"role": "user", "content": "Write an LRU Cache in Python"}
]
}'
Headers
| Header | Required | Description |
|---|---|---|
x-api-key | ✅ | The sk- key issued by OpenPAI |
anthropic-version | ✅ | API version, currently 2023-06-01 |
anthropic-beta | Experimental features, e.g. prompt-caching-2024-07-31 | |
Content-Type | ✅ | application/json |
Body fields
| Field | Type | Required | Description |
|---|---|---|---|
model | string | ✅ | Claude model ID |
messages | array | ✅ | Conversation history; role must alternate user / assistant |
max_tokens | integer | ✅ | Maximum output tokens |
system | string | array | System prompt; array form can carry cache_control | |
temperature | number | 0-1 | |
top_p | number | ||
top_k | integer | ||
stop_sequences | array | Stop sequences | |
stream | boolean | SSE stream | |
tools | array | Tool definitions | |
tool_choice | object | {type:"auto"} / {type:"any"} / {type:"tool",name:"x"} | |
thinking | object | { type:"enabled", budget_tokens: 8000 } | |
metadata | object | { user_id: "..." } |
content structure
Claude’scontent can be a string or a block array. Block types:
text— plain textimage— image (source.typeisbase64orurl)tool_use— a model-initiated tool call (assistant message)tool_result— a tool’s returned result (user message)thinking— a thinking block (thinking-mode response)document— documents like PDF
Response
{
"id": "msg_01...",
"type": "message",
"role": "assistant",
"model": "claude-opus-4-8",
"content": [
{"type": "text", "text": "Sure, here's an LRU Cache implementation..."}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 24,
"output_tokens": 256,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0
}
}
stop_reason: end_turn / max_tokens / stop_sequence / tool_use.
Streaming response
Withstream: true, events are pushed as SSE:
event: message_start
data: {"type":"message_start","message":{"id":"msg_...","role":"assistant","content":[],...}}
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":"He"}}
event: content_block_stop
data: {"type":"content_block_stop","index":0}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":256}}
event: message_stop
data: {"type":"message_stop"}
Thinking mode
claude-sonnet-4-6 and claude-haiku-4-5 use extended thinking (thinking + budget_tokens); claude-opus-4-8 uses adaptive thinking (effort, defaults to high):
{
"model": "claude-sonnet-4-6",
"max_tokens": 4096,
"thinking": { "type": "enabled", "budget_tokens": 8000 },
"messages": [{"role": "user", "content": "Prove Goldbach's conjecture"}]
}
{
"model": "claude-opus-4-8",
"max_tokens": 4096,
"effort": "high",
"messages": [{"role": "user", "content": "Prove Goldbach's conjecture"}]
}
thinking block:
{
"content": [
{"type": "thinking", "thinking": "<internal chain of thought>"},
{"type": "text", "text": "<final answer>"}
]
}
Prompt caching
{
"model": "claude-opus-4-8",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "<long 50000-char system prompt>",
"cache_control": { "type": "ephemeral" }
}
],
"messages": [{"role": "user", "content": "..."}]
}
Vision
{
"model": "claude-opus-4-8",
"max_tokens": 1024,
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{"type": "image", "source": {
"type": "url",
"url": "https://example.com/cat.png"
}}
]
}]
}
{"type": "image", "source": {
"type": "base64",
"media_type": "image/png",
"data": "<base64>"
}}
Tools
{
"model": "claude-opus-4-8",
"max_tokens": 1024,
"tools": [{
"name": "get_weather",
"description": "Get weather",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}],
"messages": [{"role": "user", "content": "Weather in Shanghai"}]
}
tool_use block:
{
"content": [{
"type": "tool_use",
"id": "toolu_01...",
"name": "get_weather",
"input": {"city": "Shanghai"}
}],
"stop_reason": "tool_use"
}
{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": "toolu_01...",
"content": "Shanghai is 26°C and clear today"
}]
}