Claude API
This module provides native support for Anthropic’s Claude API within the sttp-openai library. Unlike OpenAI compatibility layers, this provides direct access to Claude’s unique features and API structure.
Claude Features
✅ Native Claude API support - Direct Claude API integration, not compatibility layer
✅ ContentBlock structure - Support for Claude’s rich message content blocks (text, images)
✅ Proper Authentication - Uses
x-api-keyandanthropic-versionheaders✅ Messages API - Complete
/v1/messagesendpoint implementation✅ Models API - List available Claude models via
/v1/models✅ Streaming Support - Server-Sent Events streaming for all effect systems (fs2, ZIO, Akka, Pekko, Ox)
✅ Tool Calling - Native Claude tool calling support
✅ Structured Outputs - Beta support for JSON schema validation (Claude 4.1+ models)
✅ Image Support - Multi-modal inputs via ContentBlock with base64 encoding
✅ Comprehensive Error Handling - Claude-specific exception hierarchy
✅ System Messages - Proper system message handling via
systemparameter✅ Cross-platform - Support for Scala 2.13 and Scala 3
Basic Usage (Claude)
//> using dep com.softwaremill.sttp.ai::claude:0.5.1
import sttp.ai.claude.*
import sttp.ai.claude.config.ClaudeConfig
import sttp.ai.claude.models.{ContentBlock, Message}
import sttp.ai.claude.requests.MessageRequest
import sttp.client4.*
object Main:
def main(args: Array[String]): Unit =
// Create an instance of ClaudeClient using your Anthropic API key
// Set ANTHROPIC_API_KEY environment variable or pass it directly
val config = ClaudeConfig.fromEnv // reads ANTHROPIC_API_KEY
val backend: SyncBackend = DefaultSyncBackend()
val client = ClaudeClient(config)
// Create a simple message
val messages = List(
Message.user(List(ContentBlock.text("Hello Claude! What's the weather like today?")))
)
val request = MessageRequest.simple(
model = "claude-3-haiku-20240307", // Fast, cost-effective model
messages = messages,
maxTokens = 500
)
// Send the request (returns Either[ClaudeException, MessageResponse])
val response = client.createMessage(request).send(backend)
response.body match {
case Right(messageResponse) =>
messageResponse.content.foreach {
case ContentBlock.Text(text, _, _) => println(text)
case _ => // Handle other content types if needed
}
println(s"Usage: ${messageResponse.usage}")
case Left(error) =>
println(s"Claude API Error: ${error.getMessage}")
}
backend.close()
Key differences from OpenAI:
Uses
ContentBlockinstead of simple strings for rich content (text, images)Separate system parameter instead of system role messages
Different authentication headers (
x-api-key+anthropic-version)Native Claude model names (e.g.,
claude-3-haiku-20240307)
Claude Configuration
case class ClaudeConfig(
apiKey: String, // Your Anthropic API key
anthropicVersion: String = "2023-06-01", // API version header
baseUrl: Uri = "https://api.anthropic.com", // API base URL
timeout: Duration = 60.seconds, // Request timeout
maxRetries: Int = 3, // Max retry attempts
organization: Option[String] = None // Optional organization ID
)
Environment Variables:
ANTHROPIC_API_KEY- Your API key (required)ANTHROPIC_VERSION- API version (optional, defaults to “2023-06-01”)ANTHROPIC_BASE_URL- Custom base URL (optional)