{
  "openapi": "3.1.0",
  "info": {
    "title": "AppFrame Public API",
    "version": "1.0.0",
    "description": "Read-only public API of AppFrame (appfra.me), the iOS app launch image generator. Returns site information, pricing, editor themes/fonts/social formats, blog posts, and App Store app lookup with the AppFrame editor URL. No authentication. Rate limit: 60 requests per minute per IP, shared with the MCP server at /mcp, reported with IETF RateLimit-Policy and RateLimit headers. All 4xx/5xx errors use RFC 9457 application/problem+json (components.schemas.Problem). Versioning and deprecation: /api/v1 is stable; breaking changes ship only under a new path (/api/v2). Deprecated endpoints are announced at least 90 days ahead with the RFC 9745 Deprecation header, the RFC 8594 Sunset header and a Link rel=deprecation to https://appfra.me/docs#versioning; they keep working until the Sunset date.",
    "contact": {
      "name": "Simone Ruggiero",
      "email": "simone.ruggiero97@gmail.com",
      "url": "https://appfra.me/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://appfra.me/terms"
    },
    "x-api-lifecycle": {
      "status": "stable",
      "version": "v1"
    },
    "x-deprecation-policy": {
      "url": "https://appfra.me/docs#versioning",
      "minimumNoticeDays": 90,
      "headers": [
        "Deprecation (RFC 9745)",
        "Sunset (RFC 8594)"
      ],
      "breakingChanges": "new major path, e.g. /api/v2"
    }
  },
  "servers": [
    {
      "url": "https://appfra.me",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Developer docs, including the versioning and deprecation policy",
    "url": "https://appfra.me/docs#versioning"
  },
  "tags": [
    {
      "name": "site",
      "description": "Site, pricing and editor options"
    },
    {
      "name": "apps",
      "description": "App Store lookup"
    },
    {
      "name": "content",
      "description": "Blog content"
    }
  ],
  "paths": {
    "/api/v1/info": {
      "get": {
        "operationId": "getSiteInfo",
        "summary": "Get AppFrame info and pricing",
        "description": "Returns what AppFrame is, how it works, plans and prices, contact details and links to docs, OpenAPI and MCP.",
        "tags": [
          "site"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name",
                    "url",
                    "description",
                    "developer",
                    "contact",
                    "address",
                    "docs",
                    "openapi",
                    "mcp",
                    "llms",
                    "plans",
                    "counts",
                    "howItWorks",
                    "editorUrlTemplate"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "description": {
                      "type": "string"
                    },
                    "developer": {
                      "type": "object",
                      "required": [
                        "name",
                        "url"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    },
                    "contact": {
                      "type": "object",
                      "required": [
                        "email"
                      ],
                      "properties": {
                        "email": {
                          "type": "string",
                          "format": "email"
                        }
                      }
                    },
                    "address": {
                      "type": "object",
                      "required": [
                        "locality",
                        "country"
                      ],
                      "properties": {
                        "locality": {
                          "type": "string"
                        },
                        "country": {
                          "type": "string"
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "openapi": {
                      "type": "string",
                      "format": "uri"
                    },
                    "mcp": {
                      "type": "string",
                      "format": "uri"
                    },
                    "llms": {
                      "type": "string",
                      "format": "uri"
                    },
                    "plans": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "price",
                          "currency",
                          "billing",
                          "features"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "enum": [
                              "free",
                              "pro"
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "price": {
                            "type": "number"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "billing": {
                            "type": "string",
                            "enum": [
                              "free",
                              "one-time"
                            ]
                          },
                          "features": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    },
                    "counts": {
                      "type": "object",
                      "required": [
                        "themes",
                        "fonts",
                        "formats"
                      ],
                      "properties": {
                        "themes": {
                          "type": "integer"
                        },
                        "fonts": {
                          "type": "integer"
                        },
                        "formats": {
                          "type": "integer"
                        }
                      }
                    },
                    "howItWorks": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "editorUrlTemplate": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/themes": {
      "get": {
        "operationId": "listThemes",
        "summary": "List themes, fonts and social formats",
        "description": "Returns the 20 showcase themes (category, free or Pro), the 9 fonts and the 6 export aspect ratios of the editor.",
        "tags": [
          "site"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "themes",
                    "fonts",
                    "formats"
                  ],
                  "properties": {
                    "themes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "category",
                          "free"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "dark",
                              "light",
                              "bold"
                            ]
                          },
                          "free": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "fonts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "free"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "free": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "formats": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "ratio"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "ratio": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/apps": {
      "get": {
        "operationId": "searchApps",
        "summary": "Look up App Store apps",
        "description": "Looks up iOS apps on the Apple App Store and returns them with the AppFrame editor URL where a showcase image can be created. Lookup by numeric App Store ID or App Store URL is reliable. Search by app name is best-effort: Apple's search service may refuse requests from our edge network, in which case the response is 502 upstream_error and you should retry with the App Store ID or URL.",
        "tags": [
          "apps"
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Numeric App Store ID or App Store URL (reliable), or an app name (best-effort). 1-100 characters.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "example": "1232780281"
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "2-letter App Store country code.",
            "schema": {
              "type": "string",
              "pattern": "^[a-zA-Z]{2}$",
              "minLength": 2,
              "maxLength": 2,
              "default": "us"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "query",
                    "country",
                    "results"
                  ],
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "trackId",
                          "name",
                          "developer",
                          "icon",
                          "genre",
                          "price",
                          "rating",
                          "ratingCount",
                          "version",
                          "appStoreUrl",
                          "screenshotCount",
                          "editorUrl"
                        ],
                        "properties": {
                          "trackId": {
                            "type": "integer"
                          },
                          "name": {
                            "type": "string"
                          },
                          "developer": {
                            "type": "string"
                          },
                          "icon": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uri"
                          },
                          "genre": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "price": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "rating": {
                            "type": "number"
                          },
                          "ratingCount": {
                            "type": "integer"
                          },
                          "version": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "appStoreUrl": {
                            "type": "string",
                            "format": "uri"
                          },
                          "screenshotCount": {
                            "type": "integer"
                          },
                          "editorUrl": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "502": {
            "description": "Upstream App Store service error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/blog": {
      "get": {
        "operationId": "listBlogPosts",
        "summary": "List blog posts",
        "description": "Returns all AppFrame blog posts about iOS app marketing, ASO and launch strategy, with title, description, date and URL.",
        "tags": [
          "content"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "posts"
                  ],
                  "properties": {
                    "posts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "title",
                          "description",
                          "date",
                          "url"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "date": {
                            "type": "string",
                            "format": "date"
                          },
                          "url": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Health check",
        "description": "Returns status ok and the server time when the API is up.",
        "tags": [
          "site"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "time"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimit-Policy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "headers": {
      "RateLimit-Policy": {
        "description": "IETF rate limit policy: 60 requests per 60 seconds per IP.",
        "schema": {
          "type": "string"
        },
        "example": "\"default\";q=60;w=60"
      },
      "RateLimit": {
        "description": "IETF rate limit state: remaining requests (best effort) and seconds until reset.",
        "schema": {
          "type": "string"
        },
        "example": "\"default\";r=59;t=60"
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details.",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code",
          "resolution"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "Link to the error code documentation"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "invalid_query",
              "invalid_country",
              "not_found",
              "method_not_allowed",
              "rate_limited",
              "upstream_error",
              "error"
            ]
          },
          "resolution": {
            "type": "string"
          }
        }
      },
      "SiteInfo": {
        "type": "object",
        "required": [
          "name",
          "url",
          "description",
          "developer",
          "contact",
          "address",
          "docs",
          "openapi",
          "mcp",
          "llms",
          "plans",
          "counts",
          "howItWorks",
          "editorUrlTemplate"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "developer": {
            "type": "object",
            "required": [
              "name",
              "url"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "contact": {
            "type": "object",
            "required": [
              "email"
            ],
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              }
            }
          },
          "address": {
            "type": "object",
            "required": [
              "locality",
              "country"
            ],
            "properties": {
              "locality": {
                "type": "string"
              },
              "country": {
                "type": "string"
              }
            }
          },
          "docs": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          },
          "mcp": {
            "type": "string",
            "format": "uri"
          },
          "llms": {
            "type": "string",
            "format": "uri"
          },
          "plans": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "price",
                "currency",
                "billing",
                "features"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "enum": [
                    "free",
                    "pro"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "price": {
                  "type": "number"
                },
                "currency": {
                  "type": "string"
                },
                "billing": {
                  "type": "string",
                  "enum": [
                    "free",
                    "one-time"
                  ]
                },
                "features": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "counts": {
            "type": "object",
            "required": [
              "themes",
              "fonts",
              "formats"
            ],
            "properties": {
              "themes": {
                "type": "integer"
              },
              "fonts": {
                "type": "integer"
              },
              "formats": {
                "type": "integer"
              }
            }
          },
          "howItWorks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "editorUrlTemplate": {
            "type": "string"
          }
        }
      },
      "EditorOptions": {
        "type": "object",
        "required": [
          "themes",
          "fonts",
          "formats"
        ],
        "properties": {
          "themes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "category",
                "free"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "category": {
                  "type": "string",
                  "enum": [
                    "dark",
                    "light",
                    "bold"
                  ]
                },
                "free": {
                  "type": "boolean"
                }
              }
            }
          },
          "fonts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "free"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "free": {
                  "type": "boolean"
                }
              }
            }
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "ratio"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "ratio": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "App": {
        "type": "object",
        "required": [
          "trackId",
          "name",
          "developer",
          "icon",
          "genre",
          "price",
          "rating",
          "ratingCount",
          "version",
          "appStoreUrl",
          "screenshotCount",
          "editorUrl"
        ],
        "properties": {
          "trackId": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "developer": {
            "type": "string"
          },
          "icon": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "genre": {
            "type": [
              "string",
              "null"
            ]
          },
          "price": {
            "type": [
              "string",
              "null"
            ]
          },
          "rating": {
            "type": "number"
          },
          "ratingCount": {
            "type": "integer"
          },
          "version": {
            "type": [
              "string",
              "null"
            ]
          },
          "appStoreUrl": {
            "type": "string",
            "format": "uri"
          },
          "screenshotCount": {
            "type": "integer"
          },
          "editorUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "AppSearchResult": {
        "type": "object",
        "required": [
          "query",
          "country",
          "results"
        ],
        "properties": {
          "query": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "trackId",
                "name",
                "developer",
                "icon",
                "genre",
                "price",
                "rating",
                "ratingCount",
                "version",
                "appStoreUrl",
                "screenshotCount",
                "editorUrl"
              ],
              "properties": {
                "trackId": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                },
                "developer": {
                  "type": "string"
                },
                "icon": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uri"
                },
                "genre": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "price": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "rating": {
                  "type": "number"
                },
                "ratingCount": {
                  "type": "integer"
                },
                "version": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "appStoreUrl": {
                  "type": "string",
                  "format": "uri"
                },
                "screenshotCount": {
                  "type": "integer"
                },
                "editorUrl": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      },
      "BlogList": {
        "type": "object",
        "required": [
          "posts"
        ],
        "properties": {
          "posts": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "slug",
                "title",
                "description",
                "date",
                "url"
              ],
              "properties": {
                "slug": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "date": {
                  "type": "string",
                  "format": "date"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "status",
          "time"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          },
          "time": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}