Claude API basics

This module provides native support for Anthropic’s Claude API within the sttp-ai library. Unlike OpenAI compatibility layers, this provides direct access to Claude’s unique features and API structure.

Claude features

Sync and async clients

  • ClaudeSyncClient — high-level and blocking: methods return the response directly and throw a ClaudeException subclass on error. The recommended default, used in most examples in these docs. Create it with ClaudeSyncClient.fromEnv (reads ANTHROPIC_API_KEY) or ClaudeSyncClient(config); call close() when done.

  • ClaudeClient — returns raw sttp-client4 Requests and parses responses as Either[ClaudeException, A]. Pair it with the sttp backend of your choice (cats-effect, ZIO, Akka/Pekko, Ox).

Basic usage

//> using dep com.softwaremill.sttp.ai::claude:0.11.0

import sttp.ai.claude.ClaudeSyncClient
import sttp.ai.claude.models.{ClaudeModel, ContentBlock, Message}
import sttp.ai.claude.requests.MessageRequest

object Main:
  def main(args: Array[String]): Unit =
    val claude = ClaudeSyncClient.fromEnv // reads ANTHROPIC_API_KEY
    try {
      val request = MessageRequest.simple(
        model = ClaudeModel.ClaudeHaiku4_5.value,
        messages = List(Message.user("Hello Claude! What's the weather like today?")),
        maxTokens = 500
      )

      // Throws a ClaudeException subclass on error
      val response = claude.createMessage(request)

      response.content.foreach {
        case ContentBlock.Text(text, _, _) => println(text)
        case _                             => () // other content block types
      }
      println(s"Usage: ${response.usage}")
    } finally claude.close()

Async usage

For non-blocking code, use ClaudeClient with an sttp backend of your choice:

//> using dep com.softwaremill.sttp.ai::claude:0.11.0

import sttp.ai.claude.*
import sttp.ai.claude.config.ClaudeConfig
import sttp.ai.claude.models.{ClaudeModel, 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 = ClaudeModel.ClaudeHaiku4_5.value,  // 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()

The example above uses the synchronous sttp backend for brevity, but ClaudeClient works with any sttp4 backend — cats-effect, ZIO, Akka/Pekko, Ox, etc. — by swapping the backend and calling .send(backend) in the corresponding effect.

Key differences from OpenAI:

  • Uses ContentBlock instead 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-haiku-4-5-20251001)

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 = 10.minutes,                   // Request timeout
  maxRetries: Int = 3,                             // Max retry attempts, honored by ClaudeSyncClient
  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)

Next steps: see Messages API for conversations, images, and advanced parameters, Tool calling and Structured outputs for advanced request features, Streaming for SSE support, and Models and error handling for the models API and exception hierarchy.