API reference

Normalization and reconciliation API

Public, stateless JSON endpoints for exports from open-source API gateways.

Security boundary

PayAPIKey's hosted endpoints do not accept gateway administrator tokens, channel keys, cookies, or sessions. Native API reads must happen in a local connector/sidecar you control; the hosted service receives stripped billing metadata only.

Endpoints

POST/api/v1/reconcile

Generate summaries, margin, and findings from three canonical ledgers.

POST/api/v1/normalize

Convert a One API-family log response into canonical ledgers.

GET/api/v1/connectors

Read support status, resource paths, field mappings, and limitations.

GET/api/v1/connectors/{connectorId}/manifest

Read one connector's capability, security, and machine-mapping contract.

GET/api/v1/examples/reconciliation

Fetch a runnable canonical input example.

GET/openapi.json

Fetch the machine-readable OpenAPI 3.1 contract.

POST /api/v1/reconcile

The request body must be a canonical ReconciliationInput. downstreamUsage is required; upstream or payment data may be omitted, but the report marks the relevant checks incomplete.

FieldTypeDescription
versionstringOptional input schema version.
currencystringReport currency; defaults to USD. No automatic FX conversion.
periodobjectOptional start/end settlement period.
downstreamUsagearrayRequired downstream consumption-revenue records.
upstreamChargesarrayOptional upstream actual-cost records.
paymentsarrayOptional payment and wallet-funding records.
JSON
{
  "currency": "USD",
  "period": { "start": "2026-07-01T00:00:00Z", "end": "2026-08-01T00:00:00Z" },
  "downstreamUsage": [{
    "requestId": "req_01",
    "occurredAt": "2026-07-10T08:00:00Z",
    "model": "example-model",
    "channelId": "channel_7",
    "status": "success",
    "chargedAmount": "0.024",
    "currency": "USD",
    "tokens": { "input": 1200, "output": 300, "cacheRead": 500 }
  }],
  "upstreamCharges": [{
    "requestId": "req_01",
    "occurredAt": "2026-07-10T08:00:00Z",
    "model": "example-model",
    "status": "success",
    "costAmount": "0.016",
    "currency": "USD"
  }],
  "payments": []
}

Record fields

downstreamUsage[]

FieldTypeDescription
requestIdstringRequired stable identifier for request-level matching.
occurredAtdate-timeRequired ISO 8601 timestamp.
model / channelIdstringModel and channel dimensions.
statusenumsuccess | failed | pending | refunded
chargedAmountnumber | decimal stringRequired amount charged to the customer; decimal strings are recommended.
refundAmount / expectedChargenumber | decimal stringOptional refund and price-snapshot expected charge.
tokensobjectinput, output, cacheRead, cacheWrite, reasoning, media

upstreamCharges[]

FieldTypeDescription
requestIdstringRecommended; exact match to downstream requestId.
upstreamIdstringUpstream bill or request identifier.
occurredAt / modeldate-time / stringRequired.
statusenumsuccess | failed | pending | refunded
costAmountnumber | decimal stringRequired actual upstream cost; decimal strings are recommended.
refundAmount / currencynumber | decimal string / stringOptional refund amount and currency.

payments[]

FieldTypeDescription
transactionIdstringRequired payment transaction identifier.
occurredAtdate-timeRequired.
statusenumsettled | pending | failed | refunded | chargeback
amountnumber | decimal stringRequired captured amount; decimal strings are recommended.
feeAmount / refundAmountnumber | decimal stringProcessor fee and refund.
creditedAmountnumber | decimal stringCredit actually issued to the wallet for funding reconciliation.

POST /api/v1/normalize

Accepts a native New API, One API, or one-hub log response and converts it into canonical input. connector must be a supported ID; logs may be an array or a common paginated response.

JSON
{
  "connector": "new-api",
  "currency": "USD",
  "quotaPerUnit": 500000,
  "logs": { "data": [{ "id": 1, "request_id": "req_01", "created_at": 1783670400, "model_name": "example-model", "quota": 12000 }] }
}

quotaPerUnit must come from the deployed /api/status.data.quota_per_unit value; the number above is illustrative and must not be hard-coded across instances.

Sanitize locally first

The normalizer rejects keys, cookies, sessions, and body fields such as prompt, content, or messages. Channel responses are especially likely to contain keys; keep IDs, models, token counts, and monetary metadata only.

Responses, limits, and errors

  • 200 Successful responses are wrapped in { data: ... }.
  • 400 Invalid JSON-domain fields or ledger values; details contains up to 50 validation messages.
  • 413 Request body exceeds 2 MB.
  • 415 Content-Type is not application/json.
  • Each ledger accepts at most 5,000 records; amounts may be finite non-negative JSON numbers or canonical decimal strings; no currency conversion is performed.
  • The public API permits cross-origin JSON calls, but gateway administrator credentials must never be exposed from a browser.

Download the OpenAPI 3.1 JSON