Fhddos implements the Anthropic Messages API protocol at POST /v1/messages. You can use the official Anthropic Python or TypeScript SDK, any HTTP client, or drop-in replace your existing Anthropic integration by swapping the base URL and API key. No Anthropic account is required — authenticate with your Fhddos token.
Set Up Your Environment
export BASE_URL="https://aiapi.fhddos.com"
export TOKEN="your-fhddos-token"
Endpoint
Basic Text Request
cURL
Python SDK
TypeScript SDK
curl -X POST "$BASE_URL/v1/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Explain the difference between TCP and UDP in plain English."}
]
}'
import os
import anthropic
client = anthropic.Anthropic(
api_key=os.environ["TOKEN"],
base_url=os.environ["BASE_URL"],
)
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explain the difference between TCP and UDP in plain English."}
],
)
print(message.content[0].text)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: process.env.TOKEN!,
baseURL: process.env.BASE_URL!,
});
const message = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [
{ role: "user", content: "Explain the difference between TCP and UDP in plain English." }
],
});
console.log(message.content[0].text);
Key Request Fields
| Field | Type | Required | Description |
|---|
model | string | ✅ | Claude model ID, e.g. claude-sonnet-4-6 |
messages | array | ✅ | Conversation turns — role (user or assistant) and content |
max_tokens | integer | ✅ | Maximum tokens in the response |
system | string | ❌ | System prompt to set Claude’s behavior and persona |
tools | array | ❌ | Function definitions Claude can invoke |
stream | boolean | ❌ | Set true to receive server-sent event chunks |
System Prompt
Pass a system field to define Claude’s role or constraints before the conversation begins:
curl -X POST "$BASE_URL/v1/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 512,
"system": "You are a senior software engineer who gives concise, practical code reviews.",
"messages": [
{"role": "user", "content": "Review this function: def add(a, b): return a + b"}
]
}'
Pass image blocks inside the content array of any user message. Claude accepts base64-encoded data or publicly accessible image URLs:
curl -X POST "$BASE_URL/v1/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "<BASE64_IMAGE_DATA>"
}
},
{
"type": "text",
"text": "Describe the chart in this image and summarise the key trends."
}
]
}]
}'
curl -X POST "$BASE_URL/v1/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/architecture-diagram.png"
}
},
{
"type": "text",
"text": "What services are shown in this architecture diagram and how do they connect?"
}
]
}]
}'
Define tools as JSON schemas in the tools array. Claude will emit a tool_use block in its response when it decides to call a function:
curl -X POST "$BASE_URL/v1/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"tools": [{
"name": "get_weather",
"description": "Get the current weather for a given city",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city name, e.g. London"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit"
}
},
"required": ["city"]
}
}],
"messages": [
{"role": "user", "content": "What is the weather like in Tokyo right now?"}
]
}'
When Claude calls the tool, its response contains a tool_use content block with the function name and parsed input. You then call your function and send the result back in a tool_result block to continue the conversation.
Streaming
Add "stream": true to receive tokens incrementally as server-sent events:
curl -X POST "$BASE_URL/v1/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"stream": true,
"messages": [
{"role": "user", "content": "Write a 200-word short story about a lighthouse keeper."}
]
}'
Each event is a JSON object prefixed with data:. The stream closes with a message_stop event.
Use the Anthropic SDK’s streaming helpers (client.messages.stream(...)) to handle event parsing, tool-use interrupts, and connection errors automatically.
Multi-Turn Conversations
Build a conversation by including all previous turns in the messages array:
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "What is a closure in JavaScript?"},
{"role": "assistant", "content": "A closure is a function that retains access to variables from its enclosing scope even after that scope has finished executing..."},
{"role": "user", "content": "Can you show me a practical example?"}
]
}
Fhddos does not store conversation state between requests. You are responsible for maintaining the messages array and appending each new turn before sending the next request.