Other Official SDKs Basics
8 examples to get you started with the other official Claude SDKs - 5 basic and 3 intermediate.
Search across all documentation pages
8 examples to get you started with the other official Claude SDKs - 5 basic and 3 intermediate.
ANTHROPIC_API_KEY environment variable.go get, Maven/Gradle, NuGet, Composer, or Bundler).The simplest possible Messages API call using anthropic-sdk-go.
package main
import (
"context"
"fmt"
"os"
"github.com/anthropics/anthropic-sdk-go"
"github.com/anthropics/anthropic-sdk-go/option"
)
func main() {
client := anthropic.NewClient(
option.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")),
)
message, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeSonnet5,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Say hello in one sentence.")),
},
})
if err != nil {
panic(err)
}
fmt.Println(message.Content[0].Text)
}anthropic.NewClient reads no config beyond the API key option; there's no separate "connect" step.error value, not an exception, so check err before touching message.message.Content is a slice of content blocks; a plain text reply is Content[0].Text.Related: Calling Claude from Go with the Official SDK - streaming and tool_use in Go
The same call using the Java SDK's builder-style client.
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
public class FirstCall {
public static void main(String[] args) {
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_SONNET_5)
.maxTokens(1024)
.addUserMessage("Say hello in one sentence.")
.build();
Message message = client.messages().create(params);
System.out.println(message.content().get(0).text().get());
}
}AnthropicOkHttpClient.fromEnv() reads ANTHROPIC_API_KEY from the environment automatically.MessageCreateParams.builder() is Java's idiomatic way to assemble a request with optional fields.The same call using the C# SDK's typed request object and async/await.
using Anthropic.SDK;
using Anthropic.SDK.Messaging;
var client = new AnthropicClient(Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY"));
var response = await client.Messages.GetClaudeMessageAsync(new MessageParameters
{
Model = AnthropicModels.ClaudeSonnet5,
MaxTokens = 1024,
Messages = new List<Message>
{
new Message(RoleType.User, "Say hello in one sentence.")
}
});
Console.WriteLine(response.Message);GetClaudeMessageAsync follows .NET's async convention, so it must be awaited inside an async context.MessageParameters mirrors the Messages API request body field-for-field, just as a typed C# object.The same call using PHP's associative-array request style.
<?php
require 'vendor/autoload.php';
use Anthropic\Anthropic;
$client = Anthropic::factory()
->withApiKey(getenv('ANTHROPIC_API_KEY'))
->make();
$response = $client->messages()->create([
'model' => 'claude-sonnet-5',
'max_tokens' => 1024,
'messages' => [
['role' => 'user', 'content' => 'Say hello in one sentence.'],
],
]);
echo $response->content[0]->text;Anthropic::factory() is a fluent builder; withApiKey() and make() produce the configured client.max_token) fails at request time, not before.The same call using Ruby's hash-based request style.
require "anthropic"
client = Anthropic::Client.new(api_key: ENV["ANTHROPIC_API_KEY"])
response = client.messages.create(
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [
{ role: "user", content: "Say hello in one sentence." }
]
)
puts response.content[0].textAnthropic::Client.new takes the API key directly as a keyword argument.Every SDK returns the same underlying fields; this example reads more of them.
message, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeSonnet5,
MaxTokens: 256,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Name three Go standard library packages.")),
},
})
if err != nil {
panic(err)
}
fmt.Println("Stop reason:", message.StopReason)
fmt.Println("Input tokens:", message.Usage.InputTokens)
fmt.Println("Output tokens:", message.Usage.OutputTokens)
for _, block := range message.Content {
if block.Type == "text" {
fmt.Println(block.Text)
}
}StopReason tells you why generation stopped: end_turn, max_tokens, tool_use, and so on - check it before assuming the reply is complete.Usage carries token counts for both sides of the exchange, which every SDK exposes in some typed or dictionary form.Content is always a list of blocks even for a single text reply, because the same field also carries tool_use blocks.Related: Messages API Basics - the request/response shape every SDK wraps
The system parameter behaves identically everywhere; only the syntax to set it changes.
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_SONNET_5)
.maxTokens(512)
.system("You are a terse, technical code reviewer. Answer in bullet points only.")
.addUserMessage("Review this function signature: func Add(a, b int) int")
.build();
Message message = client.messages().create(params);
System.out.println(message.content().get(0).text().get());response = client.messages.create(
model: "claude-sonnet-5",
max_tokens: 512,
system: "You are a terse, technical code reviewer. Answer in bullet points only.",
messages: [
{ role: "user", content: "Review this function signature: func Add(a, b int) int" }
]
)system field is a top-level request parameter in every SDK, never a message in the messages array.The same rate-limit failure, handled the way each language expects.
message, err := client.Messages.New(ctx, params)
if err != nil {
var apiErr *anthropic.Error
if errors.As(err, &apiErr) && apiErr.StatusCode == 429 {
fmt.Println("Rate limited, back off and retry.")
return
}
panic(err)
}try
{
var response = await client.Messages.GetClaudeMessageAsync(parameters);
}
catch (RateLimitException)
{
Console.WriteLine("Rate limited, back off and retry.");
}errors.As, matching Go's no-exceptions convention.Related: Idiomatic Tool Use Across Go, Java, C#, PHP, and Ruby - the same cross-language comparison, applied to tool_use
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the current official SDKs for Go, Java, C#, PHP, and Ruby. Model names, SDK versions, and pricing move quickly - verify current specifics at platform.claude.com/docs before relying on them.
Reviewed by Chris St. John·Last updated Jul 19, 2026