Skip to main content
This tutorial shows how to use Claude models through Gloo with the official Anthropic SDKs. You’ll set up the SDK, send a first message, stream a long answer, see Claude’s thinking, run a tool call, and point Claude Code or the Claude Agent SDK at Gloo. Want the concepts first? Read the Anthropic Messages guide.
Why Anthropic Messages? If you already have code written for the Anthropic SDK, you change two lines (the base URL and the key) and it keeps working: the same request body, the same responses and streaming events, and the same error types. It’s a direct endpoint, so you pay the model’s published rate with nothing added.

Prerequisites

Before starting, ensure you have:
  • A Gloo AI Studio account
  • Your API key from the API Keys page, exported as GLOO_API_KEY
  • Authentication setup - Complete the Authentication Tutorial first
  • Python 3 or Node.js, and the Anthropic SDK for your language:

Understanding the endpoint

All requests go to one endpoint: POST /ai/v2/direct/anthropic/v1/messages You don’t type that path yourself. You give the SDK the base URL, and it adds /v1/messages. Like the other direct endpoints, this one applies no guardrails, output moderation or routing: your request goes to the Claude model you name. See the API reference for every request and response field.

Step 1: Set up the client

Create the client with the Gloo base URL and pass your key as the auth token:
Use auth_token (authToken in TypeScript), not api_key. The auth token is sent as Authorization: Bearer, which is where this endpoint reads your key, in every SDK version. SDK versions before Python 2.0 and TypeScript 1.0 send api_key as an x-api-key header instead, and the request returns 401.

Or configure it from the environment

The SDKs also read the base URL and token from environment variables, so you can construct the client with no arguments:
Keep the key in the environment or a secrets manager, never in source code.

Step 2: Send your first message

Understanding the response

The response is an Anthropic message object:
  • content is a list of blocks. Read the text blocks for the answer. On a thinking model you may also see thinking blocks before the text; see Step 4.
  • model is the model ID you sent, whichever form you used.
  • stop_reason says why Claude stopped.
  • usage reports input_tokens, output_tokens, and the prompt caching fields cache_creation_input_tokens and cache_read_input_tokens, as Anthropic defines them.
max_tokens is required. It counts Claude’s thinking as well as the answer, so leave room for both (see Good to know).

Pick a model

Name a Claude model by its Gloo model ID or by Anthropic’s own ID. Both of these call Claude Opus 5.5:
  • gloo-anthropic-claude-opus-5.5
  • claude-opus-5-5
Other current choices are Claude Sonnet 5.5 (gloo-anthropic-claude-sonnet-5.5) and Claude Haiku 5.5 (gloo-anthropic-claude-haiku-5.5). See Supported Models for every Claude model and its rates.

What You’ll See

A two-sentence explanation of prompt caching, the model ID you sent, and a usage summary with input and output token counts.

Step 3: Stream the answer

For long answers, stream. The SDK’s streaming helper prints text as it arrives and still gives you the full message at the end:
The events are Anthropic’s own (message_start, content_block_start, content_block_delta, content_block_stop, message_delta, message_stop and ping), passed through as Claude sends them, so the SDK helpers work unchanged.

How errors arrive on a stream

  • Before the stream starts, a failure is a real HTTP error (429, 529 and so on). Nothing is sent until Claude’s first event arrives, so your SDK can retry it like any other request. You never get an error inside a 200. When someone is waiting, cap those retries as shown in Reading errors.
  • After the stream starts, a failure ends the stream with an event: error, as on Anthropic’s API. The SDK raises it while you iterate.
Once text has reached your user, retrying from scratch can repeat or replace what they’ve already read. Handling Streaming Failures covers when to keep partial output, when to retry and how to tell the user; the same thinking applies here.

When to stream

A non-streaming request with max_tokens above 21,333 returns 400, the same limit the SDKs apply, and long non-streaming requests can time out with 504. Stream anything long.

What You’ll See

The story prints word by word, then the output token count.

Step 4: See Claude’s thinking

Thinking is Claude reasoning through a problem before it answers. On this endpoint you control it with Anthropic’s own parameters, which Gloo sends to Claude as you write them:
  • thinking turns thinking on or off, and display: "summarized" returns a readable summary of it.
  • output_config.effort (low, medium, high, xhigh, max) sets how much effort Claude puts into the response, thinking included.
Gloo’s provider-neutral reasoning settings (reasoning_effort and the reasoning object) are for the Responses and Chat Completions endpoints. They aren’t read here: a reasoning_effort field is listed in the x-gloo-ignored-params response header. Use thinking and output_config.effort on this endpoint.

Ask for a summary of the thinking

Claude Opus 5.5 thinks by default, but you don’t see the thinking unless you ask for it:
With adaptive, Claude decides how much each request needs, and it can decide a request needs no thinking at all. The response then has no thinking block, only the answer, so treat the thinking block as optional when you read the response.

Stream the thinking

When you stream with display: "summarized", the thinking summary arrives before the answer. Read both from the stream’s events:

Turn thinking off, or on

What thinking does by default depends on the model: For the fastest answer on a simple request, turn thinking off on a model that allows it. On an older model, turn it on with a token budget:
The Thinking section of the guide lists which effort levels each model takes. A level the model doesn’t take returns 400.

Good to know about thinking

  • Thinking is billed as output tokens, whether or not you see it. It counts in usage.output_tokens and toward max_tokens.
  • max_tokens above the model’s output limit is lowered to that limit, and the response’s x-gloo-adjusted-params header names the value used, for example max_tokens=128000.
  • Effort is your cost lever. Lower effort means less thinking and fewer output tokens. When More Effort Is Worth It explains when a higher level pays off.

Step 5: Check what Gloo adjusted

Gloo tells you in response headers when it dropped or changed part of your request. The request still runs: Use the SDK’s raw-response helper to read them alongside the parsed message:
Log these during development. An unexpected entry usually means a field name typo or a setting meant for another endpoint, such as reasoning_effort.

Step 6: Call a tool

Tool use lets Claude ask your application to run a function and use the result. Define your own tools in tools exactly as in Anthropic’s API, run the one Claude asks for, and send the result back in a tool_result block. tool_choice is passed through. This example gives Claude a get_service_times tool and loops until Claude answers:

Multi-turn and thinking blocks

You can send Claude’s turns back exactly as the SDK returns them, thinking blocks included, as the loop above does. Gloo doesn’t pass earlier thinking blocks to the model: each new turn starts its own thinking, and the tool loop continues as normal. The x-gloo-ignored-params header then lists messages.thinking; that’s expected, not an error.

Anthropic-defined tools

Web search runs on Anthropic’s servers, so there’s no loop to write. Each search is billed in addition to tokens:
The bash (bash_*) and text editor (text_editor_*) tools are supported too; they run in your application like any tool you define. Other Anthropic-defined tools, such as web fetch, code execution, computer use and the memory tool, return 400 with tool_not_supported.

What You’ll See

Claude calls get_service_times with {"campus": "Downtown"}, your code returns the times, and Claude answers with the 9:00 AM and 11:00 AM services. Claude writes the tool input, so run_tool reads only the campus field it expects and sends an is_error result back when the input doesn’t fit, which lets Claude correct itself. MAX_TURNS stops a loop that never settles.

Step 7: Use Claude Code or the Claude Agent SDK

Claude Code and the Claude Agent SDK are agents built on the Messages API (Coding Agents explains how they work), and they read the same environment variables as the SDKs. Set them before you start a session, and name models by Anthropic’s model IDs:
Then start Claude Code, or run your Agent SDK program, from the same shell. Every request goes through your Gloo organization and is billed at the model’s published rate.
Put the exports in a project-level .envrc or your shell profile so every session picks them up, and keep GLOO_API_KEY itself out of version control.

Complete Example

This script puts the steps together: a message, a stream, thinking, and a tool call, with error handling that branches on the error code Gloo returns.
Run it:

Reading errors

Errors use Anthropic’s error shape, so the SDK raises its usual classes (RateLimitError, InternalServerError and so on) and applies its usual retry rules. Gloo adds a details object:
  • error.message is safe to show your users.
  • error.details.code is the value to branch on.
  • details.developer_message, when present, tells you what to change.
Requests on this endpoint are served by Anthropic only, with no failover to another provider, so retry a 529 rather than treating it as final. The SDKs do this for you: by default they retry twice, honoring retry-after. A 529 can ask for a long wait, and the SDKs wait for as long as retry-after says. When someone is waiting for the answer, follow the retry rule: keep max_retries (maxRetries) at 2 or fewer and set timeout so one stuck attempt can’t hold the screen. To fail fast instead of waiting out a long retry-after, set max_retries to 0 for that call and show error.message. Background jobs can keep the SDK defaults.

Troubleshooting

401 on every request : The key isn’t arriving as Authorization: Bearer. Construct the client with auth_token (authToken), not api_key, or set ANTHROPIC_AUTH_TOKEN. See Step 1. 404 with model_not_available : The model isn’t a Claude model. This endpoint serves Claude only; use Direct Responses for other providers’ models. 404 with model_retired : The Claude model you named is retired. The error message names the model to use instead. Gloo doesn’t switch it for you on this endpoint, because your thinking and effort settings were written for the model you named. 404 with endpoint_not_available : Only POST /v1/messages is served. Token counting (/v1/messages/count_tokens) and the models list (/v1/models) aren’t; use GET /platform/v2/models for the model catalog. Message Batches and the Files API aren’t available either. 400 when max_tokens is large : A non-streaming request with max_tokens above 21,333 returns 400. Stream it (Step 3). 400 with "thinking": {"type": "disabled"} : Claude Opus 5.5 always thinks, so it can’t be turned off; lower output_config.effort to low instead. On Claude Sonnet 5.5, use {"type": "between_tools"}. 400 with "type": "enabled" and budget_tokens : Claude 5 models and Claude Opus 4.7 and 4.8 don’t take a thinking budget. Use {"type": "adaptive"} and output_config.effort. 400 on output_config.effort : The model doesn’t take that level. Claude Haiku 4.5 takes no effort level at all; see Parameters for each model’s levels. 400 when you send temperature, top_p or top_k : Claude 5 models and Claude Opus 4.7 and 4.8 don’t take them, and no model does with anthropic-version: 2026-10-21. Remove them. thinking blocks come back with empty text : Add "display": "summarized" to thinking. Without it, Claude 5 models and Claude Opus 4.7 and 4.8 return thinking blocks with empty text. 400 with tool_not_supported : You included an Anthropic-defined tool that isn’t available here, such as web fetch or code execution. Web search, bash and text editor are supported; define anything else as your own tool. 429 with rate_limit_error : Your organization has too many Messages requests in flight. The response carries retry-after: 1, and the SDKs retry it for you. If the code is spend_limit_reached (with x-should-retry: false), the organization’s spending limit is reached: raise the limit rather than retrying. 504 with timeout_error : A non-streaming request ran too long. Stream it instead. reasoning_effort has no effect : That’s a setting for the Responses and Chat Completions endpoints. Here it’s dropped and listed in x-gloo-ignored-params; use output_config.effort. 413 on a large request : The body is over 10 MB. Send less, or use URL sources for large images and documents.

Next Steps

Anthropic Messages guide

Supported fields, betas, limits, errors and pricing.

API Reference

Every request and response field for Anthropic Messages.

Handling Streaming Failures

Keep partial output, retry safely and tell users what happened.

Prompt Caching

Use cache_control to cut the cost of repeated context.

Models That Think

What thinking is, and when more effort pays off.

Direct Responses

One request shape for every model in the catalog, Claude included.