AppFrame API & MCP

Overview

AppFrame exposes a free, read-only JSON API and a Model Context Protocol (MCP) server. Use them to look up an iOS app on the App Store and get the AppFrame editor link where a launch image can be created, to list the available themes, fonts and formats, or to read pricing and blog content. Image rendering happens in the browser editor and is not available through the API.

Authentication

None. All endpoints are public and read-only. CORS is open.

Endpoints

  • GET /api/v1/info

    Site info, how it works, Free and Pro plans, contact and links.

  • GET /api/v1/themes

    The 20 themes (dark, light, bold; free or Pro), 9 fonts and 6 social formats.

  • GET /api/v1/apps?q={name|id|url}&country={cc}

    Look up App Store apps with the AppFrame editor URL. App Store ID or URL is reliable; name search is best-effort and can return 502 upstream_error.

  • GET /api/v1/blog

    All blog posts with title, description, date and URL.

  • GET /api/v1/health

    Health check.

Examples

curl -s "https://appfra.me/api/v1/apps?q=1232780281&country=us"

curl -s https://appfra.me/api/v1/themes

curl -s https://appfra.me/ -H "Accept: text/markdown"

MCP server

Streamable HTTP transport, JSON-RPC 2.0 over POST, no session required. Tools: get_appframe_info, list_themes, search_apps, list_blog_posts. Resources: appframe://info, appframe://themes, https://appfra.me/llms.txt.

curl -s https://appfra.me/mcp -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_apps","arguments":{"q":"https://apps.apple.com/app/id1232780281"}}}'

Client config (Claude Desktop, Cursor and others that support remote MCP):

{ "mcpServers": { "appframe": { "url": "https://appfra.me/mcp" } } }

Rate limits

60 requests per minute per IP across /api/v1/* and /mcp. Every response carries the IETF headers RateLimit-Policy: "default";q=60;w=60 and RateLimit: "default";r=<remaining>;t=<seconds>. Over the limit you get HTTP 429 with Retry-After.

Errors

Errors use RFC 9457 application/problem+json with type, title, status, detail, code and resolution. Codes:

  • invalid_query (400): missing or too long q.
  • invalid_country (400): country is not a 2-letter code.
  • not_found (404): no matching app, or unknown endpoint.
  • method_not_allowed (405): /mcp accepts only POST (and OPTIONS).
  • rate_limited (429): wait for the reset, then retry.
  • upstream_error (502): the App Store search did not respond; retry.
  • error (500): any other failure; the status field carries the real HTTP status.
{
  "type": "https://appfra.me/docs#error-invalid_query",
  "title": "Invalid query",
  "status": 400,
  "detail": "Parameter 'q' is required (1-100 characters).",
  "code": "invalid_query",
  "resolution": "Pass an app name, a numeric App Store ID or an App Store URL in 'q'."
}

Versioning and deprecation

  • /api/v1 is stable. Fields may be added; existing fields are not removed or renamed.
  • Breaking changes ship only under a new version path (/api/v2), and v1 keeps running alongside it.
  • Deprecations are announced at least 90 days ahead on this page and with the Deprecation (RFC 9745) and Sunset (RFC 8594) response headers, plus Link: <https://appfra.me/docs#versioning>; rel="deprecation".
  • A deprecated endpoint keeps working until its Sunset date. No endpoint is deprecated today.

Command line

No package to install: the API works with curl and jq.

# Free themes
curl -s https://appfra.me/api/v1/themes | jq -r '.themes[] | select(.free) | .name'

# Editor URL for an App Store app
curl -s "https://appfra.me/api/v1/apps?q=https://apps.apple.com/app/id1232780281" | jq -r '.results[0].editorUrl'

# Latest blog posts
curl -s https://appfra.me/api/v1/blog | jq -r '.posts[:5][] | "(.date)  (.title)"'

# Pro price
curl -s https://appfra.me/api/v1/info | jq '.plans[] | select(.id=="pro") | .price'

Markdown pages

Every page is also available as Markdown: send Accept: text/markdown to any URL, or append ?format=md.