Use with Claude Code
Use PageGrid as your Claude Code backend. Same models, lower cost. Takes 30 seconds to set up.
Step 1: Get your API key
- Create an account at PageGrid
- Go to Dashboard → API Keys → Create New Key
- Copy your key (starts with sk-pgrid-)
Step 2: Set environment variables
Add these to your shell profile (~/.bashrc, ~/.zshrc, or ~/.profile):
export ANTHROPIC_API_KEY="sk-pgrid-your-key-here"
export ANTHROPIC_BASE_URL="https://api.pagegrid.in/v1"Then reload your shell:
source ~/.zshrc # or ~/.bashrcStep 3: Use Claude Code normally
claudeThat's it. Claude Code will now route all requests through PageGrid. You can use all models:
# Use Sonnet (default, fast)
claude
# Use Opus (most intelligent)
claude --model claude-opus-4-6
# Use Haiku (cheapest, fastest)
claude --model claude-haiku-4-5Verify it works
Run this to confirm PageGrid is being used:
echo $ANTHROPIC_BASE_URL
# Should output: https://api.pagegrid.in/v1For Windows (PowerShell)
$env:ANTHROPIC_API_KEY = "sk-pgrid-your-key-here"
$env:ANTHROPIC_BASE_URL = "https://api.pagegrid.in/v1"
claudeFor Windows (CMD)
set ANTHROPIC_API_KEY=sk-pgrid-your-key-here
set ANTHROPIC_BASE_URL=https://api.pagegrid.in/v1
claudeWorks with any Anthropic SDK
The same environment variables work with the Python and JavaScript SDKs too — any tool that uses the Anthropic API will automatically route through PageGrid.
# Python — no code changes needed
# Just set ANTHROPIC_API_KEY and ANTHROPIC_BASE_URL env vars
from anthropic import Anthropic
client = Anthropic() # reads from env automatically
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
print(message.content[0].text)// JavaScript — no code changes needed
// Just set ANTHROPIC_API_KEY and ANTHROPIC_BASE_URL env vars
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // reads from env automatically
const message = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }]
});
console.log(message.content[0].text);Troubleshooting
- 401 error: Check your API key is correct and starts with
sk-pgrid- - 402 error: Your wallet balance is $0. Add funds in the dashboard.
- 404 error: The model isn't available. Check
/v1/modelsfor active models. - Connection error: Make sure
ANTHROPIC_BASE_URLends with/v1(not/v1/messages)
Use with OpenClaw
Use PageGrid as the AI backend for OpenClaw — the open-source AI agent with 300K+ GitHub stars. Run Claude models through PageGrid at lower cost.
Option 1: Config file (recommended)
Edit ~/.openclaw/openclaw.json and add PageGrid as a provider:
{
"models": {
"providers": [
{
"name": "pagegrid",
"api": "anthropic-messages",
"baseUrl": "https://api.pagegrid.in",
"apiKey": "sk-pgrid-your-key-here"
}
]
}
}Important: Do NOT include /v1 in the baseUrl. OpenClaw appends /v1/messages automatically.
Option 2: Environment variables
export ANTHROPIC_BASE_URL="https://api.pagegrid.in"
export ANTHROPIC_API_KEY="sk-pgrid-your-key-here"Option 3: CLI onboarding
openclaw onboard --non-interactive \
--provider anthropic \
--custom-base-url "https://api.pagegrid.in" \
--api-key "sk-pgrid-your-key-here"Choosing a model
Set the default model in your OpenClaw config or per-conversation:
{
"models": {
"default": "claude-sonnet-4-6",
"providers": [
{
"name": "pagegrid",
"api": "anthropic-messages",
"baseUrl": "https://api.pagegrid.in",
"apiKey": "sk-pgrid-your-key-here",
"models": [
"claude-opus-4-6",
"claude-sonnet-4-6",
"claude-haiku-4-5"
]
}
]
}
}Supported features
- Streaming: Full SSE streaming support for real-time responses
- Tools: Function calling and tool use work natively
- Vision: Image analysis via base64 content blocks
- Extended thinking: Thinking blocks pass through correctly
- Multi-turn: Conversation history maintained by OpenClaw
Verify it works
# Start OpenClaw
openclaw
# In the chat, ask:
> What model are you using?
# It should respond with the model name from PageGridTroubleshooting
- 404 errors: Make sure baseUrl is
https://api.pagegrid.inwithout/v1 - 401 errors: Check your API key starts with
sk-pgrid- - 402 errors: Add funds to your PageGrid wallet
- Model not found: Check available models at
GET /v1/models
Getting Started
PageGrid provides fast, affordable access to Claude models including Opus, Sonnet, and Haiku. Get an API key, add funds, and start building.
Quick Start
- Login to your account (created by admin)
- Go to API Keys and create a new key
- Copy your key (shown only once!)
- Make your first API call
curl -X POST https://api.pagegrid.in/v1/messages \
-H "Content-Type: application/json" \
-H "api-key: sk-pgrid-your-key-here" \
-d '{
"model": "claude-opus-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "What is the capital of France?"}
]
}'Response:
{
"id": "msg_01XFDUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-opus-4-6",
"content": [
{"type": "text", "text": "The capital of France is Paris."}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 14,
"output_tokens": 10
}
}Authentication
All API requests require an API key. You can send it in two ways:
Option 1: api-key header (recommended)
curl -H "api-key: sk-pgrid-your-key-here" ...Option 2: Authorization Bearer header
curl -H "Authorization: Bearer sk-pgrid-your-key-here" ...API Key Format
Keys start with sk-pgrid- followed by 64 hex characters:
sk-pgrid-65b03b3c7bcab0bb1e865676f971c29fb86e403ed89f91234ca747e1a19169d0Key Management
- Keys are shown once at creation. Store them securely.
- Revoke compromised keys instantly from the dashboard.
- Rotate to get a new key without losing your settings.
- Set per-key rate limits and model restrictions.
Messages API
/v1/messagesSend messages and receive AI responses.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | required | Model ID (e.g., "claude-opus-4-6") |
messages | array | required | Array of message objects with role and content |
max_tokens | integer | required | Maximum tokens to generate (1 to model max) |
system | string | optional | System prompt (top-level, not in messages) |
temperature | number | optional | Randomness 0.0-1.0 (default: 1.0) |
top_p | number | optional | Nucleus sampling threshold |
top_k | integer | optional | Top-K sampling |
stop_sequences | string[] | optional | Custom stop sequences |
stream | boolean | optional | Enable SSE streaming (default: false) |
tools | array | optional | Tool definitions for function calling |
tool_choice | object | optional | auto, any, tool, or none |
thinking | object | optional | {type: "enabled"|"disabled"|"adaptive", budget_tokens?} |
metadata | object | optional | {user_id} for tracking |
Response Body
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | required | Unique message ID (e.g., "msg_...") |
type | string | required | Always "message" |
role | string | required | Always "assistant" |
model | string | required | Model that generated the response |
content | array | required | Array of content blocks (text, tool_use, thinking) |
stop_reason | string | required | end_turn, max_tokens, stop_sequence, or tool_use |
usage | object | required | {input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens} |
Message Object
{
"role": "user", // "user" or "assistant"
"content": "Hello!" // string or array of content blocks
}Content Block Types
// Text
{"type": "text", "text": "Hello!"}
// Image (base64)
{"type": "image", "source": {"type": "base64", "data": "...", "media_type": "image/png"}}
// Tool use (in response)
{"type": "tool_use", "id": "toolu_...", "name": "get_weather", "input": {"city": "Paris"}}
// Tool result (in request)
{"type": "tool_result", "tool_use_id": "toolu_...", "content": "22 degrees"}
// Thinking (in response, when thinking enabled)
{"type": "thinking", "thinking": "Let me analyze...", "signature": "..."}Multi-turn Conversation
{
"model": "claude-opus-4-6",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "What is 2+2?"},
{"role": "assistant", "content": "2+2 = 4."},
{"role": "user", "content": "Multiply that by 10."}
]
}Streaming
Set "stream": true to receive Server-Sent Events (SSE) as the model generates tokens.
curl -N -X POST https://api.pagegrid.in/v1/messages \
-H "api-key: sk-pgrid-..." \
-H "Content-Type: application/json" \
-d '{"model":"claude-opus-4-6","max_tokens":1024,"stream":true,
"messages":[{"role":"user","content":"Write a poem"}]}'SSE Event Flow
message_start — contains input_tokenscontent_block_start — opens a content blockcontent_block_delta — incremental text chunks (repeated)content_block_stop — closes the blockmessage_delta — stop_reason + final output_tokensmessage_stop — stream completeDelta Types
| Parameter | Type | Required | Description |
|---|---|---|---|
text_delta | object | required | {type: "text_delta", text: "Hello"} |
input_json_delta | object | required | Partial JSON for tool_use blocks |
thinking_delta | object | required | Extended thinking content |
signature_delta | object | required | Thinking block signature |
Token Usage in Streaming
message_startevent containsusage.input_tokens+ cache token countsmessage_deltaevent contains cumulativeusage.output_tokens- You are charged after the stream completes
Token Counting
/v1/messages/count_tokensCount tokens before sending a request. This endpoint is free — no charge to your wallet.
curl -X POST https://api.pagegrid.in/v1/messages/count_tokens \
-H "api-key: sk-pgrid-..." \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4-6",
"messages": [{"role": "user", "content": "Hello, world!"}]
}'Response:
{"input_tokens": 12}Models
/v1/modelsList all available models with capabilities and pricing.
| Model | ID | Context | Max Output | Best For |
|---|---|---|---|---|
| Loading models... | ||||
Model availability may vary. Use GET /v1/models to see currently active models with live pricing.
Pricing
Pay per token. No monthly fees. No subscriptions. No minimums.
Token Rates
| Model | Input /1M | Output /1M | Cache Write /1M | Cache Read /1M |
|---|---|---|---|---|
| Loading pricing... | ||||
Cache Token Pricing
Cache pricing is shown in the table above. When users add cache_control to their requests, tokens are billed at the cache write rate (on first request) and cache read rate (on subsequent requests).
- Cache write tokens: Charged when content is first cached (cache miss)
- Cache read tokens: Charged when content is read from cache (cache hit — much cheaper)
- Regular input tokens: Content not marked for caching
- Output tokens: Always charged at the output rate
How Billing Works
Cost per request = (input_tokens / 1M × input_rate)
+ (output_tokens / 1M × output_rate)
+ (cache_write_tokens / 1M × cache_write_rate)
+ (cache_read_tokens / 1M × cache_read_rate)
All four rates are shown in the pricing table above.
Use GET /v1/models for live pricing.Use GET /v1/models for real-time pricing. Prices shown here are examples and may change.
Error Handling
All errors return a consistent JSON format:
{
"error": {
"type": "invalid_request_error",
"message": "max_tokens is required"
}
}Error Types
| HTTP | Type | Description |
|---|---|---|
| 400 | invalid_request_error | Bad request format or missing fields |
| 401 | authentication_error | Invalid, expired, or missing API key |
| 402 | billing_error | Insufficient wallet balance |
| 403 | permission_error | Key lacks access to requested model |
| 404 | not_found_error | Model not found or inactive |
| 429 | rate_limit_error | Rate or daily/monthly limit exceeded |
| 500 | api_error | Internal server error |
| 502 | api_error | Service temporarily unavailable |
Retry Strategy
- 429: Wait and retry with exponential backoff
- 502/500: Retry after 1-5 seconds
- 401/402/403: Do not retry — fix credentials or add funds
Rate Limits
Rate limits are set per API key. Each key can have its own limits:
| Limit | Default | Description |
|---|---|---|
| Rate Limit (RPM) | 10 | Maximum requests per minute |
| Daily Request Limit | Unlimited | Maximum requests per day (0 = unlimited) |
| Monthly Token Limit | Unlimited | Maximum tokens per month (0 = unlimited) |
Set custom limits when creating a key, or contact support for higher limits.
Wallet & Billing
Prepaid wallet system. Add funds, use tokens, track everything.
How It Works
- Add funds to your wallet (any amount)
- Each API call deducts based on actual token usage
- Every transaction is logged with full breakdown
- View balance, usage, and history in the dashboard
Important
- Balance of $0 blocks all API requests
- Funds never expire
- No minimum top-up amount
- Full transaction history available in dashboard
SDK Examples
Works with popular AI SDKs. Here are examples in Python, JavaScript, and cURL.
Python
from anthropic import Anthropic
client = Anthropic(
api_key="sk-pgrid-your-key-here",
base_url="https://api.pagegrid.in"
)
# Non-streaming
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
print(message.content[0].text)
# Streaming
with client.messages.stream(
model="claude-opus-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Write a story"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)JavaScript / TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "sk-pgrid-your-key-here",
baseURL: "https://api.pagegrid.in"
});
// Non-streaming
const message = await client.messages.create({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }]
});
console.log(message.content[0].text);
// Streaming
const stream = client.messages.stream({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "Write a story" }]
});
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
process.stdout.write(event.delta.text);
}
}cURL with Streaming
curl -N -X POST https://api.pagegrid.in/v1/messages \
-H "Content-Type: application/json" \
-H "api-key: sk-pgrid-your-key" \
-d '{
"model": "claude-opus-4-6",
"max_tokens": 1024,
"stream": true,
"messages": [{"role": "user", "content": "Hello!"}]
}'