API documentation

Route AI calls through one metered proxy.

Send OpenAI chat requests to MeterLayer, enforce project budgets and rate limits, and get token usage, cost, latency, status and metadata in the dashboard.

Production base URL

https://meterlayer.io

Quick Start

  1. Register or log in at MeterLayer.
  2. Add your OpenAI key in Settings - Providers.
  3. Create a project in Projects.
  4. Copy the generated project API key.
  5. Use baseURL: https://meterlayer.io/v1 in OpenAI-compatible clients.
  6. Run a low-token test in Dashboard Playground.

Machine-readable API spec: OpenAPI JSON.

Authentication

Proxy calls use a project API key, not a user session. Keep this key on your server. Do not expose it in browser JavaScript, mobile apps, or public repos.

Authorization: Bearer <project_api_key>
Content-Type: application/json

OpenAI-Compatible Endpoint

Existing OpenAI clients can use the gateway by changing the base URL and API key. The project API key goes into the normal OpenAI SDK apiKey field.

POST https://meterlayer.io/v1/chat/completions
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AI_COST_GATEWAY_PROJECT_KEY,
  baseURL: "https://meterlayer.io/v1"
});

const completion = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Reply with one word: OK" }],
  max_tokens: 5,
  temperature: 0.2,
  metadata: {
    feature: "first-smoke-test",
    customerId: "internal-test"
  }
});

The endpoint accepts model,messages,max_tokens, generation options such as temperature and optionalmetadata. Streaming is not supported yet.

Gateway-Native Endpoint

The gateway validates the project key, checks project status, model allow-list, budget, rate limit and provider credential, then forwards the request to OpenAI.

{
  "provider": "openai",
  "model": "gpt-4o-mini",
  "messages": [
    { "role": "user", "content": "Hello" }
  ],
  "maxOutputTokens": 1024,
  "temperature": 0.2,
  "topP": 0.9,
  "metadata": {
    "userId": "optional-user-id",
    "feature": "email-generator",
    "customerId": "optional-customer-id"
  }
}
FieldTypeRequiredNotes
provider"openai" | "anthropic" | "gemini"YesMVP forwards OpenAI requests. Other providers are reserved for the provider abstraction.
modelstringYesMust be enabled in project settings.
messagesarrayYes1-100 messages. Roles: system, user, assistant.
maxOutputTokensintegerNoDefaults server-side. Requests above the configured limit are rejected.
metadataobjectNoStored with logs. Use feature, userId, customerId, tenantId, or similar routing context.

Response

On success, the body is the provider response. MeterLayer adds response headers with request ID, estimated cost and rate-limit information.

HeaderMeaning
X-AI-Cost-Gateway-Request-IdRequest ID for finding the entry in logs.
X-AI-Cost-Gateway-CostEstimated request cost in USD on successful provider responses.
X-AI-Cost-Gateway-RemainingCompatibility alias for remaining requests in the current rate-limit window.
X-AI-Cost-Gateway-RateLimit-RemainingRemaining requests in the current rate-limit window.
X-AI-Cost-Gateway-RateLimit-ResetISO timestamp when the current rate-limit window resets.
X-AI-Cost-Gateway-RateLimit-Backendupstash, postgres, or memory.

Rate-limit headers are included after the project API key is validated and the project rate-limit check has run.

{
  "id": "chatcmpl_...",
  "object": "chat.completion",
  "model": "gpt-4o-mini",
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "Hello! How can I help?"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 9,
    "completion_tokens": 7,
    "total_tokens": 16
  }
}

Examples

curl

curl -X POST https://meterlayer.io/api/proxy/chat \
  -H "Authorization: Bearer $AI_COST_GATEWAY_PROJECT_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Request-Id: demo-request-001" \
  -d '{
    "provider": "openai",
    "model": "gpt-4o-mini",
    "messages": [
      { "role": "system", "content": "You write concise product copy." },
      { "role": "user", "content": "Write one sentence about an AI cost dashboard." }
    ],
    "maxOutputTokens": 200,
    "metadata": {
      "feature": "product-description",
      "customerId": "customer-123"
    }
  }'

TypeScript

const response = await fetch("https://meterlayer.io/api/proxy/chat", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.AI_COST_GATEWAY_PROJECT_KEY}`,
    "Content-Type": "application/json",
    "X-Request-Id": crypto.randomUUID()
  },
  body: JSON.stringify({
    provider: "openai",
    model: "gpt-4o-mini",
    messages: [{ role: "user", content: "Hello" }],
    metadata: {
      userId: "user-123",
      feature: "chat"
    }
  })
});

const data = await response.json();
if (!response.ok) throw new Error(data.error);
return data;

First Customer Smoke

Use this sequence for the first production feature routed through MeterLayer. Keep the project API key in a backend secret manager, set a conservative project budget, and restrict allowed models before sending traffic.

  1. Add the customer OpenAI key in Settings - Providers and run the provider test.
  2. Create a project for the app or environment, for example web-prod.
  3. Copy the project API key once and store it server-side.
  4. Send one low-token smoke request with metadata.feature.
  5. Open Logs, Prompts, Models and Budgets.
  6. Record X-AI-Cost-Gateway-Request-Id for support.
const completion = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Reply with one word: OK" }],
  max_tokens: 16,
  metadata: {
    feature: "first-customer-smoke",
    customerId: "internal-test"
  }
});

Rollback is simple: restore the original OpenAI API key and base URL in the customer application. Support should ask for timestamp, project, model, feature and request ID, not provider keys, project keys, full prompts or personal data.

Request IDs

Send a unique X-Request-Id for retries and traceability. If the same project sends the same ID again, the gateway returns 409 Duplicate request ID.

Errors

Error responses include an error message andrequestId. Validation failures also include details.

{
  "error": "Provider or model is not allowed for this project.",
  "requestId": "req_..."
}
StatusMeaning
400Invalid body, missing provider credential, or invalid proxy setting.
401Missing or invalid project API key.
402Monthly budget exceeded or projected output cost would exceed budget.
403Project disabled, or provider/model is not allowed.
409Duplicate X-Request-Id.
413Request body is too large.
429Project rate limit exceeded.
502Provider response was invalid or missing usage data.
504Provider request timed out.

Pricing

ModelInput per 1MOutput per 1M
gpt-4o-miniUSD 0.15USD 0.60
gpt-4oUSD 5.00USD 15.00
inputCost = inputTokens / 1_000_000 * inputPer1M
outputCost = outputTokens / 1_000_000 * outputPer1M
totalCost = inputCost + outputCost