Services Catalog
The services catalog is MarginFront’s record of every model and non-LLM service it can calculate cost for. When you fire a usage event withmodel and modelProvider, MarginFront looks up the catalog entry that matches and uses its rate to compute cost.
Use this endpoint to discover canonical names BEFORE firing events. If your service is in the catalog, sendThe catalog is global. It is not org-scoped. Every authenticated caller sees the same entries. The catalog is read-only via the API. Entries are managed by an internal sync script that pulls from OpenRouter, LiteLLM, and a hand-curated list of non-LLM services.model: '<canonicalName>'andmodelProvider: '<provider>'and cost auto-resolves on ingest. If not, the event still lands but cost stays null (NEEDS_COST_BACKFILL). ThePOST /v1/events/map-modelendpoint can then redirect an unknown name to an existing catalog entry. It cannot create new rates.
List services
Returns paginated catalog entries. Filter by provider, service type, LLM-vs-non-LLM, or full-text search. Method & URL:| Field | Type | Description |
|---|---|---|
provider | string | Filter by lowercase provider name (e.g. openai, google, anthropic, twilio). Case-insensitive. |
serviceType | string | Filter by category (e.g. LLM, Geocoding, Compute, Web Search, Vector Database, SMS). |
isApi | boolean | Filter to non-LLM API entries only (true) or LLM-only (false). Omit for both. |
search | string | Case-insensitive search across canonicalName and displayName. |
page | integer | 1-based page number. Defaults to 1. |
limit | integer | Page size, 1 to 100. Defaults to 50. |
| Field | Description |
|---|---|
id | UUID of the catalog entry. Pass to GET /v1/services/:id for the full record. |
externalId | Source-specific identifier (e.g. openai/gpt-4o, api/cloud-run-cpu-second, litellm/anthropic/claude-sonnet-4-20250514). Useful for tracing where the entry came from. |
canonicalName | The lowercase name to send as model in your usage events. This is what the cost lookup matches against. |
displayName | Human-readable name for UI surfaces. Not used for matching. |
provider | Lowercase provider name to send as modelProvider. |
serviceType | Category label (e.g. LLM, Geocoding, Compute). |
inputCost | Per-unit cost on the input side. Returned as a string-formatted decimal so JS Number precision can’t truncate fractional cents. null when the service does not publish an input-side rate. |
outputCost | Per-unit cost on the output side (LLM output tokens). null for non-LLM services. |
costUnit | Unit the rates are denominated in (e.g. 1M tokens, 1K requests, 1K vCPU-seconds). |
contextWindow | LLM context window size in tokens. null for non-LLM. |
source | Where the entry came from: openrouter, litellm, or curated. |
isApi | true for non-LLM API entries (Cloud Run, Twilio, Google Places, etc.). false for LLM models. |
isActive | false if the entry has been deactivated. The list endpoint filters these out by default. |
Get a single service
| Code | Cause |
|---|---|
404 | The catalog entry does not exist or has been deactivated. |
401 | Missing or invalid API key. |
Using the catalog in your integration
Pattern that avoids theNEEDS_COST_BACKFILL cycle:
- Before adding a new service to your code, call
GET /v1/services?search=<your-service-name>(or?provider=<provider>). - If the response has a matching entry, use its
canonicalNameasmodeland itsproviderasmodelProvider. - Fire usage events. Cost auto-resolves on ingest.
- Map an existing entry. If your service is similar to one in the catalog (e.g. a Google Places sub-endpoint mapping to the bundled
google-placesentry), usePOST /v1/events/map-modelto redirect your unknown name to the existing entry. Cost backfills retroactively for events already saved withcost = null. - Catalog gap. If nothing in the catalog represents your service accurately, fire events anyway. Events are saved with
cost = nullandeventStatus = NEEDS_COST_BACKFILL. Email[email protected]with the service name and your provider’s pricing page; we’ll add it to the catalog.
Programmatic access
The same catalog is available via:- Node SDK:
client.services.list(...)andclient.services.get(id). Documented in the SDK reference. - MCP: the
list_catalog_servicestool. Documented in the MCP tools reference.

