{
  "openapi": "3.1.0",
  "info": {
    "title": "Fastemy ASO Agent API",
    "version": "1.0.0",
    "description": "Free App Store Optimization data for agents: live App Store rank for a phrase, search demand from App Store autocomplete, and a listing audit scored out of 100. No key. Fresh checks: 30 a minute per IP; answers are cached (ranks 6 h, demand 24 h, audits 1 h). Method: https://aso.fastemy.com/agent.md",
    "contact": {
      "name": "Fastemy",
      "email": "contact@fastemy.com",
      "url": "https://fastemy.com"
    }
  },
  "servers": [
    {
      "url": "https://aso.fastemy.com"
    }
  ],
  "externalDocs": {
    "description": "How to read the results",
    "url": "https://aso.fastemy.com/audit.md"
  },
  "paths": {
    "/api/rank": {
      "get": {
        "operationId": "getRank",
        "summary": "Live App Store ranking for a search phrase in one storefront",
        "description": "Reads the App Store’s own search (not the relevance-ordered public search API) and returns the top results with a reading of the field.",
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 60
            },
            "description": "The search phrase, as people type it."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "us",
              "pattern": "^[a-z]{2}$"
            },
            "description": "Two-letter App Store country (storefront), e.g. us, gb, de, tr."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 25
            }
          },
          {
            "name": "app",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Your App Store id (or URL), to get your own rank."
          }
        ],
        "responses": {
          "200": {
            "description": "Ranking",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Rank"
                }
              }
            }
          },
          "400": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/demand": {
      "get": {
        "operationId": "getDemand",
        "summary": "Search demand 0–100 from App Store autocomplete",
        "description": "Walks the autocomplete prefix by prefix. 0 (dead) means nobody types it. One- and two-word terms score lower than their real volume.",
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 60
            },
            "description": "The search phrase, as people type it."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "us",
              "pattern": "^[a-z]{2}$"
            },
            "description": "Two-letter App Store country (storefront), e.g. us, gb, de, tr."
          }
        ],
        "responses": {
          "200": {
            "description": "Demand",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Demand"
                }
              }
            }
          },
          "400": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/suggest": {
      "get": {
        "operationId": "getSuggestions",
        "summary": "Raw App Store autocomplete suggestions for a prefix",
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 60
            },
            "description": "The search phrase, as people type it."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "us",
              "pattern": "^[a-z]{2}$"
            },
            "description": "Two-letter App Store country (storefront), e.g. us, gb, de, tr."
          }
        ],
        "responses": {
          "200": {
            "description": "Suggestions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "term": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string"
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "suggestions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/audit": {
      "get": {
        "operationId": "getAudit",
        "summary": "Audit an App Store listing, scored out of 100",
        "description": "Apple does not publish the subtitle or keyword field: pass them to score them too.",
        "parameters": [
          {
            "name": "app",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "App Store id or apps.apple.com URL."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "us",
              "pattern": "^[a-z]{2}$"
            },
            "description": "Two-letter App Store country (storefront), e.g. us, gb, de, tr."
          },
          {
            "name": "lang",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "en",
                "tr"
              ],
              "default": "en"
            }
          },
          {
            "name": "subtitle",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "keywords",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Audit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Audit"
                }
              }
            }
          },
          "400": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Bad input, rate limit or Apple unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "docs": {
            "type": "string"
          }
        }
      },
      "RankedApp": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "developer": {
            "type": "string"
          },
          "ratings": {
            "type": "integer"
          },
          "rating": {
            "type": "number"
          },
          "icon": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": "string"
          }
        }
      },
      "Rank": {
        "type": "object",
        "properties": {
          "term": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RankedApp"
            }
          },
          "field": {
            "type": "object",
            "properties": {
              "medianRatings": {
                "type": "integer",
                "description": "Median rating count of the top 10"
              },
              "lightApps": {
                "type": "integer",
                "description": "Apps under 100 ratings in the top 10"
              },
              "top1Exact": {
                "type": "boolean",
                "description": "#1’s name contains the exact phrase"
              },
              "exactInTop10": {
                "type": "integer"
              },
              "you": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "verdict": {
                "type": "string",
                "enum": [
                  "yours",
                  "open",
                  "contested",
                  "hard"
                ]
              }
            }
          }
        }
      },
      "Demand": {
        "type": "object",
        "properties": {
          "term": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "score": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "dead": {
            "type": "boolean"
          },
          "method": {
            "type": "string",
            "enum": [
              "prefix",
              "exact",
              "extend",
              "weak",
              "none"
            ]
          },
          "prefix": {
            "type": "string"
          },
          "position": {
            "type": "integer"
          },
          "extensions": {
            "type": "integer"
          },
          "suggestions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Finding": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pass",
              "warn",
              "fail",
              "info"
            ]
          },
          "points": {
            "type": "number"
          },
          "max": {
            "type": "number"
          },
          "title": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          },
          "fix": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Source id, see https://aso.fastemy.com/sources/"
          }
        }
      },
      "Audit": {
        "type": "object",
        "properties": {
          "app": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "developer": {
                "type": "string"
              },
              "country": {
                "type": "string"
              },
              "category": {
                "type": "string"
              },
              "ratings": {
                "type": "integer"
              },
              "rating": {
                "type": "number"
              },
              "version": {
                "type": "string"
              },
              "updated": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "scoredMax": {
            "type": "integer"
          },
          "findings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Finding"
            }
          },
          "fixes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Finding"
            }
          },
          "missing": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "subtitle",
                "keywords"
              ]
            }
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}