Getting Started with Wikidata SPARQL

← Wikidata SPARQL API

When to use this API

When you need structured factual data from the world's largest open knowledge graph — entity IDs, properties, relationships, classifications. Wikidata SPARQL is one of the few free APIs where you can ask arbitrary relational queries (joins, filters, counts) against 100M+ items and get structured JSON back. It's surprisingly good for "lateral" questions — what connects two things, what shares a property, what's the count of X — because SPARQL treats relationships as first-class data. For simple key-value lookups ("what is the capital of France?"), a REST country API is faster; reach for this endpoint when the question involves traversing relationships or aggregating across entities.

Finding instances of a Wikidata class

"What are some domestic cats in Wikidata?" Wikidata classifies every entity with an instance of (P31) property. The pattern ?item wdt:P31 wd:Q146 matches entities that are instances of Q146 (domestic cat). The wdt: prefix is the "truthy" shortcut — it returns the best value of a property without qualifiers.

curl "https://query.wikidata.org/sparql?query=SELECT+%3Fitem+%3FitemLabel+WHERE+%7B+%3Fitem+wdt%3AP31+wd%3AQ146+%7D+LIMIT+10" | head -c 10000
{
  "head": {
    "vars": ["item", "itemLabel"]
  },
  "results": {
    "bindings": [
      { "item": { "type": "uri", "value": "http://www.wikidata.org/entity/Q378619" } },
      { "item": { "type": "uri", "value": "http://www.wikidata.org/entity/Q498787" } },
      { "item": { "type": "uri", "value": "http://www.wikidata.org/entity/Q677525" } }
    ]
  }
}

The query declares both ?item and ?itemLabel, but the response only populates ?item. Naming a variable ?XLabel does NOT auto-populate it — you need the SERVICE wikibase:label clause (next vignette). Without it, you get bare Q-IDs: Q378619 is some domestic cat entity, but you can't tell which one from this response. The "type": "uri" marker distinguishes entity references from string values.

Wikidata contains domestic cat entities (Q378619, Q498787, Q677525 and more), but the basic query returns only their Q-IDs without human-readable names. You need the label service to resolve those IDs.

Getting readable names with the label service

"Who are some people in Wikidata?" The previous query returned bare Q-IDs. Add SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } to the WHERE clause and any variable named ?XLabel auto-populates with the label of the entity in ?X.

curl "https://query.wikidata.org/sparql?query=SELECT+%3Fitem+%3FitemLabel+WHERE+%7B+%3Fitem+wdt%3AP31+wd%3AQ5+.+SERVICE+wikibase%3Alabel+%7B+bd%3AserviceParam+wikibase%3Alanguage+%22en%22+%7D+%7D+LIMIT+5" | head -c 10000
{
  "head": {
    "vars": ["item", "itemLabel"]
  },
  "results": {
    "bindings": [
      {
        "item": { "type": "uri", "value": "http://www.wikidata.org/entity/Q42" },
        "itemLabel": { "type": "literal", "value": "Douglas Adams" }
      }
    ]
  }
}

The real story is the type field. "uri" means an entity reference; "literal" means a string value. The label service produces "literal" entries, so you can tell entity references from labels at a glance. Q42 resolves to "Douglas Adams" — not "Douglas Adams (author)" or "Q42/Douglas_Adams", just the clean label. If no English label exists for an entity, the label service falls back to the entity's Q-ID, which is how you detect missing translations.

Wikidata lists Douglas Adams (Q42) among its human entries. The label service resolved the bare URI to the readable name "Douglas Adams" — without it, you'd see only http://www.wikidata.org/entity/Q42.

Pitfalls

One-line summary for the user

I can query the Wikidata knowledge graph — 100M+ entities with their properties and relationships — via SPARQL in a single unauthenticated GET, but you must add the label service to get readable names instead of bare Q-IDs.