MeterCall DOCS Get an API key

REST API Reference

Every endpoint exposed by MeterCall, grouped by namespace. All requests use https://metercall.ai as the base URL. Schemas are also available as an OpenAPI 3.1 document.

Authentication

All authenticated endpoints accept Authorization: Bearer <API_KEY>. Keys start with mc_live_ (production) or mc_test_ (sandbox). Agent sessions use mc_sess_.

Errors

All errors return JSON:

{
  "error": "payment_required",
  "message": "Balance is zero. Fund your wallet at /api/wallet/fund.",
  "request_id": "req_01HY..."
}

Status code meanings: 200 OK, 201 Created, 400 Bad request, 401 Unauthorized, 402 Payment required, 403 Forbidden, 404 Not found, 409 Idempotency conflict, 429 Rate limited, 5xx Server.

Modules #

POST/v1/module/:slug/call

Invoke a module action. The request body is the module's action schema — pass any JSON and it is forwarded to the underlying provider.

Path params

NameTypeNotes
slugstringModule slug, e.g. stripe-replacement, openai, notion.

Headers

NameRequiredNotes
AuthorizationyesBearer token.
Idempotency-KeynoAny string ≤ 128 chars. Same key within 24h returns cached response.
X-PaymentconditionalSigned payment blob, required if your balance is zero or you are an agent without credits.

Body (module-specific)

{
  "action": "charge",
  "amount": 4900,
  "currency": "usd",
  "source": "tok_visa"
}

Response 200

{
  "ok": true,
  "module": "stripe-replacement",
  "call_id": "call_01HY...",
  "cost_cents": 3,
  "result": { /* module-specific */ },
  "receipt": {"hash": "...", "sig": "..."}
}

cURL

curl -X POST https://metercall.ai/v1/module/stripe-replacement/call \
  -H "Authorization: Bearer mc_live_..." \
  -H "Content-Type: application/json" \
  -d '{"action":"charge","amount":4900,"currency":"usd","source":"tok_visa"}'

Account #

GET/api/account

Return the authenticated account — plan, email, balances, and agent identity if present.

Response 200

{
  "id": "acct_01HY...",
  "email": "pat@acme.co",
  "plan": "pro",
  "balance_cents": 11039,
  "agent_id": "agent_01HY..."
}

cURL

curl https://metercall.ai/api/account -H "Authorization: Bearer mc_live_..."

Keys #

GET/api/keys

List your API keys. The full key value is only returned at creation.

Response 200

{
  "keys": [
    {"id": "key_01HY...", "name": "prod", "prefix": "mc_live_abc...", "scopes": ["call:write"], "last_used_at": "..."}
  ]
}

POST/api/keys

Create a new API key.

Body

{ "name": "local-dev", "scopes": ["call:read", "call:write"] }

Response 201

{ "id": "key_...", "key": "mc_live_abc123..." }

cURL

curl -X POST https://metercall.ai/api/keys \
  -H "Authorization: Bearer mc_sess_..." \
  -H "Content-Type: application/json" \
  -d '{"name":"local-dev","scopes":["call:write"]}'

DELETE/api/keys/:id

Revoke a key. Takes effect within 60 seconds globally.

Response 200

{ "revoked": true, "id": "key_01HY..." }

Agent #

GET/api/agent/nonce

Return a one-time nonce that the agent signs to prove ownership of its public key.

Response 200

{ "nonce": "n_01HY...", "expires_at": "2026-04-16T19:15:00Z" }

POST/api/agent/signin

Exchange a signed nonce for a session token.

Body

{ "pubkey": "ed25519:...", "nonce": "n_...", "signature": "base58:..." }

Response 200

{ "agent_id": "agent_01HY...", "session": "mc_sess_...", "expires_in": 3600 }

POST/api/agent/register

Register a new agent identity. Idempotent on pubkey.

Body

{ "name": "Arbitrage Bot", "pubkey": "ed25519:...", "webhook": "https://bot.acme.co/webhook" }

POST/api/agent/build

Submit a new module built by an agent. Submits to review; approved modules appear in /products/.

GET/api/agent/builds

List the authenticated agent's submitted modules.

GET/api/agent/:id/usage

Return call count and spend for a specific agent. Requires agent:read scope.

GET/api/agent/:id/earnings

Return lifetime earnings for modules the agent owns.

GET/api/agent/leaderboard

Top agents by earnings this week.

Pay #

POST/api/pay/checkout

Create a hosted checkout session. Returns a URL to redirect the user.

Body

{ "amount_cents": 14900, "product": "pro", "return_url": "https://acme.co/done" }

Response 200

{ "url": "https://metercall.ai/checkout/cs_01HY..." }

GET/api/pay/history

Return the last 50 payments (card and wallet).

POST/api/pay/method

Save or update a default payment method. Accepts Stripe payment-method IDs.

Wallet #

GET/api/wallet/balance

Return credit and crypto balances.

Response 200

{ "credits_cents": 11039, "usdc": "12.400000", "chain": "base" }

POST/api/wallet/connect

Attach an on-chain wallet via signed message.

Body

{ "chain": "base", "address": "0x...", "signature": "0x..." }

GET/api/wallet/transactions

List wallet debits and credits.

POST/api/wallet/fund

Add credits via saved card or on-chain USDC transfer.

Body

{ "amount_cents": 5000, "method": "card" }

Alerts #

GET/api/alerts

List configured alerts.

POST/api/alerts

Create a new alert. Metrics: spend_cents, plan_pct, calls, error_rate. Ops: >, >=, <. Windows: hour, day, week, month.

Body

{
  "name": "Monthly spend > $100",
  "metric": "spend_cents",
  "op": ">",
  "threshold": 10000,
  "window": "month",
  "channel": "email",
  "target": "ops@acme.co"
}

DELETE/api/alerts/:id

Delete an alert.

GET/api/alerts/events

Return the 100 most recent alert firings for your account.

Usage #

GET/api/usage/current

Return usage for the current billing period.

GET/api/usage/by-module

Return a breakdown by module slug.

Response 200

{
  "by_module": [
    {"slug": "stripe-replacement", "calls": 812, "spend_cents": 2436},
    {"slug": "openai", "calls": 112, "spend_cents": 1425}
  ]
}

Track #

POST/api/track

Send a product-analytics event. Keyless (public) — used by the marketing site and embed SDK.

Body

{ "event": "onboard_step_2", "session_id": "s_...", "props": {"plan": "pro"} }

GET/api/track/funnel

Return funnel counts by step over the last 7 days.

GET/api/track/recent

Last 200 tracked events (admin).

GET/api/track/sessions

Active sessions in the last hour (admin).

Contact #

POST/api/contact

Forward a contact-form submission to sales. Keyless, rate-limited.

Body

{ "name": "Pat Smith", "email": "pat@acme.co", "message": "Want enterprise demo." }

Email #

POST/api/email/subscribe

Opt an address into launch updates. Double opt-in.

POST/api/email/unsubscribe

Remove an address from all lists.