ShortcutPosters

Reference

Data endpoints

Static JSON and feeds for every app, game and OS in the catalogue — generated at build time, with no authentication and no request quota. There is no server-side search, no filtering, and no pagination: each endpoint below is a plain file, fetched whole.

Endpoints

The four segment manifests share one shape: count and apps differ, and so does updated — the latest verification-or-addition date within that segment, not catalogue-wide. Everything else is identical, so a client that reads one manifest can read them all. /api/{slug}.json serves one full entry at a time.

Path Returns Entries
/api/index.json The whole catalogue manifest 729
/api/apps.json The app manifest 371
/api/games.json The game manifest 355
/api/os.json The operating-system manifest 3
/api/{slug}.json One entry, with every shortcut 729

Payload schema

Every field actually emitted by /api/{slug}.json, field by field. The lightweight manifest entries in the segment manifests above carry a subset of these same values (slug, name, category, totalShortcuts, lastVerified, hash, page) plus one field of their own: data, the absolute URL of the full payload below for that entry.

Field Type Meaning
slug string URL-safe identifier — also the {slug} in this endpoint's own path.
name string Display name.
category string Raw category id, e.g. "productivity", "gaming", "os".
categoryLabel string Human-readable label for category.
os string[] Desktop OS this shortcut data targets: any of "mac", "win", "linux".
platforms string[] Release availability for games — any of "pc", "xbox", "playstation", "switch", "switch2". Ground truth, independent of what binding data this entry holds: a game listed as "xbox" may still carry keyboard-only shortcuts. Empty for non-games.
website string | null The app's own site, when known.
stores object | null Official storefront URLs present for this entry (appStore, macAppStore, steam, gog, epic) — only existing keys are included.
description string One-line summary.
totalShortcuts number Count of shortcut/command entries across all groups.
added string ISO date the entry joined the catalogue.
lastVerified string | null ISO date a human last checked the data against sources; null if never verified.
sources string[] Official-doc URLs the data was checked against. May be empty.
hasPoster boolean True when at least one live buy channel exists for this entry.
hash string Content-only fingerprint (12 hex chars) — see dataVersion & hash below.
page string Absolute URL of this entry's human-readable page.
groups[] array The shortcut list, grouped by category.
groups[].category string Group heading, e.g. "Editing", "Navigation".
groups[].items[] array Shortcuts or commands in this group.
groups[].items[].name string The action's label.
groups[].items[].mac string, optional Present only when a Mac binding exists.
groups[].items[].win string, optional Present only when a Windows binding exists.
groups[].items[].linux string, optional Present only when a Linux binding exists.
groups[].items[].gamepad string, optional Canonical gamepad binding (games only).
groups[].items[].type "command", optional Present only for typed-command entries; absent means a key-chord shortcut.

dataVersion and hash

Every manifest carries a top-level dataVersion, rolled up from every app's own hash. Each app's hash fingerprints one subset of that entry — slug, name, category, os, platforms, lastVerified, and every shortcut and binding in the entry — but not the rest of the payload: categoryLabel, website, stores, description, totalShortcuts, added, sources, hasPoster, page, and the order of the items within each group — which follows an editorial priority the payload does not expose — all sit outside it. Editing one of those alone changes the JSON a client receives but moves neither the per-app hash nor dataVersion. So comparing dataVersion, then per-app hash, reliably catches changed shortcuts, bindings, or a new verification date — it is not a full-payload integrity check.

{
  "dataVersion": "e3f1a9c7d5b2846f",
  "apps": [
    {
      "slug": "blender",
      "hash": "9f3a2c1d4b6e",
      "data": "https://shortcutposters.com/api/blender.json"
    }
  ]
}

Feeds

Recently-added entries, as RSS and JSON Feed, one pair per segment.

Segment Format Feed
all XML ShortcutPosters — recently added
all JSON ShortcutPosters — recently added
apps XML ShortcutPosters — recently added apps
apps JSON ShortcutPosters — recently added apps
games XML ShortcutPosters — recently added games
games JSON ShortcutPosters — recently added games
os XML ShortcutPosters — recently added operating systems
os JSON ShortcutPosters — recently added operating systems

Version policy

  • Existing field names never disappear and never change type.
  • Adding a new field is not a breaking change.
  • dataVersion changes exactly when a fingerprinted field changes — see dataVersion and hash above for what that covers.
  • A breaking change would live under a new /api/v2/ path — the current, flat paths stay in place during the transition. /api/v1/ already works today as an alias of those same flat paths.

Terms of use

  • Keyboard shortcuts and gamepad bindings are facts: nobody owns them, and you are free to use them.
  • The compilation is our editorial work — the normalisation, the categories, and the source and verification metadata attached to every entry.
  • Reuse of this data requires visible attribution: credit ShortcutPosters and link to shortcutposters.com.
  • Reselling or redistributing the compiled database, in whole or in substantial part, is not permitted.
  • These terms cover the data only. Logos, icons and cover art shown on the site are their owners' and are not licensed here.

Full terms on the licensing page →

Examples

The games manifest, then one entry's shortcut groups:

# The games manifest, then the detail of one entry
curl -s https://shortcutposters.com/api/games.json | jq '.apps[0]'
curl -s https://shortcutposters.com/api/baldurs-gate-3.json | jq '.groups[0]'

The same walk in JavaScript, following the manifest's own links:

const index = await fetch("https://shortcutposters.com/api/apps.json").then((r) => r.json());
const app = index.apps.find((a) => a.slug === "blender");
const data = await fetch(app.data).then((r) => r.json());
console.log(data.groups.flatMap((g) => g.items).length, "shortcuts");