curl https://api.apimart.ai/v1/messages \
-H "x-api-key: $API_KEY" \
-H "anthropic-version: 2025-10-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello, world"}
]
}'
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.apimart.ai"
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Hello, world"}
]
)
print(message.content)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: process.env.API_KEY,
baseURL: 'https://api.apimart.ai'
});
const message = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'Hello, world' }
]
});
console.log(message.content);
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
)
func main() {
url := "https://api.apimart.ai/v1/messages"
payload := map[string]interface{}{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": []map[string]string{
{
"role": "user",
"content": "Hello, world",
},
},
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("x-api-key", os.Getenv("API_KEY"))
req.Header.Set("anthropic-version", "2025-10-01")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
String url = "https://api.apimart.ai/v1/messages";
String apiKey = System.getenv("API_KEY");
String payload = """
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Hello, world"
}
]
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("x-api-key", apiKey)
.header("anthropic-version", "2025-10-01")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$url = "https://api.apimart.ai/v1/messages";
$apiKey = getenv('API_KEY');
$payload = [
"model" => "claude-sonnet-4-6",
"max_tokens" => 1024,
"messages" => [
[
"role" => "user",
"content" => "Hello, world"
]
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"x-api-key: " . $apiKey,
"anthropic-version: 2025-10-01",
"Content-Type: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
require 'net/http'
require 'json'
require 'uri'
url = URI("https://api.apimart.ai/v1/messages")
api_key = ENV['API_KEY']
payload = {
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [
{
role: "user",
content: "Hello, world"
}
]
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = api_key
request["anthropic-version"] = "2025-10-01"
request["Content-Type"] = "application/json"
request.body = payload.to_json
response = http.request(request)
puts response.body
import Foundation
let url = URL(string: "https://api.apimart.ai/v1/messages")!
let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? ""
let payload: [String: Any] = [
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
[
"role": "user",
"content": "Hello, world"
]
]
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue(apiKey, forHTTPHeaderField: "x-api-key")
request.setValue("2025-10-01", forHTTPHeaderField: "anthropic-version")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
}
}
task.resume()
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var url = "https://api.apimart.ai/v1/messages";
var apiKey = Environment.GetEnvironmentVariable("API_KEY");
var payload = @"{
""model"": ""claude-sonnet-4-6"",
""max_tokens"": 1024,
""messages"": [
{
""role"": ""user"",
""content"": ""Hello, world""
}
]
}";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", apiKey);
client.DefaultRequestHeaders.Add("anthropic-version", "2025-10-01");
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}
#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
int main(void) {
CURL *curl;
CURLcode res;
const char *api_key = getenv("API_KEY");
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
const char *url = "https://api.apimart.ai/v1/messages";
const char *payload = "{"
"\"model\":\"claude-sonnet-4-6\","
"\"max_tokens\":1024,"
"\"messages\":[{\"role\":\"user\",\"content\":\"Hello, world\"}]"
"}";
char auth_header[256];
snprintf(auth_header, sizeof(auth_header), "x-api-key: %s", api_key);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, auth_header);
headers = curl_slist_append(headers, "anthropic-version: 2025-10-01");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSURL *url = [NSURL URLWithString:@"https://api.apimart.ai/v1/messages"];
NSString *apiKey = [NSProcessInfo processInfo].environment[@"API_KEY"];
NSDictionary *payload = @{
@"model": @"claude-sonnet-4-6",
@"max_tokens": @1024,
@"messages": @[
@{
@"role": @"user",
@"content": @"Hello, world"
}
]
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload
options:0
error:&error];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:apiKey forHTTPHeaderField:@"x-api-key"];
[request setValue:@"2025-10-01" forHTTPHeaderField:@"anthropic-version"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:jsonData];
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
return;
}
NSString *result = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"%@", result);
}];
[task resume];
[[NSRunLoop mainRunLoop] run];
}
return 0;
}
(* Requires cohttp and yojson libraries *)
open Lwt
open Cohttp
open Cohttp_lwt_unix
let url = "https://api.apimart.ai/v1/messages"
let api_key = Sys.getenv "API_KEY"
let payload = {|{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Hello, world"
}
]
}|}
let () =
let headers = Header.init ()
|> fun h -> Header.add h "x-api-key" api_key
|> fun h -> Header.add h "anthropic-version" "2025-10-01"
|> fun h -> Header.add h "Content-Type" "application/json"
in
let body = Cohttp_lwt.Body.of_string payload in
let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) ->
body |> Cohttp_lwt.Body.to_string >|= fun body_str ->
print_endline body_str
in
Lwt_main.run response
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
void main() async {
final url = Uri.parse('https://api.apimart.ai/v1/messages');
final apiKey = Platform.environment['API_KEY'];
final payload = {
'model': 'claude-sonnet-4-6',
'max_tokens': 1024,
'messages': [
{
'role': 'user',
'content': 'Hello, world'
}
]
};
final response = await http.post(
url,
headers: {
'x-api-key': apiKey!,
'anthropic-version': '2025-10-01',
'Content-Type': 'application/json',
},
body: jsonEncode(payload),
);
print(response.body);
}
library(httr)
library(jsonlite)
url <- "https://api.apimart.ai/v1/messages"
api_key <- Sys.getenv("API_KEY")
payload <- list(
model = "claude-sonnet-4-6",
max_tokens = 1024,
messages = list(
list(
role = "user",
content = "Hello, world"
)
)
)
response <- POST(
url,
add_headers(
`x-api-key` = api_key,
`anthropic-version` = "2025-10-01",
`Content-Type` = "application/json"
),
body = toJSON(payload, auto_unbox = TRUE),
encode = "raw"
)
cat(content(response, "text"))
{
"model": "claude-sonnet-4-6",
"id": "msg_011CdfeHuC728oxqaLrRNbcB",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "Hello! I'm Claude. Nice to meet you."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"stop_details": null,
"usage": {
"input_tokens": 12,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"cache_creation": {
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 0
},
"output_tokens": 18,
"service_tier": "standard",
"inference_geo": "global"
}
}
{
"error": {
"code": "model_not_found",
"message": "model not found (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Invalid API key (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Insufficient balance (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Too many requests (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Internal server error (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
Serie de texto
API de Mensajes Claude
- Totalmente compatible con el protocolo nativo Anthropic Claude Messages (
POST /v1/messages) - Admite conversaciones de múltiples turnos, streaming SSE, llamadas a herramientas y extended thinking
- Admite contenido multimodal con texto e imágenes
- Respuesta retransmitida tal cual desde el upstream, sin envoltorio
{code, data}
POST
/
v1
/
messages
curl https://api.apimart.ai/v1/messages \
-H "x-api-key: $API_KEY" \
-H "anthropic-version: 2025-10-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello, world"}
]
}'
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.apimart.ai"
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Hello, world"}
]
)
print(message.content)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: process.env.API_KEY,
baseURL: 'https://api.apimart.ai'
});
const message = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'Hello, world' }
]
});
console.log(message.content);
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
)
func main() {
url := "https://api.apimart.ai/v1/messages"
payload := map[string]interface{}{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": []map[string]string{
{
"role": "user",
"content": "Hello, world",
},
},
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("x-api-key", os.Getenv("API_KEY"))
req.Header.Set("anthropic-version", "2025-10-01")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
String url = "https://api.apimart.ai/v1/messages";
String apiKey = System.getenv("API_KEY");
String payload = """
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Hello, world"
}
]
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("x-api-key", apiKey)
.header("anthropic-version", "2025-10-01")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$url = "https://api.apimart.ai/v1/messages";
$apiKey = getenv('API_KEY');
$payload = [
"model" => "claude-sonnet-4-6",
"max_tokens" => 1024,
"messages" => [
[
"role" => "user",
"content" => "Hello, world"
]
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"x-api-key: " . $apiKey,
"anthropic-version: 2025-10-01",
"Content-Type: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
require 'net/http'
require 'json'
require 'uri'
url = URI("https://api.apimart.ai/v1/messages")
api_key = ENV['API_KEY']
payload = {
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [
{
role: "user",
content: "Hello, world"
}
]
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = api_key
request["anthropic-version"] = "2025-10-01"
request["Content-Type"] = "application/json"
request.body = payload.to_json
response = http.request(request)
puts response.body
import Foundation
let url = URL(string: "https://api.apimart.ai/v1/messages")!
let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? ""
let payload: [String: Any] = [
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
[
"role": "user",
"content": "Hello, world"
]
]
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue(apiKey, forHTTPHeaderField: "x-api-key")
request.setValue("2025-10-01", forHTTPHeaderField: "anthropic-version")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
}
}
task.resume()
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var url = "https://api.apimart.ai/v1/messages";
var apiKey = Environment.GetEnvironmentVariable("API_KEY");
var payload = @"{
""model"": ""claude-sonnet-4-6"",
""max_tokens"": 1024,
""messages"": [
{
""role"": ""user"",
""content"": ""Hello, world""
}
]
}";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", apiKey);
client.DefaultRequestHeaders.Add("anthropic-version", "2025-10-01");
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}
#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
int main(void) {
CURL *curl;
CURLcode res;
const char *api_key = getenv("API_KEY");
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
const char *url = "https://api.apimart.ai/v1/messages";
const char *payload = "{"
"\"model\":\"claude-sonnet-4-6\","
"\"max_tokens\":1024,"
"\"messages\":[{\"role\":\"user\",\"content\":\"Hello, world\"}]"
"}";
char auth_header[256];
snprintf(auth_header, sizeof(auth_header), "x-api-key: %s", api_key);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, auth_header);
headers = curl_slist_append(headers, "anthropic-version: 2025-10-01");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSURL *url = [NSURL URLWithString:@"https://api.apimart.ai/v1/messages"];
NSString *apiKey = [NSProcessInfo processInfo].environment[@"API_KEY"];
NSDictionary *payload = @{
@"model": @"claude-sonnet-4-6",
@"max_tokens": @1024,
@"messages": @[
@{
@"role": @"user",
@"content": @"Hello, world"
}
]
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload
options:0
error:&error];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:apiKey forHTTPHeaderField:@"x-api-key"];
[request setValue:@"2025-10-01" forHTTPHeaderField:@"anthropic-version"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:jsonData];
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
return;
}
NSString *result = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"%@", result);
}];
[task resume];
[[NSRunLoop mainRunLoop] run];
}
return 0;
}
(* Requires cohttp and yojson libraries *)
open Lwt
open Cohttp
open Cohttp_lwt_unix
let url = "https://api.apimart.ai/v1/messages"
let api_key = Sys.getenv "API_KEY"
let payload = {|{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Hello, world"
}
]
}|}
let () =
let headers = Header.init ()
|> fun h -> Header.add h "x-api-key" api_key
|> fun h -> Header.add h "anthropic-version" "2025-10-01"
|> fun h -> Header.add h "Content-Type" "application/json"
in
let body = Cohttp_lwt.Body.of_string payload in
let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) ->
body |> Cohttp_lwt.Body.to_string >|= fun body_str ->
print_endline body_str
in
Lwt_main.run response
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
void main() async {
final url = Uri.parse('https://api.apimart.ai/v1/messages');
final apiKey = Platform.environment['API_KEY'];
final payload = {
'model': 'claude-sonnet-4-6',
'max_tokens': 1024,
'messages': [
{
'role': 'user',
'content': 'Hello, world'
}
]
};
final response = await http.post(
url,
headers: {
'x-api-key': apiKey!,
'anthropic-version': '2025-10-01',
'Content-Type': 'application/json',
},
body: jsonEncode(payload),
);
print(response.body);
}
library(httr)
library(jsonlite)
url <- "https://api.apimart.ai/v1/messages"
api_key <- Sys.getenv("API_KEY")
payload <- list(
model = "claude-sonnet-4-6",
max_tokens = 1024,
messages = list(
list(
role = "user",
content = "Hello, world"
)
)
)
response <- POST(
url,
add_headers(
`x-api-key` = api_key,
`anthropic-version` = "2025-10-01",
`Content-Type` = "application/json"
),
body = toJSON(payload, auto_unbox = TRUE),
encode = "raw"
)
cat(content(response, "text"))
{
"model": "claude-sonnet-4-6",
"id": "msg_011CdfeHuC728oxqaLrRNbcB",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "Hello! I'm Claude. Nice to meet you."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"stop_details": null,
"usage": {
"input_tokens": 12,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"cache_creation": {
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 0
},
"output_tokens": 18,
"service_tier": "standard",
"inference_geo": "global"
}
}
{
"error": {
"code": "model_not_found",
"message": "model not found (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Invalid API key (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Insufficient balance (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Too many requests (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Internal server error (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
No mezcle las dos API:
/v1/* es la API de inferencia (este documento — retransmisión del upstream sin envoltorio); /api/* es la API de gestión (saldo/registros, etc., respuesta {success, message, data}). Si ve en algún lugar que /v1/messages devuelve {code, data}, prevalece este documento.curl https://api.apimart.ai/v1/messages \
-H "x-api-key: $API_KEY" \
-H "anthropic-version: 2025-10-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello, world"}
]
}'
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.apimart.ai"
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Hello, world"}
]
)
print(message.content)
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: process.env.API_KEY,
baseURL: 'https://api.apimart.ai'
});
const message = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'Hello, world' }
]
});
console.log(message.content);
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
)
func main() {
url := "https://api.apimart.ai/v1/messages"
payload := map[string]interface{}{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": []map[string]string{
{
"role": "user",
"content": "Hello, world",
},
},
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("x-api-key", os.Getenv("API_KEY"))
req.Header.Set("anthropic-version", "2025-10-01")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class Main {
public static void main(String[] args) throws Exception {
String url = "https://api.apimart.ai/v1/messages";
String apiKey = System.getenv("API_KEY");
String payload = """
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Hello, world"
}
]
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("x-api-key", apiKey)
.header("anthropic-version", "2025-10-01")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$url = "https://api.apimart.ai/v1/messages";
$apiKey = getenv('API_KEY');
$payload = [
"model" => "claude-sonnet-4-6",
"max_tokens" => 1024,
"messages" => [
[
"role" => "user",
"content" => "Hello, world"
]
]
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"x-api-key: " . $apiKey,
"anthropic-version: 2025-10-01",
"Content-Type: application/json"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
require 'net/http'
require 'json'
require 'uri'
url = URI("https://api.apimart.ai/v1/messages")
api_key = ENV['API_KEY']
payload = {
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [
{
role: "user",
content: "Hello, world"
}
]
}
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = api_key
request["anthropic-version"] = "2025-10-01"
request["Content-Type"] = "application/json"
request.body = payload.to_json
response = http.request(request)
puts response.body
import Foundation
let url = URL(string: "https://api.apimart.ai/v1/messages")!
let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? ""
let payload: [String: Any] = [
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
[
"role": "user",
"content": "Hello, world"
]
]
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue(apiKey, forHTTPHeaderField: "x-api-key")
request.setValue("2025-10-01", forHTTPHeaderField: "anthropic-version")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: payload)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print(responseString)
}
}
task.resume()
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var url = "https://api.apimart.ai/v1/messages";
var apiKey = Environment.GetEnvironmentVariable("API_KEY");
var payload = @"{
""model"": ""claude-sonnet-4-6"",
""max_tokens"": 1024,
""messages"": [
{
""role"": ""user"",
""content"": ""Hello, world""
}
]
}";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", apiKey);
client.DefaultRequestHeaders.Add("anthropic-version", "2025-10-01");
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
}
#include <stdio.h>
#include <curl/curl.h>
#include <stdlib.h>
int main(void) {
CURL *curl;
CURLcode res;
const char *api_key = getenv("API_KEY");
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
const char *url = "https://api.apimart.ai/v1/messages";
const char *payload = "{"
"\"model\":\"claude-sonnet-4-6\","
"\"max_tokens\":1024,"
"\"messages\":[{\"role\":\"user\",\"content\":\"Hello, world\"}]"
"}";
char auth_header[256];
snprintf(auth_header, sizeof(auth_header), "x-api-key: %s", api_key);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, auth_header);
headers = curl_slist_append(headers, "anthropic-version: 2025-10-01");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSURL *url = [NSURL URLWithString:@"https://api.apimart.ai/v1/messages"];
NSString *apiKey = [NSProcessInfo processInfo].environment[@"API_KEY"];
NSDictionary *payload = @{
@"model": @"claude-sonnet-4-6",
@"max_tokens": @1024,
@"messages": @[
@{
@"role": @"user",
@"content": @"Hello, world"
}
]
};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:payload
options:0
error:&error];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:apiKey forHTTPHeaderField:@"x-api-key"];
[request setValue:@"2025-10-01" forHTTPHeaderField:@"anthropic-version"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:jsonData];
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
return;
}
NSString *result = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"%@", result);
}];
[task resume];
[[NSRunLoop mainRunLoop] run];
}
return 0;
}
(* Requires cohttp and yojson libraries *)
open Lwt
open Cohttp
open Cohttp_lwt_unix
let url = "https://api.apimart.ai/v1/messages"
let api_key = Sys.getenv "API_KEY"
let payload = {|{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Hello, world"
}
]
}|}
let () =
let headers = Header.init ()
|> fun h -> Header.add h "x-api-key" api_key
|> fun h -> Header.add h "anthropic-version" "2025-10-01"
|> fun h -> Header.add h "Content-Type" "application/json"
in
let body = Cohttp_lwt.Body.of_string payload in
let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) ->
body |> Cohttp_lwt.Body.to_string >|= fun body_str ->
print_endline body_str
in
Lwt_main.run response
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
void main() async {
final url = Uri.parse('https://api.apimart.ai/v1/messages');
final apiKey = Platform.environment['API_KEY'];
final payload = {
'model': 'claude-sonnet-4-6',
'max_tokens': 1024,
'messages': [
{
'role': 'user',
'content': 'Hello, world'
}
]
};
final response = await http.post(
url,
headers: {
'x-api-key': apiKey!,
'anthropic-version': '2025-10-01',
'Content-Type': 'application/json',
},
body: jsonEncode(payload),
);
print(response.body);
}
library(httr)
library(jsonlite)
url <- "https://api.apimart.ai/v1/messages"
api_key <- Sys.getenv("API_KEY")
payload <- list(
model = "claude-sonnet-4-6",
max_tokens = 1024,
messages = list(
list(
role = "user",
content = "Hello, world"
)
)
)
response <- POST(
url,
add_headers(
`x-api-key` = api_key,
`anthropic-version` = "2025-10-01",
`Content-Type` = "application/json"
),
body = toJSON(payload, auto_unbox = TRUE),
encode = "raw"
)
cat(content(response, "text"))
{
"model": "claude-sonnet-4-6",
"id": "msg_011CdfeHuC728oxqaLrRNbcB",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "Hello! I'm Claude. Nice to meet you."
}
],
"stop_reason": "end_turn",
"stop_sequence": null,
"stop_details": null,
"usage": {
"input_tokens": 12,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"cache_creation": {
"ephemeral_5m_input_tokens": 0,
"ephemeral_1h_input_tokens": 0
},
"output_tokens": 18,
"service_tier": "standard",
"inference_geo": "global"
}
}
{
"error": {
"code": "model_not_found",
"message": "model not found (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Invalid API key (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Insufficient balance (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Too many requests (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
{
"error": {
"code": "",
"message": "Internal server error (request id: 20260803181903172761862QzohKPXF)",
"param": "",
"type": "apimart_error"
}
}
Autorizaciones
La autenticación admite dos métodos; elija uno:string
Encabezado de autenticación al estilo AnthropicVisite la página de gestión de API Keys para obtener su API Key
x-api-key: YOUR_API_KEY
string
Autenticación Bearer Token (alternativa a
x-api-key)Authorization: Bearer YOUR_API_KEY
string
Número de versión de la API (opcional; la solicitud funciona también sin él)Para facilitar la migración futura a los endpoints oficiales de Anthropic, se recomienda incluirlo:Ejemplo:
2025-10-01Body
string
predeterminado:"claude-sonnet-4-6"
requerido
Model name
claude-opus-4-8- Claude Opus 4.8 flagship modelclaude-opus-4-7- Claude Opus 4.7 flagship modelclaude-opus-4-6- Claude Opus 4.6 flagship modelclaude-sonnet-4-6- Claude Sonnet 4.6 balanced versionclaude-opus-4-5-20251101- Claude Opus 4.5 model
array
requerido
Lista de mensajesArray de mensajes para que el modelo genere la siguiente respuesta. Cada mensaje contiene los campos
Mensaje único del usuario:Conversación de múltiples turnos:Respuesta del asistente con prefijado:
role y content.💡 Relleno rápido (área Try it):- Haga clic en ”+ Add an item” para agregar un mensaje
- Entrada de
role:user(mensaje del usuario) oassistant(respuesta de la IA, para conversaciones de múltiples turnos) - Entrada de
content: el texto de su mensaje
Mostrar Detalles de los campos
Mostrar Detalles de los campos
string
predeterminado:"user"
requerido
Tipo de rolOpciones:
user (mensaje del usuario), assistant (respuesta de la IA, para conversaciones de múltiples turnos y prefijado)Nota: La API de Claude utiliza un parámetro system independiente para los prompts del sistema, no dentro de messagesstring
requerido
Contenido del mensajeContenido textual del mensaje
[{"role": "user", "content": "Hello, Claude"}]
[
{"role": "user", "content": "Hello there."},
{"role": "assistant", "content": "Hi, I'm Claude. How can I help you?"},
{"role": "user", "content": "Can you explain LLMs in plain English?"}
]
[
{"role": "user", "content": "What's the Greek name for Sun? (A) Sol (B) Helios (C) Sun"},
{"role": "assistant", "content": "The best answer is ("}
]
integer
requerido
Tokens máximos a generar (obligatorio, alineado con la API oficial de Anthropic)Número máximo de tokens a generar antes de detenerse. El modelo puede detenerse antes de alcanzar este límite.Los distintos modelos tienen valores máximos diferentes; consulte la documentación del modelo. Mínimo: 1
object
Configuración de extended thinkingAl activarlo, la respuesta
content puede incluir bloques thinking. Recomendado: usar el nombre de modelo estándar + este parámetro, en lugar de los alias de modelo -thinking del lado de la plataforma, para migrar a los endpoints oficiales sin cambiar el código.En conversaciones multi-turno que deban reenviar bloques thinking, debe devolver tal cual el signature; de lo contrario, el upstream rechazará la solicitud.string | array
Prompt del sistemaLos prompts del sistema definen el rol, la personalidad, los objetivos y las instrucciones de Claude.Formato cadena:Formato estructurado:
{
"system": "You are a professional Python programming tutor"
}
{
"system": [
{
"type": "text",
"text": "You are a professional Python programming tutor"
}
]
}
number
Parámetro de temperatura, rango 0-1Controla la aleatoriedad de la salida:
- Valores bajos (por ejemplo, 0.2): Más determinístico, conservador
- Valores altos (por ejemplo, 0.8): Más aleatorio, creativo
number
Parámetro de muestreo por núcleo (nucleus sampling), rango 0-1Utiliza muestreo por núcleo. Se recomienda usar
temperature o top_p, no ambos.Valor por defecto: 1.0integer
Muestreo Top-KMuestrea solo a partir de las K opciones más probables; elimina las respuestas de “cola larga” con baja probabilidad.Recomendado solo para casos de uso avanzados.
boolean
Habilitar streamingCuando es
true, utiliza Server-Sent Events (SSE) para transmitir las respuestas en streaming.Valor por defecto: falsearray
Secuencias de paradaSecuencias de texto personalizadas que hacen que el modelo deje de generar.Máximo 4 secuencias.Ejemplo:
["\n\nHuman:", "\n\nAssistant:"]object
MetadatosObjeto de metadatos para la solicitud.Incluye:
user_id: Identificador del usuario
array
Definiciones de herramientasLista de herramientas que el modelo puede usar para completar tareas.Ejemplo de herramienta de función:Tipos de herramientas admitidas:
{
"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"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit"
}
},
"required": ["location"]
}
}
]
}
- Herramientas de función personalizadas
- Herramienta de uso del ordenador (computer_20241022)
- Herramienta de editor de texto (text_editor_20241022)
- Herramienta Bash (bash_20241022)
object
Estrategia de elección de herramientaControla cómo el modelo utiliza las herramientas:
{"type": "auto"}: Decisión automática (por defecto){"type": "any"}: Debe usar una herramienta{"type": "tool", "name": "tool_name"}: Usar una herramienta específica
Respuesta
string
Identificador único del mensajeEjemplo:
"msg_013Zva2CMHLNnXjNJJKqJ2EF"string
Tipo de objetoSiempre
"message"string
RolSiempre
"assistant"array
Array de bloques de contenidoBloque tool_use:Bloque thinking (aparece cuando el cuerpo de la solicitud incluye el parámetro
content distingue los tipos de bloque mediante type. Una sola respuesta puede contener varios bloques (por ejemplo thinking + text cuando thinking está activado).Bloque text:{ "type": "text", "text": "OK" }
{
"type": "tool_use",
"id": "toolu_01QgsazxKXSfQVj9Q1XxjYXo",
"name": "get_weather",
"input": { "city": "Beijing" },
"caller": { "type": "direct" }
}
caller es un campo nuevo del upstream, aún no recogido en la documentación oficial; ignórelo al analizar.thinking):{
"type": "thinking",
"thinking": "推理过程文本...",
"signature": "<约 500+ 字符的签名串>"
}
En conversaciones multi-turno, al reenviar bloques thinking debe devolver tal cual el
signature; de lo contrario, el upstream rechazará la solicitud.No asuma que
content[0] es texto. Con thinking activado, content[0] puede ser un bloque thinking. Recorra y filtre:text = "".join(b.text for b in resp.content if b.type == "text")
string
Modelo que procesó la solicitudEjemplo:
"claude-sonnet-4-6"string
Motivo de paradaValores posibles:
end_turn: Finalización naturalmax_tokens: Se alcanzó el máximo de tokensstop_sequence: Se encontró una secuencia de paradatool_use: Invocó una herramienta
string | null
Secuencia de parada activadaLa secuencia de parada que se generó, si la hay; en caso contrario,
nullobject | null
Campo más reciente de Anthropic;
null en solicitudes habitualesobject
Estadísticas de uso de tokens (estructura completa no stream)
Mostrar Propiedades
Mostrar Propiedades
integer
Número de tokens de entrada
integer
Número de tokens de salida (ya incluye thinking tokens; no los sume de nuevo para facturación)
integer
Tokens de escritura en caché
integer
Tokens de lectura en caché (hit)
object
{ ephemeral_5m_input_tokens, ephemeral_1h_input_tokens }string
Por ejemplo
"standard"string
Por ejemplo
"global"object
Puede aparecer con thinking activado:
{ thinking_tokens: int }Ejemplos de uso
Conversación básica
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.apimart.ai"
)
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explain quantum computing basics"}
]
)
print(message.content[0].text)
Conversación de múltiples turnos
messages = [
{"role": "user", "content": "What is machine learning?"},
{"role": "assistant", "content": "Machine learning is a branch of AI..."},
{"role": "user", "content": "Can you give a practical example?"}
]
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages
)
Uso de prompts del sistema
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="You are a senior Python developer expert in code review and optimization.",
messages=[
{"role": "user", "content": "How to optimize this code?\n\n[code]"}
]
)
Respuesta en streaming
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Write a short essay about AI"}
]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Uso de herramientas
tools = [
{
"name": "get_stock_price",
"description": "Get real-time stock price",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol, e.g., AAPL"
}
},
"required": ["ticker"]
}
}
]
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "What's Tesla's stock price?"}
]
)
# Handle tool calls
if message.stop_reason == "tool_use":
tool_use = next(block for block in message.content if block.type == "tool_use")
print(f"Calling tool: {tool_use.name}")
print(f"Arguments: {tool_use.input}")
Comprensión visual
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/image.jpg"
}
},
{
"type": "text",
"text": "Describe this image"
}
]
}
]
)
Imagen en Base64
import base64
with open("image.jpg", "rb") as image_file:
image_data = base64.b64encode(image_file.read()).decode("utf-8")
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_data
}
},
{
"type": "text",
"text": "Analyze this image"
}
]
}
]
)
Buenas prácticas
1. Ingeniería de prompts
Definición clara del rol:system = """You are an experienced data scientist specializing in:
- Statistical analysis and data visualization
- Machine learning model development
- Python and R programming
Provide professional, accurate advice."""
message = "Please return the analysis results in JSON format with summary, key_findings, and recommendations fields."
2. Manejo de errores
from anthropic import APIError, RateLimitError
try:
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}]
)
except RateLimitError:
print("Rate limit exceeded, please retry later")
except APIError as e:
print(f"API error: {e}")
3. Optimización de tokens
# Use shorter prompts
messages = [
{"role": "user", "content": "Summarize key points:\n\n[long text]"}
]
# Limit output length
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=500, # Limit output
messages=messages
)
4. Prefijado de respuestas
# Guide model to specific format
messages = [
{"role": "user", "content": "List 5 Python best practices"},
{"role": "assistant", "content": "Here are 5 Python best practices:\n\n1."}
]
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages
)
Manejo de respuestas en streaming
Streaming con Python
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_API_KEY",
base_url="https://api.apimart.ai"
)
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Write a Python decorator example"}
]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Streaming con JavaScript
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
apiKey: process.env.API_KEY,
baseURL: 'https://api.apimart.ai'
});
const stream = await client.messages.stream({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [
{ role: 'user', content: 'Write a React component example' }
]
});
for await (const chunk of stream) {
if (chunk.type === 'content_block_delta' &&
chunk.delta.type === 'text_delta') {
process.stdout.write(chunk.delta.text);
}
}
Diferencias de la plataforma y puntos de integración
Respuesta sin envoltorio
En caso de éxito,POST /v1/messages devuelve directamente el objeto message de Anthropic, sin envoltorio {code, data}. Así, los SDK oficiales, Claude Code, Cline, etc. siguen siendo compatibles 1:1.
Formato de error (única diferencia sustancial respecto al oficial)
{
"error": {
"code": "model_not_found",
"message": "... (request id: ...)",
"param": "",
"type": "apimart_error"
}
}
"type": "error"; error.type es fijo en apimart_error, y no tipos semánticos como invalid_request_error.
Recomendación de integración: no base la lógica de reintento en error.type; use el código de estado HTTP + error.code:
| Código de estado | Significado | Acción recomendada |
|---|---|---|
| 400 | Parámetros de solicitud no válidos | No reintentar; comprobar el cuerpo de la solicitud |
| 401 | Clave no válida | No reintentar |
| 402 | Saldo insuficiente | No reintentar; indicar recarga |
| 429 | Limitación de tasa | Reintentar tras backoff |
| 5xx | Anomalía en upstream/gateway | Reintentar con backoff exponencial |
error.message, y el encabezado de respuesta x-oneapi-request-id.
Streaming SSE
Añada"stream": true a la solicitud. La secuencia de eventos es idéntica a la oficial:
message_start → content_block_start → ping → content_block_delta (varias veces) → content_block_stop → message_delta → message_stop
⚠️ La estructura de usage difiere entre stream y no stream: message_delta.usage suele tener solo 4 campos de tokens, sin cache_creation, service_tier, inference_geo. Analícelos por separado o trate todos los campos como opcionales.
Endpoint no implementado
POST /v1/messages/count_tokens no está implementado y devuelve 404. La llamada client.messages.count_tokens() del SDK oficial fallará. Para estimar tokens, hágalo en local o lea usage.input_tokens en la respuesta.
Ignorar campos desconocidos
Esta API retransmite el upstream tal cual; Anthropic puede añadir campos en cualquier momento (p. ej.stop_details, inference_geo, caller, output_tokens_details). No active un esquema estricto:
- Go: no use
DisallowUnknownFields() - Pydantic: no use
extra="forbid" - TypeScript / Zod: use
.passthrough()en lugar de.strict()
Recomendación de nombres de modelo
Los modelos homónimos con el sufijo-thinking son alias de extensión de la plataforma. Recomendado: usar el nombre de modelo estándar sin sufijo + el parámetro thinking en el cuerpo de la solicitud, para facilitar la migración a los endpoints oficiales.
Los demás campos del cuerpo de la solicitud están alineados con el oficial: model, messages, max_tokens (obligatorio), system, temperature, top_p, top_k, stop_sequences, stream, tools, tool_choice, thinking, metadata. La semántica sigue la Messages API de Anthropic.
Notas importantes
-
Seguridad de la API Key:
- Almacene las API keys en variables de entorno
- Nunca codifique las claves directamente en el código fuente
- Rote las claves periódicamente
-
Límites de tasa:
- Tenga en cuenta los límites de tasa de la API
- Implemente mecanismos de reintento (según el código de estado HTTP)
- Use retroceso exponencial (exponential backoff)
-
Gestión de tokens:
- Monitoree el uso de tokens (lea
usage) - Optimice la longitud de los prompts
- Use valores adecuados de
max_tokens - Con thinking activado,
output_tokensya incluye el thinking; no facture por duplicado
- Monitoree el uso de tokens (lea
-
Selección del modelo:
- Opus: Tareas complejas que requieren razonamiento profundo
- Sonnet: Rendimiento y costo equilibrados
- Haiku: Respuesta rápida, tareas sencillas
-
Análisis del contenido:
- Recorra
contentbuscando bloquestype == "text"; no fijecontent[0].text - Si el modelo devuelve JSON envuelto en un bloque de código Markdown, es salida del modelo y no un envoltorio de la API (vea la FAQ más abajo)
- Recorra
-
Filtrado de contenido:
- Valide la entrada del usuario
- Filtre información sensible
- Implemente moderación de contenido
FAQ
El text de content es un bloque de código ```json ... ``` — ¿cómo quitarlo?
No es un problema de estructura de la API. El campo text contiene el contenido bruto generado por el modelo: si el modelo deduce que quiere JSON, a menudo lo envuelve en un bloque de código Markdown. La API no reescribe (ni debe reescribir) la salida del modelo.
Para obtener datos estructurados limpios, hay tres enfoques correctos (del más fiable al menos):
- Usar tools para forzar salida estructurada — el más fiable; el campo
inputya es un objeto parseado:
{
"tools": [{
"name": "emit_result",
"input_schema": {
"type": "object",
"properties": { "answer": { "type": "string" } }
}
}],
"tool_choice": { "type": "tool", "name": "emit_result" }
}
- Prefill el mensaje del assistant, para que el modelo continúe desde
{:
{
"messages": [
{ "role": "user", "content": "..." },
{ "role": "assistant", "content": "{" }
]
}
- Exigir en el system prompt: «emita solo JSON, sin bloque de código Markdown».