Models, errors and the sync client
Claude Models API
val modelsRequest = client.listModels()
val models = modelsRequest.send(backend)
models match {
case Right(response) =>
response.data.foreach(model => println(s"${model.id} - ${model.displayName.getOrElse("N/A")}"))
case Left(error) =>
println(s"Error: $error")
}
Common Claude models (use listModels() for current list):
claude-3-sonnet-20240229- Balanced performance and speedclaude-3-opus-20240229- Highest capability modelclaude-3-haiku-20240307- Fastest modelclaude-instant-1.2- Legacy fast model
Claude Error Handling
Claude-specific exception hierarchy:
import sttp.ai.claude.ClaudeExceptions.*
client.createMessage(request).send(backend) match {
case Right(response) => // Success
handleResponse(response)
case Left(error) => error match {
case _: AuthenticationException => // Invalid API key
println("Authentication failed - check your API key")
case _: RateLimitException => // Rate limited
println("Rate limited - please wait before retrying")
case _: InvalidRequestException => // Malformed request
println("Invalid request - check your parameters")
case _: PermissionException => // Access denied
println("Permission denied for this resource")
case _: APIException => // Other API error
println(s"API error: ${error.getMessage}")
case _: DeserializationClaudeException => // JSON parsing error
println("Failed to parse response")
}
}
Key Differences from OpenAI API
Feature |
Claude API |
OpenAI API |
|---|---|---|
Message Content |
|
Simple strings |
System Messages |
|
Role-based message |
Authentication |
|
|
Image Input |
ContentBlock with base64 |
URL or base64 in content |
Tool Calling |
Native tool structure |
Function calling |
Streaming |
Server-Sent Events |
Server-Sent Events |
Model Names |
|
|
Synchronous Claude Client
For blocking operations, use ClaudeSyncClient:
import sttp.ai.claude.ClaudeSyncClient
val syncClient = new ClaudeSyncClient(config)
// Throws ClaudeException on error
try {
val response = syncClient.createMessage(request)
println(response.content.head.text.getOrElse(""))
} catch {
case e: ClaudeException => println(s"Error: ${e.getMessage}")
}