---
name: gridrouter-customer-integration
description: Integrates an application or agent with GridRouter, one API key and MCP server for go-to-market data vendors — key setup, catalog search, quotes, routed runs and direct endpoint calls, your own vendor keys, waterfalls, logs and live tail, errors, rate limits and idempotency. Use when calling the GridRouter API or connecting an agent to the GridRouter MCP server.
---

# GridRouter customer integration

GridRouter gives you one API, one key and one MCP server for go-to-market data vendors (email finders, enrichment, verification, search and more), with a quality score on every endpoint.

## When to use

- Calling `https://api.gridrouter.io`, connecting an agent to `https://mcp.gridrouter.io/mcp`, or choosing a capability, vendor or waterfall.

## Prerequisites

- An account at https://gridrouter.io and an API key from Settings > API keys. Keys look like `grid_live_…` (real vendors) or `grid_test_…` (sandbox endpoints only). Give the key only the scopes you need: `call`, `run`, `logs:read`, `credentials:write`, `pipelines:read`, `pipelines:write`, `pipelines:run`.
- Store it in an environment variable (`export GRID_API_KEY=…` from your secret manager). Never print it, log it, commit it or paste it into chat or a prompt.
- Machine-readable references: OpenAPI at https://api.gridrouter.io/openapi.json, docs index at https://gridrouter.io/llms.txt (also https://api.gridrouter.io/llms.txt).

## Steps

1. Find what to call (public, no key): `GET /v1/catalog/capabilities?category=people`, `GET /v1/catalog/endpoints?q=email&capability=people.email.find`, `GET /v1/catalog/endpoints/{provider}/{endpoint}` (input JSON Schema, pricing, quality), `GET /v1/catalog/leaderboards/{capability}`.
2. Price it without spending: `POST /v1/quote/{provider}/{endpoint}` with `{"input": {...}}` returns `quote_micro`.
3. Run a capability (GridRouter routes across vendors until one hits; per-success vendors bill only hits):

```bash
curl -sS https://api.gridrouter.io/v1/run/people.email.find \
  -H "Authorization: Bearer $GRID_API_KEY" -H "Idempotency-Key: lead-8841" \
  -H 'content-type: application/json' \
  -d '{"input":{"first_name":"Ada","last_name":"Lovelace","domain":"example.com"},"max_cost_micro":50000,"provider":{"sort":"quality"}}'
```

   Optional body fields: `provider` (`order`, `only`, `ignore`, `allow_fallbacks`, `sort`: price|reliability|latency|throughput|quality, `max_price_micro`), `fields` (return only these output fields), `stop_when` (`hit`|`success`), `credential` (`auto`|`managed`|`byok`), `preset` (`@slug`). Don't know the capability? `POST /v1/run/auto` with your input picks one.
4. Or call one endpoint verbatim: `POST /v1/call/{provider}/{endpoint}` with `{"input": {...}, "max_cost_micro": 50000}`. Async vendors return `202` with a job; poll `GET /v1/jobs/{id}`.
5. Read the cost: every money field is integer micro-USD (1 USD = 1,000,000). Responses carry `cost_micro`, `attempts[]`, and headers `X-Grid-Call-Id`, `X-Grid-Cost-Micro`, `X-Grid-Credential`. Look a call up later with `GET /v1/calls/{id}`; balance at `GET /v1/balance`.
6. Your own vendor keys (BYOK, never charged by GridRouter): Settings > Vendor keys in the dashboard, or the API with scope `credentials:write`: test first with `POST /v1/credentials/{provider}/verify` `{"fields":{"api_key":"…"}}` (nothing stored), save with `PUT /v1/credentials/{provider}` `{"slot":"primary","fields":{"api_key":"…"},"label":"Prod"}`, re-test with `POST /v1/credentials/{provider}/test`, list with `GET /v1/credentials`. An unknown field name returns `invalid_request` with the allowed names in `details.allowed`. Read vendor keys from your secret store; never echo them.
7. Waterfalls (saved multi-vendor recipes; the full workflow is in [gridrouter-waterfalls](../gridrouter-waterfalls/SKILL.md)): list templates with `GET /v1/waterfalls/templates?runnable=true` (public), create and publish one in a call with `POST /v1/waterfalls/from-template` `{"template":"work-email","max_cost_micro":100000}`, or build your own with `POST /v1/waterfalls`; price with `POST /v1/waterfalls/estimate`, publish with `POST /v1/waterfalls/{id}/versions` `{"bump":"minor"}`, run with `POST /v1/waterfalls/{id}/run` `{"input":{...},"max_cost_micro":100000}` (add `"wait": 30` or header `Prefer: respond-async` for long runs; poll `GET /v1/waterfalls/{id}/runs/{run_id}`). Batch up to 1,000 rows: `POST /v1/waterfalls/batch-run`.
8. Logs (scope `logs:read`): `GET /v1/logs` (filters, `limit`, `cursor`), `GET /v1/logs/{id}`, `GET /v1/logs/stats`, `GET /v1/logs/facets`. Live tail: `curl -N "https://api.gridrouter.io/v1/logs/live?format=sse&status=error" -H "Authorization: Bearer $GRID_API_KEY"` (or a WebSocket upgrade); recent events at `GET /v1/logs/live/recent?limit=50`.
9. MCP: point your client at `https://mcp.gridrouter.io/mcp` (Streamable HTTP). Interactive clients sign in with OAuth; headless agents send `Authorization: Bearer $GRID_API_KEY`. Server card: `https://mcp.gridrouter.io/mcp/server-card`. Tools share the REST names (`catalog_search`, `catalog_get`, `quote`, `run`, `call`, `waterfall_templates`, `waterfall_create_from_template`, `waterfall_run`, `logs_list`, …); call `tools/list` to see what your key's scopes allow.

## Verify

- `curl -sS "https://api.gridrouter.io/v1/catalog/endpoints?q=email" | jq '.items[0].id'` works without a key.
- A quote returns `quote_micro`; a run returns `object: "call"` with `hit`, `cost_micro` and `attempts`.
- The call appears in `GET /v1/logs` and in the dashboard's logs page.

## Errors, limits and retries

- Every error body is `{"error":{"code","message","request_id","call_id","retry_after_ms","details"}}`. Common codes: `invalid_request` 400, `unauthorized` 401, `insufficient_balance` and `max_cost_exceeded` 402, `scope_denied`, `budget_blocked`, `vendor_key_required` and `account_frozen` 403, `not_found` 404, `conflict` 409, `idempotency_mismatch` and `strict_filters` 422, `rate_limited` 429, `upstream_error` 502, `provider_capacity_unavailable` and `grid_saturated` 503, `upstream_timeout` 504.
- On 429 and 503 wait for `Retry-After` (or `retry_after_ms`), then retry with backoff; `RateLimit` and `RateLimit-Policy` headers show your remaining budget. Don't retry 4xx other than 409 and 429 without changing the request.
- Send `Idempotency-Key` (1–128 characters) on every run, call and create. A retry with the same key and body within 24 hours replays the stored response for free; the same key with a different body is `422 idempotency_mismatch`; one still in flight is `409 conflict`.
- Failed calls, and misses on per-success vendors, are not charged. Set `max_cost_micro` (or header `X-Grid-Max-Cost` in USD) on every paid request.

## Safety rules

- Keep GridRouter and vendor keys in env vars or a secret manager; never print, log or commit them.
- Use `grid_test_` keys while developing; switch to `grid_live_` only when ready to spend.
- Only look up people and companies you have a lawful basis to process.
