Documentation

Gameplainer API
Back to Documentation

Posted: December 9th, 2024

Gameplainer.com helps you monitor mentions of your brand or product across popular social platforms, including Reddit, BlueSky, X (formerly Twitter), YouTube, Twitch and Google Alerts.

With the Gameplainer API, you can seamlessly access these mentions via web requests, making it easy to integrate real-time brand monitoring into your custom dashboards, analytics tools, customer support systems, or any other application.

Getting started

  1. Sign up to Gameplainer, and subscribe to a Premium account
  2. Go to your user settings page, and scroll down to API Key settings, and click the "Generate API Key" button



    API Key settings - push the button to get an API key

    API Key settings - push the button to get an API key

  3. Once you've created an API Key, it will be displayed on the page



    API Key settings - displaying an API Key

    API Key settings - displaying an API Key

  4. Click "Copy" and it'll be copied to your clipboard

Reference

Basics

All queries need a valid API Key, which must be passed as a header parameter as shown in the examples for each of the end points.

Date formats

Any start_date or end_date parameter accepts either of:

  • Unix epoch seconds, eg 1733666480 (2024-12-08 14:01:17 UTC).
  • A date or datetime string, eg 2024-12-08 or 2024-12-08T14:01:17Z.

Strings that include a timezone offset (a trailing Z or +02:00) are honored as written. A string with no offset is interpreted as UTC, so include an offset if you need a specific zone.

If a date parameter is present but cannot be read as either form, the request returns an error instead of silently ignoring the filter. For example, {"success": false, "error": "start_date must be a unix timestamp (seconds, post-2024) or a parseable date"}. Epoch values must be after 2024-01-01.

Errors

Errors are returned as {"success": false, "error": "..."} with a 200 status, except for authentication and rate limiting, which use 401, 403 and 429.

Error messages name the specific problem rather than a generic one, so an unexpected empty result is worth reading carefully. A request that is accepted but matches nothing returns success: true with an empty data array, never an error.

Endpoint: Query/List

Returns all of your searches. Optionally filter to a single source type.

https://gameplainer.com/api/query/list

Parameters

Name Required Values Description
type optional reddit, twitter, youtube, bluesky, google_alert, steam, twitch If specified, only searches of that source are returned. x is accepted as an alias for twitter, and google_alerts for google_alert.

Response fields

Field Description
id The search's hash key. Pass it as forum_id to Query/Search or Query/Streams.
type The source this search reads.
description Human-readable summary of what the search does, including the game name where relevant.
frequency How often Gameplainer checks this source for you: minute, hour or day, set by your account level.
results_total Total results stored for this search. For twitch this counts broadcast sessions; see vods_total for recordings.
last_searched Unix timestamp of the last time this source was checked.
search The raw search term. Absent for sources that track a game rather than a term, such as twitch and steam.
app_id The game this search tracks, as a game hash key. Pass it as app_id to Query/Streams. Only present when the search tracks a game.
game The game's name. Only present when the search tracks a game.
vods_total twitch only. Number of stored VODs (recordings) for the game.
followers_filter Minimum-audience filter (reddit karma, youtube subscribers), when one is set.

Example use

All of your searches:

curl -X GET "https://gameplainer.com/api/query/list" \
   -H "Authorization: YOUR_API_KEY"

Only your Twitch searches:

curl -X GET "https://gameplainer.com/api/query/list?type=twitch" \
   -H "Authorization: YOUR_API_KEY"

Example response

{
    "success": true,
    "data": [
    {
        "id": "vPt3Or",
        "type": "reddit",
        "description": "SubReddit: 'indiegames' searching for `twister`",
        "frequency": "hour",
        "results_total": 19,
        "last_searched": 1733692122,
        "search": "twister",
        "reddit_search_type": "comments",
        "mute_subreddits": "noisysubbredditexample, freeindiegames",
        "subreddits": null
    },
    {
        "id": "KqtWmJ",
        "type": "youtube",
        "description": "YouTube videos matching `twister`",
        "frequency": "hour",
        "results_total": 110,
        "last_searched": 1733692120,
        "search": "twister",
        "followers_filter": 1000
    },
    {
        "id": "X1t1XA",
        "type": "twitch",
        "description": "Twitch streams for Twister",
        "frequency": "minute",
        "results_total": 8121,
        "last_searched": 1768409143,
        "app_id": "Qd3R8x",
        "game": "Twister",
        "vods_total": 6704
    }]
}

Endpoint: Query/Search

Returns a JSON object containing results matching your searches, newest first.

Results are cursor-paginated. Every response includes a meta object with the cursors for the current page, so you can page backwards through history or poll forward for new results without tracking offsets.

https://gameplainer.com/api/query/search

Parameters

Name Required Values Description
type optional reddit, twitter, youtube, bluesky, google_alert, steam, twitch If not specified, results are not filtered by source. google_alerts is accepted as an alias for google_alert.
forum_id optional a forum hash key, eg vPt3Or The id of one of your searches (as returned by Query/List). Restricts results to that single source/channel. Must be a search belonging to your account.
sub_type optional stream, vod twitch only, ignored for every other source. Picks what a Twitch query returns: broadcast sessions (the default) or recordings. See Twitch.
start_date optional Unix epoch seconds (eg 1733666480) or a date/datetime string (eg 2024-12-08 or 2024-12-08T14:01:17Z). See Date formats. If specified, only results found by Gameplainer at or after this time are returned. A present-but-invalid value returns an error.
end_date optional Unix epoch seconds (eg 1733666480) or a date/datetime string (eg 2024-12-08 or 2024-12-08T14:01:17Z). See Date formats. If specified, only results found by Gameplainer at or before this time are returned. A present-but-invalid value returns an error.
start_after optional a result hash key, eg KaMiZG Returns results OLDER than this result. Pass the meta.cursor_bottom from your previous response to fetch the next (older) page. Only valid with sort=recent.
start_before optional a result hash key, eg Gxi0WE Returns results NEWER than this result. Pass the meta.cursor_top from your most recent response to fetch results that have arrived since. Only valid with sort=recent.
sort optional recent (default), likes, replies, reposts, quotes, bookmarks, views, engagement Ordering. recent returns newest first with cursor paging. Any other value ranks by that engagement metric, highest first, and uses page-based paging (see Sorting by engagement). Twitch accepts only recent and views.
page optional an integer 1 or greater Page number for engagement sorts. Defaults to 1. Ignored when sort=recent.
num_per_page optional an integer between 1 and 50 If specified, only this many items will be returned per query. By default this will be 50

Paging through results

Each response includes a meta block:

Field Description
count Number of results in this page
cursor_top Hash key of the newest result in this page
cursor_bottom Hash key of the oldest result in this page
has_more true if more results exist in the direction you paged
last_searched Unix timestamp of when the source was last checked. Only returned when forum_id is supplied.
sub_type Which Twitch sub-type answered the query. Only returned for twitch.

To walk backwards through history, repeat the request passing start_after=<cursor_bottom> until has_more is false. To poll for new results, store cursor_top and pass it as start_before on your next call.

Cursors belong to the feed that produced them. A cursor from a Twitch sub_type=stream page is not valid on a sub_type=vod page, and passing one across returns an error rather than a wrong page.

Engagement metrics

Where a source exposes per-result engagement, the result includes a metrics object. This is how you rank X (Twitter) posts by engagement.

Field Description
likes Like count
replies Reply count. On X this is what the platform shows as comments.
reposts Repost / retweet count
quotes Quote-post count
bookmarks Bookmark count
views View count
updated_at ISO8601 datetime (UTC) of the last time these counts were refreshed, or null if they have only the value captured when the post was first found

The metrics object is only present when at least one metric is available, so check for its presence before reading it. For X results the top-level rating and comments fields are intentionally null; engagement lives in metrics. Counts are captured when a post is first found and best-effort refreshed afterwards, so recent posts may still have their counts climbing; updated_at tells you how fresh they are.

Sorting by engagement

By default results come back newest first. Pass sort to rank by engagement instead, highest first. This is the simplest way to pull the top posts for a weekly report.

sort value Ranks by
recent Newest first (default). Uses cursor paging.
likes Like count
replies Reply count
reposts Repost / retweet count
quotes Quote-post count
bookmarks Bookmark count
views View count
engagement Composite: likes + reposts + quotes + replies

Engagement sorts use page-based paging rather than cursors. Combine sort with start_date / end_date to bound the window, set num_per_page (up to 50), and walk with page (1, 2, 3, ...) until has_more is false. The cursor parameters start_after and start_before are only valid with sort=recent; passing them alongside a different sort returns an error.

The response meta for an engagement sort returns count, sort, page, and has_more (no cursor_top / cursor_bottom). Posts with no value for the chosen metric sort last. Because counts are refreshed on a best-effort basis, rankings of very recent posts can still shift slightly as their numbers settle.

Example: top X posts of the week by engagement

curl -X GET "https://gameplainer.com/api/query/search?type=twitter&start_date=2024-12-02&end_date=2024-12-08T23:59:59Z&sort=engagement&num_per_page=25" \
   -H "Authorization: YOUR_API_KEY"

The second page:

curl -X GET "https://gameplainer.com/api/query/search?type=twitter&start_date=2024-12-02&end_date=2024-12-08T23:59:59Z&sort=engagement&num_per_page=25&page=2" \
   -H "Authorization: YOUR_API_KEY"

Twitch

Twitch works through the same endpoint, envelope and cursors as every other source, but the underlying data is broadcast sessions and recordings rather than posts, so a few things differ.

sub_type picks what you get.

  • sub_type=stream (the default) returns broadcast sessions. Each session carries a vods array holding the recordings of that broadcast, so the common case needs one call.
  • sub_type=vod returns recordings as their own items. This is the only way to reach highlights and uploads, which have no parent session.

The two are separate feeds rather than one merged list, because a merged list would return most broadcasts twice: once as the session, then again as its own recording a few hours later.

sort accepts only recent and views. Twitch reports no like, repost, quote or bookmark counts. For a session, views is the peak concurrent viewer count, which is the only audience figure Twitch reports for a live broadcast. For a VOD it is the cumulative view count. Both keep moving after the fact, so sort=views uses page-based paging like the other engagement sorts.

live=true restricts a sub_type=stream query to broadcasts that are still on air.

Recordings expire. Twitch keeps archives for 7 days, or 14 for Affiliate, Partner, Turbo and Prime channels. A stream's vods array is empty until Twitch finishes encoding, and empty again once the archive has gone. Highlights and uploads are permanent. expired on a VOD tells you its URL no longer resolves and its view_count is final.

For per-broadcast detail (thumbnails, viewer snapshots, streamer profile) use Query/Streams instead, which is organised by game rather than by search.

Example: this week's Twitch broadcasts for a game

curl -X GET "https://gameplainer.com/api/query/search?type=twitch&start_date=2024-12-02&num_per_page=25" \
   -H "Authorization: YOUR_API_KEY"

The most-watched recordings instead:

curl -X GET "https://gameplainer.com/api/query/search?type=twitch&sub_type=vod&sort=views&num_per_page=25" \
   -H "Authorization: YOUR_API_KEY"

Example use

Most recent results across all your searches:

curl -X GET "https://gameplainer.com/api/query/search" \
   -H "Authorization: YOUR_API_KEY"

Results for a single search/channel, 25 at a time:

curl -X GET "https://gameplainer.com/api/query/search?forum_id=vPt3Or&num_per_page=25" \
   -H "Authorization: YOUR_API_KEY"

The next (older) page:

curl -X GET "https://gameplainer.com/api/query/search?forum_id=vPt3Or&num_per_page=25&start_after=XPipEp" \
   -H "Authorization: YOUR_API_KEY"

Results within a date window, using a date string:

curl -X GET "https://gameplainer.com/api/query/search?forum_id=vPt3Or&start_date=2024-12-01&end_date=2024-12-08T23:59:59Z" \
   -H "Authorization: YOUR_API_KEY"

Example response

{
    "success": true,
    "data": [
        {
            "id": "Gxi0WE",
            "datetime": "2024-12-09T08:26:18.571Z",
            "source": "bluesky",
            "source_id": "at://did:plc:lzwscnvcbkpdytcjvsixfyar/app.bsky.feed.post/3lcucjahwck2x",
            "sub_type": null,
            "search": "twister",
            "url": "https://bsky.app/profile/chrisvasselli.bsky.social/post/3lcucjahwck2x",
            "user_name": "chrisvasselli.bsky.social",
            "title": "Post",
            "body": "Things I learned at the Nintendo Museum today: Nintendo published Twister in Japan.",
            "rating": null,
            "comments": "1",
            "followers": "950",
            "language": null,
            "nsfw": null,
            "image_thumbnail_url": null
        },
        {
            "id": "XPipEp",
            "datetime": "2024-12-08T08:00:39.000Z",
            "source": "twitter",
            "source_id": "1865700000000000000",
            "sub_type": "tweet",
            "search": "twister",
            "url": "https://twitter.com/somegamer/status/1865700000000000000",
            "user_name": "somegamer",
            "title": "Tweet",
            "body": "just hit a new personal best on Twister, this game lives in my head rent free",
            "rating": null,
            "comments": null,
            "followers": "4820",
            "language": "en",
            "nsfw": null,
            "image_thumbnail_url": null,
            "metrics": {
                "likes": 312,
                "replies": 18,
                "reposts": 26,
                "quotes": 4,
                "bookmarks": 41,
                "views": 20544,
                "updated_at": "2024-12-08T20:13:20.000Z"
            }
        }
    ],
    "meta": {
        "count": 2,
        "cursor_top": "Gxi0WE",
        "cursor_bottom": "XPipEp",
        "has_more": true,
        "last_searched": 1733692122
    }
}

Example response: Twitch broadcasts

{
    "success": true,
    "data": [
        {
            "id": "Gxi0WE",
            "datetime": "2024-12-09T18:02:11.000Z",
            "source": "twitch",
            "source_id": "40987654321",
            "sub_type": "stream",
            "search": null,
            "url": "https://www.twitch.tv/somestreamer",
            "user_name": "somestreamer",
            "title": "twister speedrun attempts!",
            "body": null,
            "rating": null,
            "comments": null,
            "followers": 95000,
            "language": "en",
            "nsfw": false,
            "image_thumbnail_url": "https://static-cdn.jtvnw.net/.../thumb.jpg",
            "metrics": {
                "views": 1820,
                "updated_at": "2024-12-09T20:24:53.000Z"
            },
            "live": false,
            "end_time": "2024-12-09T20:24:53.000Z",
            "duration_minutes": 142,
            "peak_viewers": 1820,
            "current_viewers": 0,
            "helix_stream_id": "40987654321",
            "game": "Twister",
            "streamer": {
                "name": "SomeStreamer",
                "login": "somestreamer",
                "twitch_id": "123456789",
                "followers": 95000,
                "profile_image_url": "https://static-cdn.jtvnw.net/.../profile.png"
            },
            "vods": [
                {
                    "id": "Ka9iZG",
                    "vod_type": "archive",
                    "title": "twister speedrun attempts!",
                    "url": "https://www.twitch.tv/videos/2312345678",
                    "published_at": "2024-12-09T20:24:53.000Z",
                    "duration_seconds": 8562,
                    "view_count": 4300,
                    "views_updated_at": "2024-12-11T06:00:00.000Z",
                    "thumbnail_url": "https://static-cdn.jtvnw.net/.../vod.jpg",
                    "expired": false
                }
            ]
        }
    ],
    "meta": {
        "count": 1,
        "cursor_top": "Gxi0WE",
        "cursor_bottom": "Gxi0WE",
        "has_more": true,
        "sub_type": "stream",
        "last_searched": 1768409143
    }
}

Endpoint: Query/Streams

Returns Twitch stream sessions for one of your games, newest first, with the recordings of each session nested.

A game is identified either by app_id (a game hash key, as returned by Query/List) or by forum_id (one of your searches, resolved to its game). You can only request streams for games you track. Results are cursor-paginated using the same scheme as Query/Search.

app_id is a Gameplainer game hash key such as Qd3R8x, not a Steam AppID. Take it from the app_id field of Query/List.

https://gameplainer.com/api/query/streams

Parameters

Name Required Values Description
app_id Required (or forum_id) a game hash key, eg Qd3R8x A game hash key. Returns streams for that game.
forum_id Required (or app_id) a forum hash key, eg vPt3Or The id of one of your searches (from Query/List). Resolved to the game it tracks.
live optional true, false If true, only currently-live streams (no end time) are returned.
start_date optional Unix epoch seconds (eg 1733666480) or a date/datetime string (eg 2024-12-08 or 2024-12-08T14:01:17Z). See Date formats. If specified, only streams that started at or after this time are returned. A present-but-invalid value returns an error.
end_date optional Unix epoch seconds (eg 1733666480) or a date/datetime string (eg 2024-12-08 or 2024-12-08T14:01:17Z). See Date formats. If specified, only streams that started at or before this time are returned. A present-but-invalid value returns an error.
start_after optional a stream hash key, eg KaMiZG Returns streams OLDER than this one. Pass the meta.cursor_bottom from your previous response to fetch the next page.
start_before optional a stream hash key, eg Gxi0WE Returns streams NEWER than this one. Pass the meta.cursor_top from your most recent response to fetch streams added since.
num_per_page optional an integer between 1 and 50 Items per page. Defaults to 50.

Paging through results

Each response includes a meta block:

Field Description
count Number of streams in this page
cursor_top Hash key of the newest stream in this page
cursor_bottom Hash key of the oldest stream in this page
has_more true if more streams exist in the direction you paged
game The game these streams belong to: app_id and name

To walk backwards through history, repeat the request passing start_after=<cursor_bottom> until has_more is false. To poll for new streams, store cursor_top and pass it as start_before on your next call.

The nested vods array

Each stream carries a vods array holding the recordings of that broadcast.

Field Description
id The VOD's hash key
vod_type archive (an automatic past broadcast), highlight or upload
title The VOD's own title, which the streamer may have changed after the broadcast
url Twitch URL for the recording
published_at When the recording became available. For an archive this is effectively the end of the broadcast.
duration_seconds Length of the recording
view_count Cumulative views
views_updated_at When view_count was last refreshed
thumbnail_url null while Twitch is still encoding
expired true once the archive has aged out, at which point url no longer resolves and view_count is final

The array is empty while Twitch is still encoding, and empty again once an archive has expired: 7 days for most channels, 14 for Affiliate, Partner, Turbo and Prime. It only ever contains recordings matched to this exact broadcast, so a streamer's highlights and uploads do not appear here. Reach those with sub_type=vod on Query/Search.

Example use

Recent streams for a game, by game hash key:

curl -X GET "https://gameplainer.com/api/query/streams?app_id=Qd3R8x&num_per_page=25" \
   -H "Authorization: YOUR_API_KEY"

Recent streams for the game tracked by one of your searches:

curl -X GET "https://gameplainer.com/api/query/streams?forum_id=vPt3Or" \
   -H "Authorization: YOUR_API_KEY"

Only currently-live streams:

curl -X GET "https://gameplainer.com/api/query/streams?app_id=Qd3R8x&live=true" \
   -H "Authorization: YOUR_API_KEY"

Example response

{
    "success": true,
    "data": [
        {
            "id": "Gxi0WE",
            "live": false,
            "start_time": "2024-12-09T18:02:11.000Z",
            "end_time": "2024-12-09T20:24:53.000Z",
            "duration_minutes": 142,
            "peak_viewers": 1820,
            "current_viewers": 0,
            "title": "twister speedrun attempts!",
            "language": "en",
            "is_mature": false,
            "thumbnail_url": "https://static-cdn.jtvnw.net/.../thumb.jpg",
            "helix_stream_id": "40987654321",
            "streamer": {
                "name": "SomeStreamer",
                "login": "somestreamer",
                "twitch_id": "123456789",
                "followers": 95000,
                "profile_image_url": "https://static-cdn.jtvnw.net/.../profile.png"
            },
            "vods": [
                {
                    "id": "Ka9iZG",
                    "vod_type": "archive",
                    "title": "twister speedrun attempts!",
                    "url": "https://www.twitch.tv/videos/2312345678",
                    "published_at": "2024-12-09T20:24:53.000Z",
                    "duration_seconds": 8562,
                    "view_count": 4300,
                    "views_updated_at": "2024-12-11T06:00:00.000Z",
                    "thumbnail_url": "https://static-cdn.jtvnw.net/.../vod.jpg",
                    "expired": false
                }
            ]
        },
        {
            "id": "XPipEp",
            "live": true,
            "start_time": "2024-12-09T16:45:00.000Z",
            "end_time": null,
            "duration_minutes": 73,
            "peak_viewers": 540,
            "current_viewers": 512,
            "title": "chill twister run",
            "language": "en",
            "is_mature": false,
            "thumbnail_url": "https://static-cdn.jtvnw.net/.../thumb2.jpg",
            "helix_stream_id": "40987654399",
            "streamer": {
                "name": "AnotherStreamer",
                "login": "anotherstreamer",
                "twitch_id": "987654321",
                "followers": 12000,
                "profile_image_url": "https://static-cdn.jtvnw.net/.../profile2.png"
            },
            "vods": []
        }
    ],
    "meta": {
        "count": 2,
        "cursor_top": "Gxi0WE",
        "cursor_bottom": "XPipEp",
        "has_more": true,
        "game": {
            "app_id": "Qd3R8x",
            "name": "Twister"
        }
    }
}

Errors

Error Meaning
app_id or forum_id is required Neither selector was supplied.
app_id is not a valid game key. Use the app_id from /api/query/list, not a Steam AppID The value could not be read as a game hash key. Passing a numeric Steam AppID is the usual cause.
forum_id not found or not accessible No search of yours has that id.
that search has no game attached, so it has no streams. Attach a game to it in Gameplainer, or pass app_id instead The search exists but tracks no game, so there is nothing to resolve.
every search you have for that game is disabled You track the game, but all of your searches for it are switched off.
game not found or not accessible You have no rights to that game.

Endpoint: Query/Create

Create a new search for Gameplainer to find mentions on a variety of sources, including Twitter (X), BlueSky, and Reddit.

Each search is limited to one source, so if you want to create multiple sources, you'll need to create multiple searches.

Searches are processed by Gameplainer at a frequency based on your account level.

https://gameplainer.com/api/query/create

Twitch and Steam searches track a game rather than a search term, so they cannot be created through this endpoint. Add them in the Gameplainer app, then read them with Query/List.

Parameters

Name Required Values Description
type Required reddit, twitter, youtube, bluesky, google_alert
search Required string value, maximum 400 characters
follower_filter optional Integer, greater than 0
frequency optional minute, hour, day
search_mentions optional true, false Used for Twitter/X searches: if specified, the value in search will be used as a username, and the returned data from the query will be mentions of that username
exact_search_required optional true, false Used for Twitter/X searches. If specified, exact string literals will be needed in tweets
reddit_search_type Required if type reddit, otherwise not used posts, comments
mute_subreddits optional comma separated list of subreddits without the r/ prefix
subreddits optional comma separated list of subreddits without the r/ prefix

Example use

curl -X GET "https://gameplainer.com/api/query/create?type=reddit&reddit_search_type=posts&search=twister" \
   -H "Authorization: YOUR_API_KEY"
curl -X GET "https://gameplainer.com/api/query/create?type=google_alert&search=https%3A%2F%2Fwww.google.com%2Falerts%2Ffeeds%2F16311364085116075549%2F11892934012420830009" \
   -H "Authorization: YOUR_API_KEY"

Example Response

{
    "success": true,
    "data": [
    {
        "id": "12tdYL",
        "type": "reddit",
        "search": "twister",
        "followers_filter": 30,
        "frequency": "hour",
        "search_mentions": false,
        "exact_search_required": null,
        "reddit_search_type": "new",
        "mute_subreddits": null,
        "subreddits": null,
        "results_total": 0,
        "last_searched": null
    }]
}
{"success": false, "error":"Invalid API key"}
Stay in the loop

Get notified when we publish new articles on game development and player feedback.