ServiceGraph API console
endpoint:https://api.servicegraph.co·

ServiceGraph API console

Live docs + playground for the ServiceGraph API. The catalog is organized as datasets, each addressed by an id in the URL: pro_services, business_directory, product_directory, newsletter, podcast, job_board, marketplace. A row is one entry in one dataset, addressed by its row key — an apex domain for most datasets, or a podcastGuid for podcast. The same apex can be a row in more than one dataset (a newsletter and a directory, say) — those are separate rows with separate unlock pricing.

Access model

  • free · bearer required

    List datasets, fetch dataset schemas, search any dataset, view a row's brief — its free fields, defined per dataset (call /v1/datasets/:id for each dataset's brief vs. detail field split). Soft-rate-limited per user.

  • paid · per-row unlock

    Unlock a row's detail block (contact, full description, services, social presence, etc.). One unlock buys N days of access to that row in that dataset. The same apex in a different dataset is a separate unlock. Per-dataset unlock price and TTL come back on GET /v1/datasets and GET /v1/datasets/:id don't hardcode them client-side. New users start with a credit grant; check GET /v1/me/credits for the current balance.

GET endpoints are idempotent — they never charge. Charges only happen on POST /v1/datasets/:id/unlocks. Already-unlocked rows in the request body are returned at cost 0.

Quick start

Get a bearer token from servicegraph.co/profile/api-keys, then paste it into the Account page — the playground will use it for every request. From your own shell:

1. list datasets
curl -H "Authorization: Bearer $TOKEN" \
  'https://api.servicegraph.co/v1/datasets'
# → { "datasets": [ { id, label, description, detail_price_credits, detail_ttl_days, row_count }, ... ] }
2. fetch a dataset's schema (brief + detail field shapes, filters)
curl -H "Authorization: Bearer $TOKEN" \
  'https://api.servicegraph.co/v1/datasets/pro_services'
3. search inside a dataset (free brief rows, with unlock state per row)
curl -H "Authorization: Bearer $TOKEN" \
  'https://api.servicegraph.co/v1/datasets/pro_services/search?filter=industry:legal+state:CA&limit=5'
# results[].unlock = { status: "active"|"none", expires_at }
4. fetch one row (always brief; detail iff already unlocked)
curl -H "Authorization: Bearer $TOKEN" \
  'https://api.servicegraph.co/v1/datasets/pro_services/animalz.co'
5. unlock detail for a batch of rows (one POST, atomic charge)
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"apexes":["animalz.co","bain.com"]}' \
  'https://api.servicegraph.co/v1/datasets/pro_services/unlocks'
# → items[].data.detail populated, billing_total: { charged, balance_after }
# → HTTP 402 if balance < total cost (no partial charge)

After step 5 the row stays unlocked for 30 days — re-running step 4 or a re-search returns the full detail with no further charge until the unlock expires.

Filter DSL

The filter query param on /v1/datasets/:id/search uses a GitHub-search-style mini-DSL — industry:legal state:CA, rating>=4 review_count_total>=20, comma-OR-lists per predicate, -x/NOT for negation. Which fields are legal in filter depends on the dataset — call /v1/datasets/:id/fields to see what's available. The dataset itself is determined by the URL, so a kind: predicate inside filter is rejected with HTTP 400.

→ Full DSL reference + live tester + field catalog

In this console

  • DSL — grammar, examples, live syntax checker, field catalog from /v1/datasets/:id/fields
  • Endpoints — every route, descriptions from /openapi.json
  • Playground — pick an endpoint, fill params, run, see raw + friendly responses, save queries locally
  • Account — paste your bearer token, see balance + spend history