Pebble Appstore API

RESTful API for accessing Pebble watchfaces and apps

Upload and manage your Pebble apps

Public Archive Available

A freely available public archive of Pebble apps and watchfaces hosted on this appstore feed is available at archive.org/details/pebble-appstore-archive

The archive contains 100 zip files (pebble-apps-batch-000.zip through pebble-apps-batch-099.zip), each containing ~150 apps with metadata, icons, screenshots, and PBW files. A daily backup syncs any updated apps to the affected batch files.

Base URL

https://appstore-api.repebble.com

Common Query Parameters

hardware

Platform filter: aplite, basalt, chalk, diorite, emery, flint, gabbro
Default: basalt

limit

Number of results per page (max 100)
Default: 20

offset

Pagination offset
Default: 0

sort

Sort order: hearts, updated
Default: updated

API Endpoints

App visibility: Listed apps appear in search and browsing. Unlisted apps are available through direct ID/UUID lookups, bulk ID lookups, and PBW downloads, but do not appear in discovery. Hidden apps and apps under DMCA takedown return 404 for direct lookups and downloads, and appear in the bulk endpoint’s missing list. Only published releases appear in public app responses. Existing response formats and hardware filtering are unchanged. Cached app details may take up to 10 minutes to expire; previously issued download links may remain valid for up to two hours.
GET/api/v1/apps/id/{id}

Get a specific app by ID

latest_release.settings_page_state values:no_page,page_loads,page_doesnt_load.
latest_release.companion_android_state values:no_companion,companion_loads,companion_doesnt_load.
latest_release.companion_ios_state values:no_companion,companion_loads,companion_doesnt_load.

curl "https://appstore-api.repebble.com/api/v1/apps/id/52f52af23f5d4600c5000946?hardware=basalt"
Example Response
{
  "data": [{
    "author": "legend",
    "capabilities": [],
    "category": "Faces",
    "category_id": "528d3ef2dc7b5f580700000a",
    "compatibility": {
      "aplite": { "supported": true, "firmware": { "major": 3 } },
      "basalt": { "supported": true, "firmware": { "major": 3 } },
      ...
    },
    "hardware_platforms": [
      {
        "sdk_version": null,
        "pebble_process_info_flags": null,
        "name": "aplite",
        "description": "Chinese Calendar",
        "images": { "icon": "...", "list": "...", "screenshot": "..." }
      },
      ...
    ],
    "description": "Chinese Calendar",
    "hearts": 115,
    "id": "52f52af23f5d4600c5000946",
    "latest_release": {
      "id": "52f52b2814d68cdfe900090c",
      "pbw_file": "https://...",
      "settings_page_state": "no_page",
      "companion_android_state": "no_companion",
      "companion_ios_state": "no_companion",
      "version": "1.0.0"
    },
    "list_image": { "144x144": "...", "80x80": "..." },
    "screenshot_images": [{ "144x168": "..." }],
    "title": "农历 Chinese Calendar",
    "type": "watchface",
    "uuid": "024f4029-2cb8-472e-8419-64c0694c82bb"
  }],
  "limit": 1,
  "offset": 0,
  "links": { "nextPage": null }
}
POST/api/v1/apps/bulk

Get multiple apps by IDs in a single request (max 500 IDs)

Request Body (JSON):

ids: string[]hardware?: string

Response:

Returns data (array of apps) and missing (array of unfound IDs)

curl -X POST "https://appstore-api.repebble.com/api/v1/apps/bulk" \
-H "Content-Type: application/json" \
-d '{"ids": ["52f52af23f5d4600c5000946", "5299cdf7e627ce114700006f"], "hardware": "basalt"}'
Example Response
{
  "data": [
    { "id": "52f52af23f5d4600c5000946", "title": "农历 Chinese Calendar", ... },
    { "id": "5299cdf7e627ce114700006f", "title": "Another App", ... }
  ],
  "missing": ["invalid-id-here"]
}
GET/api/v1/apps/dev/{developerId}

Get all apps by a specific developer

Parameters:

hardwarelimitoffsetsort
curl "https://appstore-api.repebble.com/api/v1/apps/dev/52aa4bf57314cae60a000004?hardware=basalt&limit=20"
Example Response
{
  "data": [
    { "id": "...", "title": "App 1", "author": "Developer Name", ... },
    { "id": "...", "title": "App 2", "author": "Developer Name", ... }
  ],
  "limit": 20,
  "offset": 0,
  "links": { "nextPage": "/api/v1/apps/dev/...?limit=20&offset=20" }
}
GET/api/v1/apps/category/{slug}

Get all apps in a category

Parameters:

hardwarelimitoffsetsort
curl "https://appstore-api.repebble.com/api/v1/apps/category/health-and-fitness?hardware=basalt&limit=20"
Example Response
{
  "data": [
    { "id": "...", "title": "Fitness App", "category": "Health & Fitness", ... },
    { "id": "...", "title": "Step Counter", "category": "Health & Fitness", ... }
  ],
  "limit": 20,
  "offset": 0,
  "links": { "nextPage": "/api/v1/apps/category/health-and-fitness?limit=20&offset=20" }
}
GET/api/v1/apps/collection/{slug}/{typeString}

Get apps from a collection

Collection Slugs:

  • most-loved - Most hearted apps
  • all - All apps
  • all-generated - Generated watchfaces
  • index-default - Default plugins for Index agent

Type Strings:

  • watchfaces
  • watchapps-and-companions
  • plugins

Parameters:

hardwarelimitoffsetsourcesettings
source

Filter by source code availability: available (only apps with source), none (only apps without source)
Default: no filter (all apps)

settings

Filter by settings page health: available (only apps whose latest release has no settings page, or has a verified working settings page)
Default: no filter (all apps)

curl "https://appstore-api.repebble.com/api/v1/apps/collection/most-loved/watchfaces?hardware=basalt&limit=20"
curl "https://appstore-api.repebble.com/api/v1/apps/collection/all/watchapps-and-companions?hardware=basalt&source=available"
curl "https://appstore-api.repebble.com/api/v1/apps/collection/all/watchapps-and-companions?hardware=basalt&settings=available"
curl "https://appstore-api.repebble.com/api/v1/apps/collection/index-default/plugins"
Example Response
{
  "data": [
    { "id": "...", "title": "Popular Watchface", "hearts": 1234, ... },
    { "id": "...", "title": "Another Favorite", "hearts": 987, ... }
  ],
  "limit": 20,
  "offset": 0,
  "links": { "nextPage": "/api/v1/apps/collection/most-loved/watchfaces?limit=20&offset=20" }
}
POST/api/v1/apps/id/{id}/heart

Add a heart to an app. Requires Firebase authentication via Bearer token.

Headers:

Authorization: Bearer <firebase-id-token>
curl -X POST "https://appstore-api.repebble.com/api/v1/apps/id/52f52af23f5d4600c5000946/heart" \
-H "Authorization: Bearer YOUR_FIREBASE_TOKEN"
DELETE/api/v1/apps/id/{id}/heart

Remove a heart from an app. Requires Firebase authentication. Idempotent — returns 200 even if no heart existed.

Headers:

Authorization: Bearer <firebase-id-token>
curl -X DELETE "https://appstore-api.repebble.com/api/v1/apps/id/52f52af23f5d4600c5000946/heart" \
-H "Authorization: Bearer YOUR_FIREBASE_TOKEN"
GET/api/v1/apps/id/{id}/heart

Check if the current user has hearted an app. Requires Firebase authentication.

Headers:

Authorization: Bearer <firebase-id-token>
curl "https://appstore-api.repebble.com/api/v1/apps/id/52f52af23f5d4600c5000946/heart" \
-H "Authorization: Bearer YOUR_FIREBASE_TOKEN"
POST/api/v1/apps/{id}/contact-developer

Send an email message to the developer of an app. Requires a Firebase ID token and a verified email. Your email is never shared with the developer; messages are relayed through mail.repebble.com. Rate limited to 5 messages per hour, 20 per day per sender.

Headers:

Authorization: Bearer <firebase-id-token>

Body (multipart/form-data):

  • message — required, 1–5000 chars
  • attachment — optional, 0–5 files, ≤2MB each, ≤10MB total (executables blocked)
curl -X POST "https://appstore-api.repebble.com/api/v1/apps/52f52af23f5d4600c5000946/contact-developer" \
-H "Authorization: Bearer YOUR_FIREBASE_TOKEN" \
-F "message=Loving your app!"
GET/api/v1/users/me

Get current user info including list of hearted app IDs. Requires Firebase authentication.

Headers:

Authorization: Bearer <firebase-id-token>
curl "https://appstore-api.repebble.com/api/v1/users/me" \
-H "Authorization: Bearer YOUR_FIREBASE_TOKEN"
GET/api/v1/home/{typeString}

Get home page data including banners, categories, collections, onboarding recommendations per platform, and featured apps

Type Strings:

watchfaceswatchapps-and-companionsallplugins

Parameters:

hardwarelimitoffset
curl "https://appstore-api.repebble.com/api/v1/home/watchfaces?hardware=basalt"
curl "https://appstore-api.repebble.com/api/v1/home/watchapps-and-companions?hardware=basalt"
curl "https://appstore-api.repebble.com/api/v1/home/plugins"
Example Response
{
  "banners": [],
  "categories": [
    { "id": "...", "name": "Faces", "slug": "faces", "color": "ffffff" },
    { "id": "...", "name": "Tools & Utilities", "slug": "tools-and-utilities", "color": "..." }
  ],
  "collections": [
    {
      "slug": "most-loved",
      "name": "Most Loved",
      "application_ids": ["...", "..."],
      "links": { "apps": "/api/v1/apps/collection/most-loved/watchfaces" }
    }
  ],
  "onboarding": {
    "aplite": ["appid1", "appid2"],
    "basalt": ["appid1", "appid2"],
    "chalk": ["appid1", "appid2"]
  },
  "data": [
    { "id": "...", "title": "Featured App", ... }
  ],
  "limit": 20,
  "offset": 0,
  "links": { "nextPage": null }
}

Plugins

A plugin is a .pbw whose appinfo.json contains a plugin block. It runs on the phone and exposes sources (data) and actions (tools) to the Pebble app and Index.

App types: a pbw with a plugin block and no watch binary has type: "plugin". It is compatible with every watch and passes hardware filtering. A watchapp or watchface that also carries a plugin keeps its type, and is listed with watchapps or watchfaces and with plugins. The watchfaces, watchapps-and-companions and all type strings never return plugin-only apps, so existing clients are unaffected.

Listings: use the plugins type string with /api/v1/home and /api/v1/apps/collection. These return type: "plugin" apps, and watchapps and watchfaces whose plugin isn't null. Plugins have their own categories (Productivity, Smart Home, Music & Media, Finance & News, Utilities).

FIELDSmanifest_version, uses_permissions, pebblekit2_packages

On every app object, from the latest release's appinfo.json, so the Pebble app can ask for permissions before installing. Apply to the whole app (watchapp, PKJS and plugin).

manifest_version

appinfo.json manifestVersion, 1 when absent. Below 2 the app predates permissions: uses_permissions is ignored and a plugin never loads.

uses_permissions

appinfo.json usesPermissions, as [{name, parameters}]. Internet lists hosts in parameters.domains; another plugin's permission has a plugin uuid.

pebblekit2_packages

Android packages of the app's PebbleKit 2 companion (appinfo.json companionApp.android.apps[].package).

FIELDplugin

Present on every app object returned by the endpoints above. null when the app carries no plugin.

description

What the plugin does. Also read by the LLM in Index.

sources

Data the plugin serves: {category, items, properties, supports_multiple}.

actions

Tools the plugin offers: {name, description, destructive, requires_confirmation}. Parameter schemas are in manifest.

oauth_connectors

Hosted OAuth connectors the plugin declares, as [{slug}]. Sign-in goes through /api/oauth/broker, keyed by the app UUID and slug.

config_page

Settings page: a file inside the pbw or an https URL. null if none.

manifest

The appinfo.json plugin block, verbatim. Clients that load plugins should use this.

curl "https://appstore-api.repebble.com/api/v1/apps/id/20415cd5ebe281b69ed9ee53"
Example Response
{
  "data": [{
    "title": "Todoist",
    "type": "plugin",
    "uuid": "0d520cba-326c-4a22-a269-d1ab1ae38977",
    "category": "Productivity",
    "compatibility": {
      "aplite": { "supported": true, "firmware": { "major": 3 } },
      ...
    },
    "hardware_platforms": [],
    "latest_release": { "pbw_file": "https://...", "version": "1.0.0", ... },
    "manifest_version": 2,
    "uses_permissions": [
      { "name": "Internet", "parameters": { "domains": ["api.todoist.com"] } }
    ],
    "pebblekit2_packages": [],
    "plugin": {
      "description": "Creates Todoist tasks as reminders...",
      "sources": [
        { "category": "reminders", "items": ["list"], "properties": {}, "supports_multiple": false }
      ],
      "actions": [
        { "name": "create_reminder", "description": "...", "destructive": false, "requires_confirmation": false }
      ],
      "oauth_connectors": [{ "slug": "todoist" }],
      "config_page": "config.html",
      "manifest": { "description": "...", "oauth": { "todoist": {} }, ... }
    },
    ...
  }],
  "limit": 1,
  "offset": 0,
  "links": { "nextPage": null }
}

Copyright and Complaints

For copyright infringement claims, content removal requests, or other complaints regarding apps or content hosted on this platform, please contact us at appstore@repebble.com. We will review and respond to all legitimate requests in a timely manner.

Changelog

  • 2026-10-07Permissions: manifest_version, uses_permissions and pebblekit2_packages on every app object. Removed plugin.permissions.
  • 2026-10-05Plugins: plugins type string for /api/v1/home and /api/v1/apps/collection, a plugin field on every app object, the plugin app type, and the index-default collection.
  • 2026-09-17Unlisted apps: returned by /api/v1/apps/id and /api/v1/apps/bulk, but left out of home, collection, category and developer listings.
  • 2026-04-22New POST /api/v1/apps/{id}/contact-developer and a contactable flag on app objects. Hardware filtering in home and collection listings uses only the latest published release.