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

  1. Create an account at PageGrid
  2. Go to Dashboard → API Keys → Create New Key
  3. Copy your key (starts with pg-)

Step 2: Set environment variables

Add these to your shell profile (~/.bashrc, ~/.zshrc, or ~/.profile):

bash
export ANTHROPIC_API_KEY="pg-your-key-here"
export ANTHROPIC_BASE_URL="https://api.pagegrid.in/v1"

Then reload your shell:

bash
source ~/.zshrc  # or ~/.bashrc

Step 3: Use Claude Code normally

bash
claude

That's it. Claude Code will now route all requests through PageGrid. You can use all models:

bash
# Use Sonnet (default, fast)
claude

# Use Opus (most intelligent)
claude --model claude-opus-4-6

# Use Haiku (cheapest, fastest)
claude --model claude-haiku-4-5

Verify it works

Run this to confirm PageGrid is being used:

bash
echo $ANTHROPIC_BASE_URL
# Should output: https://api.pagegrid.in/v1

For Windows (PowerShell)

bash
$env:ANTHROPIC_API_KEY = "pg-your-key-here"
$env:ANTHROPIC_BASE_URL = "https://api.pagegrid.in/v1"
claude

For Windows (CMD)

bash
set ANTHROPIC_API_KEY=pg-your-key-here
set ANTHROPIC_BASE_URL=https://api.pagegrid.in/v1
claude

Works 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
# 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
// 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 pg-
  • 402 error: Your wallet balance is $0. Add funds in the dashboard.
  • 404 error: The model isn't available. Check /v1/models for active models.
  • Connection error: Make sure ANTHROPIC_BASE_URL ends with /v1 (not /v1/messages)

Use with Codex CLI

Use PageGrid as your OpenAI Codex CLI backend. PageGrid supports the /v1/chat/completions endpoint in full OpenAI-compatible format.

Step 1: Get your API key

  1. Create an account at PageGrid
  2. Go to Dashboard → API Keys → Create New Key
  3. Copy your key (starts with pg-)

Step 2: Set environment variables

Add these to your shell profile (~/.bashrc, ~/.zshrc, or ~/.profile):

bash
export OPENAI_API_KEY="pg-your-key-here"
export OPENAI_BASE_URL="https://api.pagegrid.in/v1"

Then reload your shell:

bash
source ~/.zshrc  # or ~/.bashrc

Step 3: Use Codex CLI normally

bash
codex

Codex CLI will now route all requests through PageGrid using the OpenAI Chat Completions format.

Choose a model

bash
# Use GPT-5.4
codex --model gpt-5.4

# Use GPT-5.5
codex --model gpt-5.5

# Use Claude models via OpenAI format
codex --model claude-opus-4-6
codex --model claude-sonnet-4-6

One-liner (without setting env permanently)

bash
OPENAI_API_KEY="pg-your-key" OPENAI_BASE_URL="https://api.pagegrid.in/v1" codex

For Windows (PowerShell)

bash
$env:OPENAI_API_KEY = "pg-your-key-here"
$env:OPENAI_BASE_URL = "https://api.pagegrid.in/v1"
codex

For Windows (CMD)

bash
set OPENAI_API_KEY=pg-your-key-here
set OPENAI_BASE_URL=https://api.pagegrid.in/v1
codex

How it works

Codex CLI sends requests to /v1/chat/completions in OpenAI format. PageGrid automatically translates the request to the upstream provider and returns the response in proper OpenAI Chat Completions format — including streaming chunks with choices[].delta.content.

Troubleshooting

  • 401 error: Check your API key is correct
  • 402 error: Your wallet balance is $0. Add funds in the dashboard.
  • Model not found: Check GET /v1/models for available models
  • Base URL: Must be https://api.pagegrid.in/v1 (with /v1)

Use with Codex App

Use PageGrid with the Codex desktop/web app by configuring a custom OpenAI base URL.

Step 1: Open Codex App Settings

  1. Open the Codex app
  2. Go to Settings (gear icon)
  3. Find the "API" or "Provider" section

Step 2: Configure the API

Set the following values:

Base URL:https://api.pagegrid.in/v1
API Key:pg-your-key-here
Model:gpt-5.4(or any model from the list below)

If the app uses environment variables

Some Codex app versions read from environment variables. Create a .env file in your project root:

bash
OPENAI_API_KEY=pg-your-key-here
OPENAI_BASE_URL=https://api.pagegrid.in/v1

Available models

PageGrid supports both OpenAI and Claude models through the Chat Completions format:

OpenAI Models

  • gpt-5.4
  • gpt-5.5

Claude Models

  • claude-opus-4-8
  • claude-opus-4-7
  • claude-opus-4-6
  • claude-sonnet-4-6
  • claude-haiku-4-5-20251001

Verify the connection

Test with a curl request to confirm the endpoint works:

bash
curl https://api.pagegrid.in/v1/chat/completions \
  -H "Authorization: Bearer pg-your-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4",
    "messages": [{"role": "user", "content": "Hello!"}],
    "max_tokens": 100
  }'

Response (OpenAI format):

json
{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "created": 1700000000,
  "model": "gpt-5.4",
  "choices": [{
    "index": 0,
    "message": {"role": "assistant", "content": "Hello! How can I help?"},
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 10,
    "completion_tokens": 8,
    "total_tokens": 18
  }
}

Streaming

Set "stream": true in your request body. The response uses the standard OpenAI SSE chunk format with data: {...} lines ending with data: [DONE].

Troubleshooting

  • 401 error: Check your API key. Use it as a Bearer token in the Authorization header.
  • Base URL format: Must include /v1 — use https://api.pagegrid.in/v1
  • Wrong response format: Make sure you're hitting /v1/chat/completions, not /v1/messages
  • 402 error: Wallet is empty. Add funds in the PageGrid dashboard.

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:

json
{
  "models": {
    "providers": [
      {
        "name": "pagegrid",
        "api": "anthropic-messages",
        "baseUrl": "https://api.pagegrid.in",
        "apiKey": "pg-your-key-here"
      }
    ]
  }
}

Important: Do NOT include /v1 in the baseUrl. OpenClaw appends /v1/messages automatically.

Option 2: Environment variables

bash
export ANTHROPIC_BASE_URL="https://api.pagegrid.in"
export ANTHROPIC_API_KEY="pg-your-key-here"

Option 3: CLI onboarding

bash
openclaw onboard --non-interactive \
  --provider anthropic \
  --custom-base-url "https://api.pagegrid.in" \
  --api-key "pg-your-key-here"

Choosing a model

Set the default model in your OpenClaw config or per-conversation:

json
{
  "models": {
    "default": "claude-sonnet-4-6",
    "providers": [
      {
        "name": "pagegrid",
        "api": "anthropic-messages",
        "baseUrl": "https://api.pagegrid.in",
        "apiKey": "pg-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

bash
# Start OpenClaw
openclaw

# In the chat, ask:
> What model are you using?

# It should respond with the model name from PageGrid

Troubleshooting

  • 404 errors: Make sure baseUrl is https://api.pagegrid.in without /v1
  • 401 errors: Check your API key starts with pg-
  • 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

  1. Login to your account (created by admin)
  2. Go to API Keys and create a new key
  3. Copy your key (shown only once!)
  4. Make your first API call
bash
curl -X POST https://api.pagegrid.in/v1/messages \
  -H "Content-Type: application/json" \
  -H "api-key: pg-your-key-here" \
  -d '{
    "model": "claude-opus-4-6",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "What is the capital of France?"}
    ]
  }'

Response:

json
{
  "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)

bash
curl -H "api-key: pg-your-key-here" ...

Option 2: Authorization Bearer header

bash
curl -H "Authorization: Bearer pg-your-key-here" ...

API Key Format

Keys start with pg- followed by 64 hex characters:

text
pg-65b03b3c7bcab0bb1e865676f971c29fb86e403ed89f91234ca747e1a19169d0

Key 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.

Chat Completions API

POST/v1/chat/completions

OpenAI-compatible Chat Completions endpoint. Use this with Codex, OpenAI SDKs, or any tool that supports custom OpenAI base URLs.

Request Body

ParameterTypeRequiredDescription
modelstringrequiredModel ID (e.g., "gpt-5.4", "claude-opus-4-6")
messagesarrayrequiredArray of {role, content} objects
max_tokensintegeroptionalMaximum tokens to generate (also accepts max_completion_tokens)
temperaturenumberoptionalRandomness 0.0-2.0
top_pnumberoptionalNucleus sampling
streambooleanoptionalEnable SSE streaming (default: false)

Example Request

bash
curl -X POST https://api.pagegrid.in/v1/chat/completions \
  -H "Authorization: Bearer pg-your-key-here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "What is 2+2?"}
    ],
    "max_tokens": 100
  }'

Response

json
{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "created": 1700000000,
  "model": "gpt-5.4",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "2 + 2 = 4."
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 25,
    "completion_tokens": 8,
    "total_tokens": 33
  }
}

Streaming Response

Set "stream": true. Each chunk follows the OpenAI SSE format:

text
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","model":"gpt-5.4","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","model":"gpt-5.4","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","model":"gpt-5.4","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":10,"completion_tokens":5,"total_tokens":15}}

data: [DONE]

Using with OpenAI SDK

python
from openai import OpenAI

client = OpenAI(
    api_key="pg-your-key-here",
    base_url="https://api.pagegrid.in/v1"
)

response = client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Hello!"}],
    max_tokens=100
)
print(response.choices[0].message.content)
javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "pg-your-key-here",
  baseURL: "https://api.pagegrid.in/v1"
});

const response = await client.chat.completions.create({
  model: "gpt-5.4",
  messages: [{ role: "user", content: "Hello!" }],
  max_tokens: 100
});
console.log(response.choices[0].message.content);

Key Differences from Messages API

FeatureChat CompletionsMessages API
Endpoint/v1/chat/completions/v1/messages
FormatOpenAIAnthropic
Responsechoices[0].message.contentcontent[0].text
Streamingchoices[0].delta.contentSSE events
Auth headerAuthorization: Bearerx-api-key or api-key
Best forCodex, OpenAI SDK appsClaude Code, Anthropic SDK

Messages API

POST/v1/messages

Send messages and receive AI responses.

Request Body

ParameterTypeRequiredDescription
modelstringrequiredModel ID (e.g., "claude-opus-4-6")
messagesarrayrequiredArray of message objects with role and content
max_tokensintegerrequiredMaximum tokens to generate (1 to model max)
systemstringoptionalSystem prompt (top-level, not in messages)
temperaturenumberoptionalRandomness 0.0-1.0 (default: 1.0)
top_pnumberoptionalNucleus sampling threshold
top_kintegeroptionalTop-K sampling
stop_sequencesstring[]optionalCustom stop sequences
streambooleanoptionalEnable SSE streaming (default: false)
toolsarrayoptionalTool definitions for function calling
tool_choiceobjectoptionalauto, any, tool, or none
thinkingobjectoptional{type: "enabled"|"disabled"|"adaptive", budget_tokens?}
metadataobjectoptional{user_id} for tracking

Response Body

ParameterTypeRequiredDescription
idstringrequiredUnique message ID (e.g., "msg_...")
typestringrequiredAlways "message"
rolestringrequiredAlways "assistant"
modelstringrequiredModel that generated the response
contentarrayrequiredArray of content blocks (text, tool_use, thinking)
stop_reasonstringrequiredend_turn, max_tokens, stop_sequence, or tool_use
usageobjectrequired{input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens}

Message Object

json
{
  "role": "user",       // "user" or "assistant"
  "content": "Hello!"   // string or array of content blocks
}

Content Block Types

javascript
// 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

json
{
  "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.

bash
curl -N -X POST https://api.pagegrid.in/v1/messages \
  -H "api-key: pg-..." \
  -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

1. message_start — contains input_tokens
2. content_block_start — opens a content block
3. content_block_delta — incremental text chunks (repeated)
4. content_block_stop — closes the block
5. message_delta — stop_reason + final output_tokens
6. message_stop — stream complete

Delta Types

ParameterTypeRequiredDescription
text_deltaobjectrequired{type: "text_delta", text: "Hello"}
input_json_deltaobjectrequiredPartial JSON for tool_use blocks
thinking_deltaobjectrequiredExtended thinking content
signature_deltaobjectrequiredThinking block signature

Token Usage in Streaming

  • message_start event contains usage.input_tokens + cache token counts
  • message_delta event contains cumulative usage.output_tokens
  • You are charged after the stream completes

Token Counting

POST/v1/messages/count_tokens

Count tokens before sending a request. This endpoint is free — no charge to your wallet.

bash
curl -X POST https://api.pagegrid.in/v1/messages/count_tokens \
  -H "api-key: pg-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4-6",
    "messages": [{"role": "user", "content": "Hello, world!"}]
  }'

Response:

json
{"input_tokens": 12}

Models

GET/v1/models

List all available models with capabilities and pricing.

ModelIDContextMax OutputBest 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

ModelInput /1MOutput /1MCache Write /1MCache 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

text
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:

json
{
  "error": {
    "type": "invalid_request_error",
    "message": "max_tokens is required"
  }
}

Error Types

HTTPTypeDescription
400invalid_request_errorBad request format or missing fields
401authentication_errorInvalid, expired, or missing API key
402billing_errorInsufficient wallet balance
403permission_errorKey lacks access to requested model
404not_found_errorModel not found or inactive
429rate_limit_errorRate or daily/monthly limit exceeded
500api_errorInternal server error
502api_errorService 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:

LimitDefaultDescription
Rate Limit (RPM)10Maximum requests per minute
Daily Request LimitUnlimitedMaximum requests per day (0 = unlimited)
Monthly Token LimitUnlimitedMaximum 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

  1. Add funds to your wallet (any amount)
  2. Each API call deducts based on actual token usage
  3. Every transaction is logged with full breakdown
  4. 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

python
from anthropic import Anthropic

client = Anthropic(
    api_key="pg-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

javascript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: "pg-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

bash
curl -N -X POST https://api.pagegrid.in/v1/messages \
  -H "Content-Type: application/json" \
  -H "api-key: pg-your-key" \
  -d '{
    "model": "claude-opus-4-6",
    "max_tokens": 1024,
    "stream": true,
    "messages": [{"role": "user", "content": "Hello!"}]
  }'