360 Secure SkillHub
360 安全技能中心

scavio-app-store

该工具依托Scavio API,提供三大核心功能:按关键词/开发商等搜索Apple应用商店应用(最多200条)、通过应用ID或bundle id获取单应用完整详情、获取带应用版本的结构化用户评论。适用于竞品调研、ASO优化、批量元数据采集等场景。需通过带API密钥的POST请求调用,每个端点消耗1积分,输出均为标准JSON格式,支持多地区商店front。

scavio-ai
scavio-ai
热度 22.01
最近更新 2026-08-19 00:39:12
分类:搜索依赖:第三方 API应用场景:市场分析 / 研究 / 报告撰写

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add scavio-app-store
Metadata
name
scavio-app-store
description
Search the Apple App Store, read a full app listing by App Store id or bundle id, and pull user reviews as structured JSON. 3 endpoints, 1 credit each, any Apple storefront.
version
1.0.0
tags
app-store, apple, ios, ipados, macos, aso, app-store-optimization, mobile-apps, app-reviews, app-metadata, bundle-id, itunes, competitor-research, agents, langchain, crewai, autogen, structured-data, json, ai-agents
metadata
{"openclaw":{"requires":{"env":["SCAVIO_API_KEY"]},"primaryEnv":"SCAVIO_API_KEY","timeout":90,"throttle":1,"emoji":"📱","homepage":"https://scavio.dev/docs/app-store-search"}}

Apple App Store via Scavio

Search the App Store, pull a full app listing by App Store id or bundle id, and read user reviews with the app version each was written against. All three endpoints return structured JSON.

When to trigger

Use this skill when the user asks to:

  • Find iOS, iPadOS or macOS apps matching a keyword, category term, or publisher name
  • Pull a single app's full listing: price, ratings, version, release notes, screenshots, size, minimum OS
  • Read App Store reviews for an app, in one storefront or across several countries
  • Compare an app against competitors, or audit a publisher's whole catalogue
  • Do App Store Optimization research (title, description, genres, ratings by country)
  • Build a bulk app-metadata dataset

Setup

Get a free API key at scavio.dev (50 free credits to get started, no card required):

export SCAVIO_API_KEY=sk_live_your_key

Every request is a POST with a JSON body and:

Authorization: Bearer $SCAVIO_API_KEY

Endpoints

Base URL: https://api.scavio.dev. All paths are under /api/v1/appstore. Every endpoint costs 1 credit.

Endpoint Credits What it returns
POST /api/v1/appstore/search 1 Up to 200 fully-shaped apps, the same row as /app. No pagination.
POST /api/v1/appstore/app 1 One app's complete listing, by App Store id or bundle id
POST /api/v1/appstore/reviews 1 A page of reviews: rating, title, text, author, app version

This runs on Apple's own iTunes JSON API, so the data is first-party and cheap.

Workflow

  1. Find an app: call /appstore/search with term. Apple matches an app name, a keyword or a publisher name, so searching a developer returns their catalogue.
  2. A search is already a bulk metadata fetch. Every search row is the same complete row /app returns, up to 200 at a time. If you searched for it, you do not need to call /app for it as well.
  3. Read one app: call /appstore/app with app_id. It takes either a numeric App Store id or a bundle id (notion.id, com.burbn.instagram) and auto-detects which; the payload is identical either way.
  4. Read reviews: call /appstore/reviews with a numeric app_id and a page from 1 to 10.

Pagination

Search does not paginate. limit (1-200, default 25) is the only lever on result volume, and every offset spelling is silently ignored. To get more results, raise limit - there is no second page.

Reviews paginate by page, 50 per page, and hard-stop at page 10. 500 reviews per storefront is Apple's anonymous ceiling. To reach further, ask a different country - each storefront has its own review pool.

/app returns a single object and takes no paging parameter.

The country parameter is not cosmetic

country picks the storefront, and the storefront decides the price, the currency, the localised title and description, and whether the app is sold there at all. It must be a two-letter code: the transport falls back to us for anything else, so "usa" silently buys a US result set that looks correct.

On /search, lang is independent of country: the storefront sets the prices, lang sets the words.

Parameters

Search (/search)

Parameter Type Default Description
term string required What to search for (1-500 chars). Matches app name, keyword, or publisher name.
limit integer 25 1-200. The only lever on result volume - there is no pagination.
country string us Two-letter storefront code. Anything not two letters silently falls back to us.
entity string software software (iPhone), ipad_software, mac_software
lang string -- Five-letter locale, e.g. en_us. Independent of country.

App (/app)

Parameter Type Default Description
app_id string required App Store id or bundle id (1-255 chars, ^[A-Za-z0-9][A-Za-z0-9._-]*$). A pasted apps.apple.com URL is rejected with a free 400 - extract the id first.
country string us Two-letter storefront code

Reviews (/reviews)

Parameter Type Default Description
app_id string required Numeric App Store id only. The reviews RSS feed has no bundle-id form.
country string us Two-letter storefront code. Each storefront has its own review pool.
page integer 1 1-10, 50 reviews each. Apple hard-stops at page 10.
sort string most_recent most_recent or most_helpful

Examples

import requests

BASE = "https://api.scavio.dev"
# Your key from https://scavio.dev. Load it from your environment or secret
# store in real code - keep it out of source control.
API_KEY = "sk_your_key_here"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 1. Search - one call, up to 200 complete app rows. No pagination: raise limit.
apps = requests.post(f"{BASE}/api/v1/appstore/search", headers=HEADERS,
    json={"term": "habit tracker", "limit": 200, "country": "us"}).json()

# 2. A publisher's catalogue - the same search endpoint, a developer name as the term
catalogue = requests.post(f"{BASE}/api/v1/appstore/search", headers=HEADERS,
    json={"term": "Notion Labs", "limit": 50}).json()

# 3. One app, by numeric id or by bundle id - identical payload
app = requests.post(f"{BASE}/api/v1/appstore/app", headers=HEADERS,
    json={"app_id": "1232780281"}).json()

same_app = requests.post(f"{BASE}/api/v1/appstore/app", headers=HEADERS,
    json={"app_id": "notion.id"}).json()

# 4. Reviews - numeric id only, page 1-10, 50 per page
reviews = requests.post(f"{BASE}/api/v1/appstore/reviews", headers=HEADERS,
    json={"app_id": "1232780281", "page": 1, "sort": "most_helpful"}).json()

Reviews stop at 500 per storefront. To go wider, ask another country rather than another page:

def reviews_across_storefronts(app_id, countries=("us", "gb", "de"), pages=10):
    """1 credit per call. 10 pages x 3 countries = 30 credits, so cap it."""
    out = []
    for country in countries:
        for page in range(1, pages + 1):          # page 10 is Apple's hard stop
            data = requests.post(f"{BASE}/api/v1/appstore/reviews", headers=HEADERS,
                                 json={"app_id": app_id, "country": country,
                                       "page": page, "sort": "most_recent"}).json()["data"]
            if not data:
                break                              # empty feed, stop this storefront
            out.append({"country": country, "page": page, "data": data})
    return out

Response shapes

Every response uses the envelope { data, response_time, credits_used, credits_remaining }.

  • search - up to 200 app rows, each the same complete row /app returns.
  • app - title, description, developer and seller identity, price and currency, all-time and current-version ratings, version and release notes, genres, content rating and advisories, icons at three sizes, screenshots, download size, minimum OS, languages, supported devices, Game Center and VPP flags.
  • reviews - star rating, title, full review text, author, and the app version the review was written against.

Two shapes to code for:

  • Mac rows are thinner. An app fetched with entity: mac_software carries no iPad or Apple TV screenshots, no advisories, no features, no supported-device list and no Game Center flag. These come back empty rather than absent, so a Mac app is not a broken response.
  • The reviews feed types its entries by cardinality. Apple's RSS returns an array at two or more reviews, a bare object at exactly one, and nothing at all at zero. Any parser must handle all three; assuming an array will crash on a one-review app.

Guardrails

  • Every call is 1 credit. Search returns up to 200 complete rows for that one credit, so prefer one large search over a loop of /app calls.
  • Never say "page 2 of the search" - there is no pagination on search. Raise limit.
  • Never promise more than 500 reviews per storefront. Page 10 is Apple's ceiling; more coverage means more countries, not more pages.
  • Under sort: most_recent the vote fields come back as zeroes - those reviews are simply too new to have been voted on. Do not report that as "no one found these helpful". Use most_helpful if you need vote data.
  • country changes the price, the currency, the localised text and the availability. If the user cares about price, name the storefront you queried in your answer.
  • Never fabricate app names, ids, bundle ids, prices, ratings or review text. Only return API data.

Failure handling

  • 400 means an invalid or missing parameter - including a pasted apps.apple.com URL in app_id. Not billed. Extract the numeric id or bundle id and retry.
  • 401 means the API key is invalid or missing. Check SCAVIO_API_KEY.
  • 404 on /app means Apple could not resolve that id. This one is billed - Apple answers with a 200 carrying an empty result list and charges for it. Verify the id before looping over a list of them.
  • /reviews cannot 404. An unknown id and a real app with zero reviews return the same empty feed, so an empty result never proves the app does not exist. Confirm the app with /app first.
  • 429 means rate or usage limit exceeded. Wait before retrying. See https://scavio.dev/docs/rate-limits.
  • 502 / 503 mean upstream is temporarily unavailable - wait a few seconds and retry.
  • If SCAVIO_API_KEY is not set, prompt the user to export it before continuing.

Python SDK

langchain-scavio has no App Store tool - use the Scavio SDK directly (it handles the auth header):

pip install scavio==0.15.0
from scavio import ScavioClient

client = ScavioClient()  # reads SCAVIO_API_KEY

apps = client.app_store.search("habit tracker", limit=200, country="us")
app = client.app_store.app("notion.id")
reviews = client.app_store.reviews("1232780281", page=1, sort="most_helpful")

JavaScript / TypeScript:

npm install scavio@0.15.0
import { Scavio } from "scavio";

const scavio = new Scavio(); // reads SCAVIO_API_KEY
const apps = await scavio.appStore.search({ term: "habit tracker", limit: 200 });
const reviews = await scavio.appStore.reviews({ app_id: "1232780281", page: 1 });