Skip to main content
POST
/
v1
/
messages
Messages
curl --request POST \
  --url https://openp.ai/v1/messages
import 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_body
The Claude native protocol endpoint, fully compatible with Anthropic’s official API, with advanced features not in the OpenAI protocol such as 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

HeaderRequiredDescription
x-api-keyThe sk- key issued by OpenPAI
anthropic-versionAPI version, currently 2023-06-01
anthropic-betaExperimental features, e.g. prompt-caching-2024-07-31
Content-Typeapplication/json

Body fields

FieldTypeRequiredDescription
modelstringClaude model ID
messagesarrayConversation history; role must alternate user / assistant
max_tokensintegerMaximum output tokens
systemstring | arraySystem prompt; array form can carry cache_control
temperaturenumber0-1
top_pnumber
top_kinteger
stop_sequencesarrayStop sequences
streambooleanSSE stream
toolsarrayTool definitions
tool_choiceobject{type:"auto"} / {type:"any"} / {type:"tool",name:"x"}
thinkingobject{ type:"enabled", budget_tokens: 8000 }
metadataobject{ user_id: "..." }

content structure

Claude’s content can be a string or a block array. Block types:
  • text — plain text
  • image — image (source.type is base64 or url)
  • 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

With stream: 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"}]
}
The response includes an extra thinking block:
{
  "content": [
    {"type": "thinking", "thinking": "<internal chain of thought>"},
    {"type": "text", "text": "<final answer>"}
  ]
}
See Reasoning & thinking.

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": "..."}]
}
See Cache billing.

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"
      }}
    ]
  }]
}
Or base64:
{"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"}]
}
The assistant content in the response includes a tool_use block:
{
  "content": [{
    "type": "tool_use",
    "id": "toolu_01...",
    "name": "get_weather",
    "input": {"city": "Shanghai"}
  }],
  "stop_reason": "tool_use"
}
Return the execution result via a user message:
{
  "role": "user",
  "content": [{
    "type": "tool_result",
    "tool_use_id": "toolu_01...",
    "content": "Shanghai is 26°C and clear today"
  }]
}