Skip to content
PicoRank Docs
Website Open app

GraphQL

One request for a graph that would take several over REST — same keys, same rules, same error codes.

The GraphQL endpoint is at https://api.picorank.com/graphql (sandbox: https://api.staging.picorank.com/graphql). It authenticates with the same API keys and enforces the same permissions, plan limits and spending guards as REST — the resolvers call the same functions.

Why it exists

Ranking data is a graph. "For each domain: its slot usage, its scans, its competitors, and every keyword's position history" is one query here and at least four REST calls plus client-side stitching.

query DomainOverview {
  domains {
    host
    slots { used limit available }
    scans { name engines devices geographies }
    competitors { host }
    keywordLists { name keywordCount }
  }
}

Sandbox

GraphiQL is served at the endpoint itself, pre-loaded with worked examples. Paste your key into its Headers tab:

{ "Authorization": "Bearer pr_test_…" }

Open the GraphQL sandbox ↗

It points at staging by default, so exploring cannot spend production money or change production data.

Errors

GraphQL returns 200 with an errors array. Each error carries the same vocabulary as REST in extensions, so one handler serves both:

{
  "errors": [{
    "message": "This account has used 50 of 50 keyword research lookups for the current period.",
    "extensions": {
      "code": "quota_exhausted",
      "status": 402,
      "remedy": "Wait for the reset in meta.resets_at, upgrade, or buy the matching add-on.",
      "meta": { "metric": "research_lookups", "used": 50, "limit": 50 },
      "documentation_url": "https://docs.picorank.com/api/errors/quota_exhausted"
    }
  }]
}

Mutations that spend

startJob and addKeywords take dryRun, exactly as their REST counterparts take dry_run. startJob returns reused: true when it joined a job already running rather than starting a new one — so it is never ambiguous whether the call spent anything.

Query limits

  • Maximum nesting depth: 12.
  • Maximum selected fields per request: 5,000.
  • Cost is counted per request, not per operation, so batching several operations into one HTTP call does not step around the limit.

Exceeding either returns query_too_complex with the measured figures and the budget.

When to use REST instead

For a single resource, a simple list, or polling a job, REST is less machinery for the same answer — and it caches. Use GraphQL where the graph shape actually saves round trips.