GraphQL

The same graph, queried as a graph. Available to first-party surfaces today.

Connected panels exchanging data

REST serves the questions integrations ask most: profile this domain, list the vocabulary, tell me what changed. GraphQL serves the cases where the shape of the answer is the point, when one round trip should return a store, its technologies, and their dates together.

Both read the same corpus. Neither is a cache of the other.

Access

EndpointPOST https://api.ongoing.ai/graphql
AuthA service token issued directly by OngoingAI
KeysA workspace API key does not authenticate GraphQL. oai_live_… keys are REST credentials
Browser IDENot served. The endpoint answers POST with a query, nothing else

This is the honest state of it: GraphQL is what our own surfaces use, and access is arranged rather than self-served. If your integration needs it, write to api@ongoing.ai and say what you are building. Everything published in the REST reference is available to any workspace key today, without asking anyone.

A query

query Store($domain: String!) {
  store(domain: $domain) {
    domain
    rank
    firstSeenAt
    lastScannedAt
    technologies {
      active
      confidence
      firstSeenAt
      lastSeenAt
      technology { slug name vendorName }
    }
  }
}
curl https://api.ongoing.ai/graphql \
  -H "Authorization: Bearer YOUR_SERVICE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ store(domain:\"gymshark.com\"){ domain technologies { active technology { slug } } } }"}'

Domains are normalized for you, so GYMSHARK.COM, www.gymshark.com, and a full product URL all resolve to the same store.

What the schema covers

  • store(domain) — corpus identity, rank, first and last observation, catalog summary, and technology edges with their install dates and confidence.
  • technology(slug) — one entry from the canonical vocabulary. The same slugs REST uses.
  • candidates(...) — the evidence queue: relationships claimed by a source and awaiting verification, cursor paginated.
  • storeAnalysis(id) — the status of an analysis started by analyzeStore.
  • Mutations — ingest relationship evidence from a capture, resolve a candidate to a domain, and queue scans. Evidence ingestion is idempotent on the key you supply, so a retry replays the original receipt rather than writing the capture twice.

Reading the answers

Two behaviours are worth knowing before you branch on a response.

An unknown domain is null, not an error. A null store means we have never observed that domain. It is not a statement that the domain is not a store, and treating it as one is the most common way to misread this API.

Absence of a technology is not removal. Edges carry active along with the dates that support it. A technology that stopped appearing is marked inactive once completed observations of comparable scope confirm it, not the first time a scan misses it. The same rule governs the REST profile, and Observations explains it in full.

Which one to use

UseInterface
Enrich a list of domains, in a workflow tool or a scriptREST
One domain, one profile, in a product surfaceREST
A shape REST does not return in one callGraphQL
Writing evidence back into the graphGraphQL

On this page