Skip to content

ClaudeClient

Viames Marino edited this page Apr 25, 2026 · 1 revision

Pair framework: ClaudeClient

Pair\Services\ClaudeClient is a lightweight HTTP client for Anthropic's Claude Messages API.

It focuses on the integration paths Pair applications need most often:

  • Messages API calls for text, tool-capable, and multimodal model responses
  • stateless chat helpers that accept user, assistant, and system message roles
  • text extraction from Claude content blocks

The Pair core does not require an Anthropic SDK. The client uses cURL and keeps the provider dependency optional.

Configuration

CLAUDE_API_KEY=
CLAUDE_API_BASE_URL="https://api.anthropic.com/v1"
CLAUDE_MESSAGES_MODEL=claude-sonnet-4-5
CLAUDE_API_VERSION=2023-06-01
CLAUDE_MAX_TOKENS=1024
CLAUDE_TIMEOUT=30
CLAUDE_CONNECT_TIMEOUT=5

Keys:

  • CLAUDE_API_KEY is required before outbound API calls.
  • CLAUDE_API_BASE_URL defaults to the Claude REST API base URL.
  • CLAUDE_MESSAGES_MODEL is the default model for /messages.
  • CLAUDE_API_VERSION sets the required anthropic-version request header.
  • CLAUDE_MAX_TOKENS is the default output cap when callers omit max_tokens.

Extension path

Pair v4 integrations should be registered explicitly. An application can expose Claude as the AI adapter:

use Pair\Core\AdapterKeys;
use Pair\Core\Application;
use Pair\Services\ClaudeClient;

$app = Application::getInstance();
$app->setAdapter(AdapterKeys::AI, new ClaudeClient());

$ai = $app->adapter(AdapterKeys::AI, ClaudeClient::class);

This keeps Claude optional and avoids automatic package discovery.

Constructor

__construct(?string $apiKey = null, ?string $apiBaseUrl = null, ?string $messagesModel = null, ?string $apiVersion = null, ?int $maxTokens = null, ?int $timeout = null, ?int $connectTimeout = null)

Creates the client with explicit values or Env defaults.

Main methods

  • apiKeySet(): bool
  • createMessage(array $messages, array $options = []): array
  • createTextMessage(array $messages, array $options = []): string
  • createTextResponse(string $input, array $options = []): string
  • extractText(array $response): string

Messages API

Use createMessage() when the caller needs the full Claude response.

use Pair\Http\JsonResponse;
use Pair\Services\ClaudeClient;

$client = new ClaudeClient();

$response = $client->createMessage([
	['role' => 'user', 'content' => 'Summarize this support ticket.'],
], [
	'system' => 'Return concise Italian text.',
	'max_tokens' => 300,
]);

return new JsonResponse([
	'id' => $response['id'] ?? null,
	'text' => ClaudeClient::extractText($response),
]);

Use createTextResponse() for the common single-prompt case:

use Pair\Services\ClaudeClient;

$client = new ClaudeClient();

$summary = $client->createTextResponse('Summarize this CRM note.', [
	'system' => 'Return one sentence.',
]);

Chat

The Claude Messages API is stateless. Store conversation state in the Pair application and send the relevant history on each turn.

use Pair\Services\ClaudeClient;

$client = new ClaudeClient();

$answer = $client->createTextMessage([
	['role' => 'system', 'content' => 'You answer in Italian.'],
	['role' => 'user', 'content' => 'Ciao, chi sei?'],
]);

system messages are lifted into the top-level Claude system field. user and assistant messages remain in the transcript.

Embeddings

Claude does not expose an Anthropic-native embedding model. Anthropic documentation recommends using Voyage AI or another embedding provider for retrieval use cases. Pair therefore keeps embeddings out of ClaudeClient.

Safe Logging

Do not log raw prompts, uploaded files, model outputs, tool outputs, or chat transcripts by default.

Prefer logging operational metadata only:

  • endpoint or feature name
  • selected model
  • request duration
  • token usage from the API response
  • project-side entity IDs such as ticket_id or document_id
  • error code and sanitized error message

Operational Notes

  • Keep CLAUDE_API_KEY in .env, never in Git.
  • Keep provider-specific domain mapping in project services, not controllers.
  • Store chatbot history in project-owned tables when the application needs memory.
  • For semantic search, use OpenAI, Gemini, Voyage AI, or another embedding provider separately from Claude.

Claude References

See also: API, Integrations, AdapterRegistry, JsonResponse, OpenAIClient, GeminiClient.

Clone this wiki locally