# Messages

**Package:** Anthropic Laravel | **Version:** 1 | **URL:** https://mozex.dev/docs/anthropic-laravel/v1/usage/messages

---

The Messages API is the primary way to interact with Claude. Send messages using the `Anthropic` Facade and get back typed response objects.

## Creating a message

```php
use Anthropic\Laravel\Facades\Anthropic;

$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'messages' => [
        ['role' => 'user', 'content' => 'Hello, world'],
    ],
]);
```

The response is a `CreateResponse` object with typed properties:

```php
$response->id;            // 'msg_01BSy0WCV7QR2adFBauynAX7'
$response->model;         // 'claude-sonnet-4-6'
$response->stop_reason;   // 'end_turn'
$response->content[0]->text; // 'Hello! How can I assist you today?'

$response->usage->inputTokens;  // 10
$response->usage->outputTokens; // 19
```

## Multi-turn conversations

The Anthropic API is stateless, so you pass the full conversation history on every request:

```php
$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'messages' => [
        ['role' => 'user', 'content' => 'What is PHP?'],
        ['role' => 'assistant', 'content' => 'PHP is a server-side scripting language...'],
        ['role' => 'user', 'content' => 'What version should I use?'],
    ],
]);
```

A common Laravel pattern is to store the conversation in a model and build the array from Eloquent:

```php
$messages = $conversation->messages()
    ->latest('id')
    ->take(20)
    ->get()
    ->reverse()
    ->map(fn ($message) => [
        'role' => $message->is_assistant ? 'assistant' : 'user',
        'content' => $message->content,
    ])
    ->toArray();

$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'messages' => $messages,
]);
```

## System messages

Pass instructions, persona, or context through the `system` parameter:

```php
$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'system' => 'You are a helpful PHP expert. Answer concisely.',
    'messages' => [
        ['role' => 'user', 'content' => 'What is the null coalescing operator?'],
    ],
]);
```

The `system` parameter is separate from the `messages` array.

## Vision

Claude can read images alongside text. Pass an array of content blocks instead of a string:

```php
$imagePath = storage_path('app/photos/receipt.jpg');

$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'messages' => [
        [
            'role' => 'user',
            'content' => [
                ['type' => 'text', 'text' => 'What is in this image?'],
                [
                    'type' => 'image',
                    'source' => [
                        'type' => 'base64',
                        'media_type' => 'image/jpeg',
                        'data' => base64_encode(file_get_contents($imagePath)),
                    ],
                ],
            ],
        ],
    ],
]);
```

Supported media types are `image/jpeg`, `image/png`, `image/gif`, and `image/webp`.

### Images from Laravel Storage

If you're using Laravel's Storage facade, read the file and encode it inline:

```php
use Illuminate\Support\Facades\Storage;

$file = Storage::disk('s3')->get('uploads/photo.jpg');
$mimeType = Storage::disk('s3')->mimeType('uploads/photo.jpg');

$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'messages' => [
        [
            'role' => 'user',
            'content' => [
                ['type' => 'text', 'text' => 'Describe this photo.'],
                [
                    'type' => 'image',
                    'source' => [
                        'type' => 'base64',
                        'media_type' => $mimeType,
                        'data' => base64_encode($file),
                    ],
                ],
            ],
        ],
    ],
]);
```

You can also pass images by URL:

```php
[
    'type' => 'image',
    'source' => ['type' => 'url', 'url' => 'https://example.com/photo.jpg'],
]
```

## Tracking users

Pass a `metadata.user_id` with each request to associate it with a user in your app. The ID shows up in the Anthropic Console for analytics and abuse detection:

```php
$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'metadata' => [
        'user_id' => auth()->user()->uuid,
    ],
    'messages' => [
        ['role' => 'user', 'content' => 'Hello!'],
    ],
]);
```

Use an opaque identifier (UUID, hash). Don't send names or email addresses.

## Long-running requests in queues

Message requests that use extended thinking, code execution, or large contexts can take 30+ seconds. In Laravel, push them to a queue so they don't block the request:

```php
class AskClaudeJob implements ShouldQueue
{
    public function __construct(public string $question, public int $userId) {}

    public function handle(): void
    {
        $response = Anthropic::messages()->create([
            'model' => 'claude-sonnet-4-6',
            'max_tokens' => 4096,
            'metadata' => ['user_id' => (string) $this->userId],
            'messages' => [
                ['role' => 'user', 'content' => $this->question],
            ],
        ]);

        Answer::create([
            'user_id' => $this->userId,
            'content' => $response->content[0]->text,
        ]);
    }
}
```

Bump `ANTHROPIC_REQUEST_TIMEOUT` in your `.env` to match the expected response time so the HTTP client doesn't cut the request short.

## Handling refusals

When safety classifiers block a response, `stop_reason` comes back as `'refusal'` and `stop_details` explains why. The response is still a valid 200, so handle it like any branch in your controller or job:

```php
$response = Anthropic::messages()->create([...]);

if ($response->stop_reason === 'refusal') {
    Log::warning('Claude refused request', [
        'user_id' => auth()->id(),
        'category' => $response->stop_details->category,    // 'cyber', 'bio', or null
        'explanation' => $response->stop_details->explanation,
    ]);

    return back()->with('error', 'Your request could not be processed.');
}
```

`stop_details` is `null` on normal completions, so only touch it when `stop_reason === 'refusal'`. Treat `category` as the machine-readable signal; the `explanation` text isn't stable between calls.

## The `pause_turn` stop reason

Long-running turns can come back as `stop_reason: 'pause_turn'` instead of `'end_turn'`. Send the response back as the next assistant message to let Claude continue. This fits naturally in a queued job:

```php
class ContinueClaudeJob implements ShouldQueue
{
    public function handle(): void
    {
        $messages = $this->conversation->messagesArray();

        do {
            $response = Anthropic::messages()->create([
                'model' => 'claude-sonnet-4-6',
                'max_tokens' => 8192,
                'messages' => $messages,
            ]);

            $messages[] = [
                'role' => 'assistant',
                'content' => array_map(fn ($block) => $block->toArray(), $response->content),
            ];
        } while ($response->stop_reason === 'pause_turn');

        $this->conversation->persistFinalResponse($response);
    }
}
```

No special parameter is needed to resume; just echo the paused content back.

## Inference region

`usage->inferenceGeo` tells you which region handled the request, useful for residency logs or regional routing decisions:

```php
$response->usage->inferenceGeo; // 'us', 'eu', or null
```

## Passing any parameter

This package doesn't validate or transform request parameters. Anything you pass in the array goes directly to the Anthropic API. New API parameters work immediately, before the package adds explicit support:

```php
$response = Anthropic::messages()->create([
    'model' => 'claude-sonnet-4-6',
    'max_tokens' => 1024,
    'temperature' => 0.7,
    'top_p' => 0.9,
    'stop_sequences' => ['```'],
    'messages' => [
        ['role' => 'user', 'content' => 'Write a haiku about PHP.'],
    ],
]);
```

---

For the full list of parameters, response fields, content block types, and the latest API changes, see the [Messages page in the PHP docs](https://mozex.dev/docs/anthropic-php/v1/usage/messages) or the [Messages API reference](https://platform.claude.com/docs/en/api/messages/create) on the Anthropic docs.

---

## Table of Contents

- [Introduction](https://mozex.dev/docs/anthropic-laravel/v1)
- [AI Integration](https://mozex.dev/docs/anthropic-laravel/v1/ai-integration)
- [Support Us](https://mozex.dev/docs/anthropic-laravel/v1/support-us)
- [Requirements](https://mozex.dev/docs/anthropic-laravel/v1/requirements)
- [Changelog](https://mozex.dev/docs/anthropic-laravel/v1/changelog)
- [Contributing](https://mozex.dev/docs/anthropic-laravel/v1/contributing)
- [Questions & Issues](https://mozex.dev/docs/anthropic-laravel/v1/questions-and-issues)
- [About Mozex](https://mozex.dev/docs/anthropic-laravel/v1/about)

### Usage

- [Messages](https://mozex.dev/docs/anthropic-laravel/v1/usage/messages)
- [Streaming](https://mozex.dev/docs/anthropic-laravel/v1/usage/streaming)
- [Tool Use](https://mozex.dev/docs/anthropic-laravel/v1/usage/tool-use)
- [Thinking](https://mozex.dev/docs/anthropic-laravel/v1/usage/thinking)
- [Server Tools](https://mozex.dev/docs/anthropic-laravel/v1/usage/server-tools)
- [Citations](https://mozex.dev/docs/anthropic-laravel/v1/usage/citations)
- [Token Counting](https://mozex.dev/docs/anthropic-laravel/v1/usage/token-counting)
- [Models](https://mozex.dev/docs/anthropic-laravel/v1/usage/models)
- [Batches](https://mozex.dev/docs/anthropic-laravel/v1/usage/batches)
- [Completions](https://mozex.dev/docs/anthropic-laravel/v1/usage/completions)

### Reference

- [Configuration](https://mozex.dev/docs/anthropic-laravel/v1/reference/configuration)
- [Error Handling](https://mozex.dev/docs/anthropic-laravel/v1/reference/error-handling)
- [Meta Information](https://mozex.dev/docs/anthropic-laravel/v1/reference/meta-information)
- [Testing](https://mozex.dev/docs/anthropic-laravel/v1/reference/testing)