Create the app registration that represents the Claude API audience.
manage-claude/wif-providers/azure
History
manage-claude/wif-providers/azure Changed · +4 / -4 lines
``` <Warning> - Managed identity workloads need `max_jwt_lifetime_seconds: 86400`. Azure issues managed identity tokens with up to 24 hours between `iat` and `exp` because it caches each resource's token for that window and offers no way to force an early refresh, and the issuer's 1-hour default rejects those tokens with `invalid_grant`. The Connect workload wizard's Microsoft Entra tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` and provides no field to change it during creation, so finish the wizard, then open **Settings → Workload identity → Issuers**, edit the issuer, and raise the value to `86400`. You can also update the issuer through the Admin API. + Managed identity workloads need `max_jwt_lifetime_seconds: 86400`. Azure issues managed identity tokens with up to 24 hours between `iat` and `exp` because it caches each resource's token for that window and offers no way to force an early refresh, and the issuer's 1-hour default rejects those tokens, so the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`). The Connect workload wizard's Microsoft Entra tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` and provides no field to change it during creation, so finish the wizard, then open **Settings → Workload identity → Issuers**, edit the issuer, and raise the value to `86400`. You can also update the issuer through the Admin API. </Warning> A longer accepted lifetime means a leaked Entra token stays exchangeable for longer. If a token leaks, the lever is disabling the federation rule; a tight `oid` match limits which identities can exchange a token in the first place, as described in [Scope your rule](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#scope-your-rule).
### Verify the setup -From your Azure resource, run the cURL exchange shown in [Acquire and use the token](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token) and confirm that `POST /v1/oauth/token` returns a `200` with an `access_token` beginning with `sk-ant-oat01-` and an `expires_in` value in seconds. On `400 invalid_grant`, decode the Entra token (see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange) for the command) and check the most common Azure-side causes: +From your Azure resource, run the cURL exchange shown in [Acquire and use the token](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token) and confirm that `POST /v1/oauth/token` returns a `200` with an `access_token` beginning with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) for the deny reason, then decode the Entra token (see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange) for the command) and check the most common Azure-side causes: * **Issuer mismatch:** The registered `issuer_url` must match the token's `iss` claim exactly. A v2.0 token carries `https://login.microsoftonline.com/<TENANT_ID>/v2.0`; if the decoded `ver` claim is `1.0`, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0). * **Token lifetime:** Managed identity tokens carry up to 24 hours between `iat` and `exp`. If the issuer still has the wizard's `7500` (or the 1-hour default), raise `max_jwt_lifetime_seconds` to `86400` as described in [Configure Anthropic](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic).
``` <Warning> - The Connect workload wizard's Microsoft Entra tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` (just over 2 hours), which covers the default 60 to 90 minute lifetime of `client_credentials` tokens. A tenant token-lifetime policy or Continuous Access Evaluation (CAE) can extend that lifetime. If your decoded token's `exp` minus `iat` exceeds 7500 seconds, edit the issuer in **Settings → Workload identity → Issuers** and raise `max_jwt_lifetime_seconds` to match, or exchanges fail with `invalid_grant`. If your tenant also runs managed-identity workloads from [Use a managed identity](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-a-managed-identity), use that section's `86400` value, which covers both paths. + The Connect workload wizard's Microsoft Entra tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` (just over 2 hours), which covers the default 60 to 90 minute lifetime of `client_credentials` tokens. A tenant token-lifetime policy or Continuous Access Evaluation (CAE) can extend that lifetime. If your decoded token's `exp` minus `iat` exceeds 7500 seconds, edit the issuer in **Settings → Workload identity → Issuers** and raise `max_jwt_lifetime_seconds` to match, or exchanges fail with the opaque `401` `authentication_error` response (message `Authentication failed`). If your tenant also runs managed-identity workloads from [Use a managed identity](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-a-managed-identity), use that section's `86400` value, which covers both paths. </Warning> A longer accepted lifetime means a leaked Entra token stays exchangeable for longer. If a token leaks, the lever is disabling the federation rule; a tight `oid` match limits which identities can exchange a token in the first place, as described in [Scope your rule](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#scope-your-rule).
### Verify the setup -From inside a labeled pod, run the cURL exchange shown in [Acquire and use the token](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) and confirm that `POST /v1/oauth/token` returns a `200` with an `access_token` beginning with `sk-ant-oat01-` and an `expires_in` value in seconds. On `400 invalid_grant`, decode the Entra-issued token from step 1 (see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange) for the command) and check the most common Azure-side causes: +From inside a labeled pod, run the cURL exchange shown in [Acquire and use the token](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) and confirm that `POST /v1/oauth/token` returns a `200` with an `access_token` beginning with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) for the deny reason, then decode the Entra-issued token from step 1 (see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange) for the command) and check the most common Azure-side causes: * **Issuer mismatch:** The registered `issuer_url` must match the token's `iss` claim exactly. A v2.0 token carries `https://login.microsoftonline.com/<TENANT_ID>/v2.0`; if the decoded `ver` claim is `1.0`, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0). * **Token lifetime:** If a tenant token-lifetime policy or CAE extends the `client_credentials` token past 7500 seconds, raise the issuer's `max_jwt_lifetime_seconds` as described in [Configure Anthropic](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic-2).
manage-claude/wif-providers/azure First recorded · 1212 lines, first recorded
## Prerequisites ## Register the token audience ## Use a managed identity ### Configure the managed identity ### Configure Anthropic ### Acquire and use the token ### Verify the setup ## Use Entra Workload Identity on AKS ### Configure Entra Workload Identity ### Configure Anthropic ### Acquire and use the token ### Verify the setup ## If your tokens are v1.0 ## Scope your rule ## Next steps
The first capture of this source. The page was already there, and this is what it said.
---
title: Use WIF with Microsoft Entra ID
url: https://platform.claude.com/docs/en/manage-claude/wif-providers/azure
description: Federate Azure managed identities and Entra Workload Identity with the Claude API so your Azure workloads can call Claude without static API keys.
---
Azure workloads authenticate to the Claude API by presenting a JSON Web Token (JWT) issued by Microsoft Entra ID, then exchanging it for a short-lived Anthropic access token. The setup follows the same shape on every Azure platform:
1. **Register the token audience:** Create one app registration in your Microsoft Entra tenant to represent the Claude API audience. Every workload in the tenant requests Entra tokens for it.
2. **Set up the identity for your platform:** A managed identity on VMs, VM Scale Sets, App Service, Functions, and Container Apps, or Entra Workload Identity on AKS.
3. **Configure Anthropic:** Register your tenant's Entra issuer, create a service account, and write a federation rule that matches the token's claims.
4. **Exchange at runtime:** Your workload exchanges its Entra-issued token at `POST /v1/oauth/token` for an `sk-ant-oat01-...` Anthropic access token and calls Claude with it.
On both paths the token you present to Anthropic carries your tenant-specific Entra issuer and the managed identity's object ID in the `sub` and `oid` claims; only how the workload obtains that token differs. Pick the section for where your workload runs: [Use a managed identity](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-a-managed-identity) for VMs, VM Scale Sets, App Service, Functions, or Container Apps; [Use Entra Workload Identity on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-entra-workload-identity-on-aks) for AKS.
## Prerequisites
* Familiarity with [WIF concepts](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#concepts): service accounts, federation issuers, and federation rules.
* An Azure subscription with permission to assign managed identities (or configure Entra Workload Identity on AKS).
* Permission to create one app registration and service principal in your Microsoft Entra tenant (the shared Claude API audience). Entra only issues tokens for an audience that exists in the tenant, so the [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience) step is required before any token request succeeds.
* Your Microsoft Entra tenant ID. Find it in the Azure portal under **Microsoft Entra ID → Overview → Tenant ID**.
* Permission to create service accounts, federation issuers, and federation rules in the Claude Console for your Anthropic organization.
## Register the token audience
Microsoft Entra ID only issues a token when the requested audience exists in your tenant as an app registration with a service principal. Create one app registration to represent the Claude API audience; every workload in the tenant can request tokens for it. Without this registration, token requests fail with a "resource not found in tenant" error (`AADSTS50001` from the managed identity endpoints, `AADSTS500011` from the Entra token endpoint).
```bash
# Create the app registration that represents the Claude API audience.
APP_ID=$(az ad app create --display-name claude-api-federation --query appId -o tsv)
# Request v2.0 access tokens and set the api://<APP_ID> identifier URI.
az ad app update --id "$APP_ID" \
--identifier-uris "api://$APP_ID" \
--set api.requestedAccessTokenVersion=2
# Create the service principal so the audience resolves in your tenant.
az ad sp create --id "$APP_ID"
```
<Note>
Use the `api://<APP_ID>` identifier URI format. Entra restricts `https://` identifier URIs to verified domains of your own tenant, so a URI such as `https://api.anthropic.com` cannot be registered in most tenants; `api://<APP_ID>` is accepted everywhere. With `requestedAccessTokenVersion: 2`, tokens for this audience are v2.0, which is what this guide assumes. If you reuse an existing registration that emits v1.0 tokens, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
</Note>
## Use a managed identity
Use this path when your workload runs on a VM, a VM Scale Set, App Service, Functions, or Container Apps. The workload requests an Entra-issued JWT for its assigned managed identity from the platform's local token endpoint, then exchanges that JWT with Anthropic.
### Configure the managed identity
<Steps>
<Step title="Attach a managed identity">
Enable a system-assigned or user-assigned managed identity on your Azure resource. In the Azure portal, open the resource, go to **Identity**, and turn on **System assigned** (or attach a user-assigned identity).
After the identity is created, note its **Object (principal) ID**. This GUID appears as both the `sub` and `oid` claims in the issued token, and your Anthropic federation rule will match on it. You can find it on the resource's **Identity** page; for a user-assigned identity, it is the **Object (principal) ID** on the managed identity resource's **Overview** page. (A managed identity has only a service principal in Microsoft Entra ID, not an app registration.)
</Step>
<Step title="Find the platform's token endpoint">
The platform exposes a local token endpoint once the identity is attached:
* **VMs and VM Scale Sets:** IMDS at `http://169.254.169.254/metadata/identity/oauth2/token` with the header `Metadata: true` and `api-version=2018-02-01`.
* **App Service, Functions, and Container Apps:** The URL in the `IDENTITY_ENDPOINT` environment variable with the header `X-IDENTITY-HEADER` set to the value of `IDENTITY_HEADER`, and `api-version=2019-08-01`. IMDS is not reachable on these platforms.
If the resource has more than one user-assigned managed identity, add `client_id=<IDENTITY_CLIENT_ID>` to the token request to select one. Azure recommends always specifying it. Without it, the outcome depends on whether the resource also has a system-assigned identity enabled: if it does, the request silently falls back to that identity and then fails your federation rule's `oid` match; if it does not, the request fails outright as soon as a second user-assigned identity is attached.
</Step>
<Step title="Decode a sample token">
Request a token from the endpoint and decode its payload to confirm the claims your federation rule needs to match. (For the decode command, see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange).) A v2.0 token for a managed identity carries these claims:
```json
{
"iss": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
"sub": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"aud": "<APP_ID>",
"oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"tid": "<TENANT_ID>",
"azp": "<IDENTITY_CLIENT_ID>",
"ver": "2.0",
"exp": 1775527120
}
```
| Claim | Value | Match this when |
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `oid` | The managed identity's object ID, identical to `sub` | You want to authorize one specific managed identity. This is the default; the rule in [Configure Anthropic](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic) matches it. |
| `azp` | The calling identity's client ID | You want to authorize every workload that shares one app registration. For a managed identity, `azp` is unique to that identity, so it is equivalent to `oid`. |
| `aud` | The audience app registration's client ID (the `<APP_ID>` GUID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience)) | Always. The rule's `audience` field must equal the token's `aud` value exactly. |
| `tid` | Your tenant ID | You want defense in depth. The issuer URL already pins the tenant. |
If the decoded token's `ver` claim is `1.0`, the claim names and values differ. See [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0) before continuing.
</Step>
</Steps>
### Configure Anthropic
In the Claude Console, open **Settings → Workload identity**, click **Connect workload**, and select the **Microsoft Entra** tile. The wizard walks you through registering the issuer, creating a service account, and creating a federation rule.
The wizard creates these resources for you. Use the following values whether you enter them in the wizard or send them to the [Admin API](https://platform.claude.com/docs/en/manage-claude/wif-admin-api):
**Federation issuer:** Choose **v2.0 (login.microsoftonline.com)** in the wizard's **Token issuer** selector. (The selector defaults to v1; that default exists for tenants reusing older registrations that still emit v1.0 tokens.) Entra publishes an OIDC discovery document at the per-tenant issuer URL, so use discovery mode. Each Microsoft Entra tenant you federate needs its own issuer record.
```json
{
"name": "azure-prod-tenant",
"issuer_url": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
"jwks": { "type": "discovery" },
"max_jwt_lifetime_seconds": 86400
}
```
<Warning>
Managed identity workloads need `max_jwt_lifetime_seconds: 86400`. Azure issues managed identity tokens with up to 24 hours between `iat` and `exp` because it caches each resource's token for that window and offers no way to force an early refresh, and the issuer's 1-hour default rejects those tokens with `invalid_grant`. The Connect workload wizard's Microsoft Entra tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` and provides no field to change it during creation, so finish the wizard, then open **Settings → Workload identity → Issuers**, edit the issuer, and raise the value to `86400`. You can also update the issuer through the Admin API.
</Warning>
A longer accepted lifetime means a leaked Entra token stays exchangeable for longer. If a token leaks, the lever is disabling the federation rule; a tight `oid` match limits which identities can exchange a token in the first place, as described in [Scope your rule](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#scope-your-rule).
**Federation rule:** Match on the managed identity's object ID and your tenant ID. For the v2.0 tokens this guide configures, the `audience` value is the audience app registration's client ID (the `<APP_ID>` GUID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience)). Use the exact `aud` value from your decoded token.
```json
{
"name": "azure-inference-worker",
"issuer_id": "fdis_...",
"match": {
"audience": "<APP_ID>",
"claims": {
"oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
"tid": "<TENANT_ID>"
}
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}
```
`token_lifetime_seconds` is the lifetime of the Anthropic access token the exchange returns, not of the Entra token; the SDK refreshes it for you.
### Acquire and use the token
At runtime your workload fetches its Entra token, exchanges it at `POST /v1/oauth/token`, and uses the returned bearer token to call Claude. Each Anthropic SDK handles the exchange and refresh loop when you supply a token-provider callable, as shown in the following examples. The cURL tab shows the raw flow.
The samples fetch the managed identity token from the platform's token endpoint: IMDS on VMs and VM Scale Sets, or the `IDENTITY_ENDPOINT` service on App Service, Functions, and Container Apps. Replace `<APP_ID>` in the `api://<APP_ID>` resource value with the audience app registration's client ID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience).
<Tip>
If your workload already uses the Azure Identity client library, pass its token acquisition (`DefaultAzureCredential` with the scope `api://<APP_ID>/.default`) as the identity token provider instead of calling the token endpoints directly. The library selects the correct endpoint on every Azure platform, including AKS with Entra Workload Identity.
</Tip>
<CodeGroup>
```bash cURL
# 1. Fetch the Entra-issued token (managed identity).
# On a VM or VM Scale Set, use IMDS. With multiple user-assigned
# identities, append &client_id=<IDENTITY_CLIENT_ID>.
ENTRA_TOKEN=$(curl -sS -H "Metadata: true" \
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=api://<APP_ID>" \
| jq -r .access_token)
# On App Service, Functions, or Container Apps, use the local token
# service instead (IMDS is not reachable there):
# ENTRA_TOKEN=$(curl -sS -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" \
# "$IDENTITY_ENDPOINT?api-version=2019-08-01&resource=api://<APP_ID>" \
# | jq -r .access_token)
# For AKS with Entra Workload Identity, use the two-hop exchange in the
# "Use Entra Workload Identity on AKS" section instead.
# 2. Exchange it for an Anthropic access token.
RESPONSE=$(curl -sS https://api.anthropic.com/v1/oauth/token \
-H "content-type: application/json" \
-d @- <<JSON
{
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": "$ENTRA_TOKEN",
"federation_rule_id": "$ANTHROPIC_FEDERATION_RULE_ID",
"organization_id": "$ANTHROPIC_ORGANIZATION_ID",
"service_account_id": "$ANTHROPIC_SERVICE_ACCOUNT_ID",
"workspace_id": "$ANTHROPIC_WORKSPACE_ID"
}
JSON
)
ACCESS_TOKEN=$(echo "$RESPONSE" | jq -r .access_token)
# 3. Call the Claude API with the bearer token.
curl https://api.anthropic.com/v1/messages \
-H "authorization: Bearer $ACCESS_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello from Azure"}]
}' | jq -r '.content[] | select(.type == "text") | .text'
```
```python Python
import os
import anthropic
import requests
from anthropic import WorkloadIdentityCredentials
# The audience app registration's identifier URI (see Register the token audience).
AUDIENCE = "api://<APP_ID>"
def fetch_entra_token() -> str:
"""Fetch a managed identity token from the platform's token endpoint."""
# With multiple user-assigned identities, add client_id=<IDENTITY_CLIENT_ID>
# to the request params to select one.
if endpoint := os.environ.get("IDENTITY_ENDPOINT"):
# App Service, Functions, Container Apps
response = requests.get(
endpoint,
headers={"X-IDENTITY-HEADER": os.environ["IDENTITY_HEADER"]},
params={"api-version": "2019-08-01", "resource": AUDIENCE},
timeout=5,
)
else:
# VM or VM Scale Set: Azure Instance Metadata Service (IMDS)
response = requests.get(
"http://169.254.169.254/metadata/identity/oauth2/token",
headers={"Metadata": "true"},
params={"api-version": "2018-02-01", "resource": AUDIENCE},
timeout=5,
)
response.raise_for_status()
return response.json()["access_token"]
client = anthropic.Anthropic(
credentials=WorkloadIdentityCredentials(
identity_token_provider=fetch_entra_token,
federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
),
)
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello from Azure"}],
)
print(next(block.text for block in message.content if block.type == "text"))
```
```typescript TypeScript
import Anthropic from "@anthropic-ai/sdk";
import { oidcFederationProvider } from "@anthropic-ai/sdk/lib/credentials/oidc-federation";
// The audience app registration's identifier URI (see Register the token audience).
const AUDIENCE = "api://<APP_ID>";
async function fetchEntraToken(): Promise<string> {
// App Service, Functions, and Container Apps inject IDENTITY_ENDPOINT;
// VMs and VM Scale Sets use IMDS.
// With multiple user-assigned identities, append &client_id=<IDENTITY_CLIENT_ID>.
const identityEndpoint = process.env.IDENTITY_ENDPOINT;
const url = identityEndpoint
? `${identityEndpoint}?api-version=2019-08-01&resource=${AUDIENCE}`
: `http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=${AUDIENCE}`;
const headers: Record<string, string> = identityEndpoint
? { "X-IDENTITY-HEADER": process.env.IDENTITY_HEADER! }
: { Metadata: "true" };
const response = await fetch(url, { headers });
const body = (await response.json()) as { access_token: string };
return body.access_token;
}
const client = new Anthropic({
credentials: oidcFederationProvider({
identityTokenProvider: fetchEntraToken,
federationRuleId: process.env.ANTHROPIC_FEDERATION_RULE_ID!,
organizationId: process.env.ANTHROPIC_ORGANIZATION_ID!,
serviceAccountId: process.env.ANTHROPIC_SERVICE_ACCOUNT_ID,
workspaceId: process.env.ANTHROPIC_WORKSPACE_ID,
baseURL: "https://api.anthropic.com",
fetch
})
});
const message = await client.messages.create({
model: "claude-opus-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello from Azure" }]
});
for (const block of message.content) {
if (block.type === "text") {
console.log(block.text);
}
}
```
```go Go
package main
Cut at 300 lines.