Back to Resources

How to Test Claude API & Models Endpoint

Execute automated latency probes, list available Claude models, and handle HTTP 429 and 529 error boundaries across Python and TypeScript.

Production AI pipelines require deterministic health checks before serving traffic. Rather than sending heavy conversational payloads to verify whether an API key works or if the provider is healthy, automated systems use lightweight probes to inspect model availability and network latency.

This guide provides tested patterns across cURL, Python, and TypeScript to monitor Claude API connectivity, query model metadata, and handle upstream error states gracefully.

Contents

The Anatomy of a Claude API Probe

A comprehensive connectivity check performs two distinct operations:

  1. Credential and Capability Verification: An authenticated GET request to the /v1/models endpoint. This call consumes zero generation tokens and verifies that your API credentials possess valid permissions. If you need a refresher on environment secrets, review How to Manage Anthropic API Keys and Environment Variables.
  2. Execution and Latency Verification: A minimal POST request to /v1/messages with max_tokens: 1 using a fast model such as claude-3-5-haiku-20241022. This roundtrip test confirms that inference pipelines, token accounting, and socket handshakes function properly.

For detailed SDK installation instructions prior to probing, see How to Set Up Anthropic Python and TypeScript SDKs.

Listing Available Models via GET /v1/models

The Anthropic Models API provides a list of models accessible to your organization. Inspecting this endpoint programmatically prevents configuration errors where application runners target deprecated model identifiers.

cURL Probe

You can verify raw connectivity from any shell environment:

Terminalbash
curl -s -X GET "https://api.anthropic.com/v1/models" \  -H "x-api-key: ${ANTHROPIC_API_KEY}" \  -H "anthropic-version: 2023-06-01"

A successful response returns an HTTP 200 payload containing a paginated array of model records:

json
{  "data": [    {      "type": "model",      "id": "claude-3-5-sonnet-20241022",      "display_name": "Claude 3.5 Sonnet",      "created_at": "2024-10-22T00:00:00Z"    },    {      "type": "model",      "id": "claude-3-5-haiku-20241022",      "display_name": "Claude 3.5 Haiku",      "created_at": "2024-10-22T00:00:00Z"    }  ],  "has_more": false,  "first_id": "claude-3-5-sonnet-20241022",  "last_id": "claude-3-5-haiku-20241022"}

Consult the official Anthropic API Documentation for recent model releases and parameter specifications.

Automated Latency Probing with Messages

While /v1/models verifies authorization, inference latency must be checked against /v1/messages.

To minimize cost, configure your latency probe with:

  • Target model: claude-3-5-haiku-20241022
  • Maximum tokens: 1
  • Input content: Single-token prompt string ("ping")

This design consumes minimal usage while giving your APM collectors an accurate read on roundtrip TTFT (Time to First Token) plus network overhead. For token budgeting patterns across engineering organizations, review Cost Control and Token Budgets for Small Teams.

Error Boundaries: Handling 429 and 529 Status Codes

Robust test harnesses isolate failure modes into distinct remediation tracks:

HTTP StatusError TypeRoot CauseRecommended Action
401authentication_errorMissing or revoked API keyAlert operations; rotate credentials
403permission_errorKey lacks scope or workspace accessInspect workspace permissions in Console
429rate_limit_errorRequest or token burst limits exceededBackoff exponentially; examine concurrent workloads
529overloaded_errorAnthropic capacity temporarily constrainedRetry with jittered backoff; failover to queue
500api_errorUpstream internal server errorLog request ID header and retry

Both Python and TypeScript SDKs provide typed exception hierarchies for these exact codes.

Executable Python Connectivity Suite

The following implementation queries available models, runs a latency ping probe, and logs execution timing:

python
import osimport sysimport timefrom dotenv import load_dotenvimport anthropicfrom anthropic import Anthropic, RateLimitError, InternalServerError, APIConnectionError, APIStatusErrorload_dotenv()api_key = os.environ.get("ANTHROPIC_API_KEY")if not api_key:    print("Error: ANTHROPIC_API_KEY environment variable is not set.")    sys.exit(1)client = Anthropic(api_key=api_key)def check_models():    """Query model inventory via client.models.list()."""    print("Probing models catalog...")    start_time = time.perf_counter()    try:        page = client.models.list(limit=20)        duration_ms = (time.perf_counter() - start_time) * 1000        print(f"Models probe successful: {len(page.data)} models discovered ({duration_ms:.2f} ms).")        return True    except RateLimitError as exc:        print(f"Rate limited (HTTP 429): {exc.message}")        return False    except InternalServerError as exc:        print(f"Anthropic Overloaded/Internal error (HTTP {exc.status_code}): {exc.message}")        return False    except APIConnectionError as exc:        print(f"Network connectivity error: {exc}")        return False    except APIStatusError as exc:        print(f"API returned status {exc.status_code}: {exc.message}")        return Falsedef check_latency(model: str = "claude-3-5-haiku-20241022"):    """Measure single-token completion latency."""    print(f"Probing message inference latency against {model}...")    start_time = time.perf_counter()    try:        response = client.messages.create(            model=model,            max_tokens=1,            messages=[{"role": "user", "content": "ping"}],        )        duration_ms = (time.perf_counter() - start_time) * 1000        print(f"Inference probe successful in {duration_ms:.2f} ms (Usage: {response.usage.input_tokens} input, {response.usage.output_tokens} output tokens).")        return True    except RateLimitError as exc:        print(f"Rate limited during inference probe: {exc.message}")        return False    except InternalServerError as exc:        print(f"Anthropic capacity error: {exc.message}")        return False    except APIConnectionError as exc:        print(f"Socket connection failure: {exc}")        return Falseif __name__ == "__main__":    models_healthy = check_models()    latency_healthy = check_latency()    if models_healthy and latency_healthy:        print("All connectivity probes passed.")        sys.exit(0)    else:        print("Connectivity probes failed.")        sys.exit(1)

Executable TypeScript Connectivity Suite

For Node.js and Edge runtimes, the official TypeScript SDK provides identical guarantees:

typescript
import Anthropic from "@anthropic-ai/sdk";import * as dotenv from "dotenv";dotenv.config();const apiKey = process.env.ANTHROPIC_API_KEY;if (!apiKey) {  console.error("Error: ANTHROPIC_API_KEY environment variable is missing.");  process.exit(1);}const client = new Anthropic({ apiKey });async function verifyModels(): Promise {  const start = performance.now();  try {    const response = await client.models.list({ limit: 20 });    const elapsed = performance.now() - start;    console.log(`Retrieved ${response.data.length} models in ${elapsed.toFixed(2)} ms.`);    return true;  } catch (err: unknown) {    if (err instanceof Anthropic.RateLimitError) {      console.error(`Rate limit exceeded (HTTP 429): ${err.message}`);    } else if (err instanceof Anthropic.InternalServerError) {      console.error(`Server overloaded or unavailable (HTTP ${err.status}): ${err.message}`);    } else if (err instanceof Anthropic.APIConnectionError) {      console.error(`Connection handshake failed: ${err.message}`);    } else {      console.error(`API probe failed: ${err}`);    }    return false;  }}async function verifyLatency(model = "claude-3-5-haiku-20241022"): Promise {  const start = performance.now();  try {    const message = await client.messages.create({      model,      max_tokens: 1,      messages: [{ role: "user", content: "ping" }],    });    const elapsed = performance.now() - start;    console.log(`Latency probe succeeded in ${elapsed.toFixed(2)} ms. Tokens: in=${message.usage.input_tokens}, out=${message.usage.output_tokens}`);    return true;  } catch (err: unknown) {    if (err instanceof Anthropic.RateLimitError) {      console.error(`Rate limit encountered during ping: ${err.message}`);    } else if (err instanceof Anthropic.InternalServerError) {      console.error(`Upstream service issue (HTTP ${err.status}): ${err.message}`);    } else {      console.error(`Ping probe error: ${err}`);    }    return false;  }}async function run() {  const modelsOk = await verifyModels();  const latencyOk = await verifyLatency();  if (modelsOk && latencyOk) {    console.log("All systems operational.");    process.exit(0);  }  process.exit(1);}run();

Production Monitoring and CI/CD Verification

Integrating these probes into continuous integration pipelines protects deployment workflows:

  • Pre-deployment smoke tests: Run the models check inside deployment jobs to catch invalid credentials before traffic routes to new revisions.
  • Canary health probes: Configure orchestrator liveness checks using lightweight curl probes against /v1/models every 60 seconds.
  • Alert thresholds: Alert engineering teams when single-token inference roundtrip latencies on Haiku exceed 1,500 ms over a consecutive 3-sample window.

All runnable scripts and configuration templates from this tutorial are hosted in the open companion repository under recipes/claude/03-test-api-connectivity/.

FAQ

Does querying the GET /v1/models endpoint consume tokens?

No. The /v1/models endpoint is a metadata operation that incurs no token charges. It only counts against your organization's rate limit for requests per minute.

What is the difference between HTTP 429 and HTTP 529?

An HTTP 429 response indicates that your client has exceeded its assigned rate limit for requests per minute (RPM) or tokens per minute (TPM). An HTTP 529 status indicates that Anthropic servers are experiencing temporary capacity constraints. Applications should implement exponential backoff with randomized jitter for both conditions.

Which model should be used for automated latency health checks?

Use claude-3-5-haiku-20241022. It features lower latency and cost compared to larger models, making it ideal for synthetic uptime pings and token accounting validation.

Can cURL probes pass custom headers for tracing?

Yes. You can pass the standard anthropic-version: 2023-06-01 header along with custom diagnostic headers such as x-request-id to correlate requests in upstream monitoring dashboards.

Share