--- name: store-api description: Call any App Store Connect API or Google Play Developer API operation that storebound's commands do not wrap, safely - `storebound api list / coverage` to find it, `storebound api apple|play ` (or `METHOD path`) to call it, with GETs run freely, writes dry until the owner sends them with --yes in a terminal, and owner-only operations (submit, release, delete, cancel, prices, testers, replies) needing the operation id typed. Use when the user needs a store feature with no storebound command (custom product pages, Game Center, app clips, users, purchases, sales reports, edit-level Play reads) or asks whether an endpoint is supported. --- # Store API (every endpoint) storebound covers the release journey with high-level commands. Everything else in the App Store Connect API (1303 operations) and the Google Play Developer APIs (Android Publisher v3: 145, Reporting v1beta1: 25) is reachable through `storebound api`, generated from the official specs pinned in `specs/`. Prefer a high-level command whenever one exists (`storebound api coverage` and docs/api-coverage.md show which operations a command already wraps): those are idempotent, check the config and know the store's rules. ## Find the operation - `storebound api list --store apple --search "appCustomProductPages"` (words match the id, method and path; `--json`). - `storebound api coverage`: counts per API and per resource, and how many a command already wraps. - The full table with gates: docs/api-coverage.md in the storebound repository. - Apple ids look like `apps_getCollection`, `appStoreVersions_updateInstance`, `apps_customerReviews_getToManyRelated`. Google ids look like `androidpublisher.edits.tracks.list` (the `androidpublisher.` prefix may be left out). ## Read (runs right away; MCP tool `api_get`) ```sh storebound api apple apps_getCollection --param 'filter[bundleId]=com.example.app' --param 'fields[apps]=name,sku' storebound api apple GET '/v1/apps//appStoreVersions?filter[platform]=IOS' --all-pages storebound api play reviews.list --param packageName=com.example.app --all-pages --json storebound api play POST /v1beta1/apps/com.example.app/crashRateMetricSet:query --body query.json # a read storebound api apple salesReports_getCollection --param ... --out report.gz # non-JSON bodies need --out ``` - Parameters: `--param name=value`, repeatable; lists are comma-separated (Apple) or repeated (Google). Missing required parameters and unknown names are errors before anything is sent. - `--all-pages` follows Apple's `links.next` and Google's page tokens and merges the pages. - Play edit-scoped reads (`edits.*.get/list`) need an edit id, and opening an edit (`edits.insert`) is a write: use `storebound play status` for those reads instead of opening edits by hand. - MCP: `api_get` with `store`, `operation`, `params` (object) and `all_pages`. It runs GET operations only. ## Write (only the owner sends) 1. Run the write without `--yes`: it prints the exact request (method, URL, body; the key is never shown) and sends nothing. Show that to the owner. 2. The owner runs it in their own terminal with `--yes`. Under MCP or in the desktop app a write is never sent, whatever the flags. `--yes` with stdout not a TTY (piped `| tail`, redirected `> out.json`, an agent's shell) is refused: exit 1 and "refused: writes through `storebound api` need an interactive terminal ... Nothing was sent." on stderr (store-pitfalls 78). Never pipe or redirect a write; use the dedicated command the message names. An agent without a terminal sends a plain (non-owner) write with `--yes --confirm `, the id equal to the one the call resolved to (store-pitfalls 92), after showing the dry run. `--confirm` never applies to owner-only operations. 3. Owner-only operations (cli/api/gate.ts: every DELETE, submissions and their cancel, release requests, phased release changes, product page test start / stop, price schedules and price migrations, review replies, tester and user invitations, Play `edits.commit`, product activation, refunds, revokes and cancels, app signing) also ask for the operation id to be typed at the prompt. Never try to get around this: tell the owner what the call does and let them run it (AGENTS.md rule 1). Bodies: `--body file.json` (Apple: a JSON:API document `{ "data": { "type": ..., "attributes": ..., "relationships": ... } }`), `--upload file` for Google media uploads (bundles, APKs, images). ## Rules - Credentials only from env or `.storebound/` (same keys as every other command); never ask for them in chat. - Never answer compliance questions through raw calls (age rating, App Privacy, Data safety, export compliance): the matching skill and the owner decide. - Rate limits: storebound retries 429 and 5xx with backoff (Retry-After honoured) and prints Apple's remaining hourly quota; long `--all-pages` runs go to the background with a log (`> .storebound/api.log 2>&1 &`).