{
  "openapi": "3.1.0",
  "info": {
    "title": "Sonar API",
    "description": "App Store Optimization data for AI agents, MCP tools, and automation. Keyword research, rank tracking, ASO scoring, reviews, and revenue estimates for the iOS App Store and Google Play.",
    "version": "1.0.0",
    "termsOfService": "https://trysonar.app/terms",
    "contact": {
      "url": "https://trysonar.app/support"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://trysonar.app/terms"
    }
  },
  "servers": [
    {
      "url": "https://trysonar.app",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "API reference",
    "url": "https://trysonar.app/docs/api"
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "aso_xxx",
        "description": "API key with the `aso_` prefix. Get one at /developers (paid plans)."
      }
    },
    "parameters": {
      "Store": {
        "name": "store",
        "in": "query",
        "required": true,
        "description": "App store",
        "schema": {
          "type": "string",
          "enum": [
            "ios",
            "android"
          ]
        }
      },
      "Country": {
        "name": "country",
        "in": "query",
        "required": false,
        "description": "ISO 3166-1 alpha-2 country code",
        "schema": {
          "type": "string",
          "default": "us",
          "pattern": "^[a-z]{2}$"
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "Pagination cursor from a previous response's next_cursor",
        "schema": {
          "type": "string"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Page size (1–200)",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200
        }
      },
      "Days": {
        "name": "days",
        "in": "query",
        "required": false,
        "description": "History window in days (1–365)",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 365,
          "default": 30
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "App": {
        "type": "object",
        "properties": {
          "storeId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "developer": {
            "type": "string"
          },
          "rating": {
            "type": "number"
          },
          "reviews": {
            "type": "integer"
          },
          "category": {
            "type": "string"
          },
          "iconUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Keyword": {
        "type": "object",
        "properties": {
          "keyword": {
            "type": "string"
          },
          "popularity": {
            "type": "number",
            "description": "0–100 popularity score"
          },
          "difficulty": {
            "type": "number",
            "description": "0–100 proprietary difficulty score"
          },
          "resultsCount": {
            "type": "integer"
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Plan or scope insufficient (workspace endpoints need the Full plan; writes also need a write-scope key)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found or not tracked by your organization",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (Full plan: 1000/day)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/api/v1/apps/lookup": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "Look up an app by store ID",
        "parameters": [
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "name": "id",
            "in": "query",
            "required": true,
            "description": "App store ID (numeric for iOS, package for Android)",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Country"
          }
        ],
        "responses": {
          "200": {
            "description": "App metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/App"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/apps/search": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "Search apps in a store",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "$ref": "#/components/parameters/Country"
          },
          {
            "name": "num",
            "in": "query",
            "description": "Max results (1–50)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/App"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/apps/aso-score": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "Calculate an ASO optimization score (0–100)",
        "parameters": [
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Country"
          }
        ],
        "responses": {
          "200": {
            "description": "ASO score breakdown"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/apps/extract-keywords": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "Extract keywords from an app's metadata",
        "parameters": [
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Country"
          },
          {
            "name": "max",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Extracted keywords"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/apps/reviews": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "Fetch app reviews",
        "parameters": [
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Country"
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "recent",
                "helpful"
              ],
              "default": "recent"
            }
          },
          {
            "name": "min_rating",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            }
          },
          {
            "name": "max_rating",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "App reviews"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/apps/revenue": {
      "get": {
        "tags": [
          "Apps"
        ],
        "summary": "Estimate monthly revenue for an app (single or bulk)",
        "description": "Pass `id` for a single app or `ids` (comma-separated, up to 25) for bulk lookup. Bulk counts as one request.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "name": "id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ids",
            "in": "query",
            "description": "Comma-separated store IDs (max 25)",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Country"
          }
        ],
        "responses": {
          "200": {
            "description": "Monthly revenue estimate(s)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/keywords/search": {
      "get": {
        "tags": [
          "Keywords"
        ],
        "summary": "Keyword research with difficulty + popularity",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "$ref": "#/components/parameters/Country"
          }
        ],
        "responses": {
          "200": {
            "description": "Keyword data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Keyword"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/keywords/suggestions": {
      "get": {
        "tags": [
          "Keywords"
        ],
        "summary": "Autocomplete-driven keyword suggestions",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "$ref": "#/components/parameters/Country"
          }
        ],
        "responses": {
          "200": {
            "description": "Suggested keywords"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/keywords/metrics": {
      "get": {
        "tags": [
          "Keywords"
        ],
        "summary": "Difficulty + popularity for a specific keyword (or bulk)",
        "description": "Pass `q` for a single keyword or `qs` (comma-separated, max 25) for bulk. 1 credit per keyword. Use this when you already have a keyword list — `/keywords/search` is the heavier endpoint that also fans out into related terms.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Single keyword (use this OR qs)"
          },
          {
            "name": "qs",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated bulk keywords, up to 25"
          },
          {
            "$ref": "#/components/parameters/Store"
          },
          {
            "$ref": "#/components/parameters/Country"
          }
        ],
        "responses": {
          "200": {
            "description": "Single keyword data (when `q`) or array of keyword data (when `qs`)",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/Keyword"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Keyword"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid params"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/api/v1/apps": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "List your tracked apps with latest snapshots",
        "description": "Requires the Full plan. Cursor paginated (default 100).",
        "parameters": [
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Tracked apps (paginated)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/apps/{id}": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "App metadata + up to 90 days of snapshots",
        "description": "Requires the Full plan.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Sonar app UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "App detail with snapshot history"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/apps/{id}/keywords": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "Keywords tracked for an app",
        "description": "Latest difficulty/popularity per keyword. Requires the Full plan. Cursor paginated (default 50).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Sonar app UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Tracked keywords (paginated)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "post": {
        "tags": [
          "Write"
        ],
        "summary": "Track keywords for an app (bulk, idempotent)",
        "description": "Requires the Full plan and a write-scope API key. Re-posting the same terms reports them as already_tracked.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Sonar app UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "keywords"
                ],
                "properties": {
                  "keywords": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 120
                    },
                    "minItems": 1,
                    "maxItems": 200
                  },
                  "country": {
                    "type": "string",
                    "pattern": "^[a-z]{2}$",
                    "description": "Optional — defaults to the linked product's country"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Per-keyword outcomes: { added, already_tracked, failed, results }"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/apps/{id}/rankings": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "Rank history for an app's tracked keywords",
        "description": "Daily positions per keyword over the window. Requires the Full plan. Cursor paginated over keywords (default 50).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Sonar app UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Days"
          },
          {
            "name": "keyword_id",
            "in": "query",
            "description": "Restrict to one keyword",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Rank history per keyword (paginated)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/apps/{id}/changes": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "Change history for a tracked app",
        "description": "Detected releases, metadata edits, screenshots, price, and category changes, newest first. Requires the Full plan.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Sonar app UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "release",
                "metadata",
                "screenshots",
                "price",
                "category"
              ]
            }
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Detected changes"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/keywords/{id}/rankings": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "SERP history for a tracked keyword",
        "description": "Which apps ranked in the top results on each measured day. Requires the Full plan.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Sonar keyword UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Days"
          }
        ],
        "responses": {
          "200": {
            "description": "SERP entries, newest first"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/competitors/{id}/keywords": {
      "get": {
        "tags": [
          "Workspace"
        ],
        "summary": "Keywords a competitor ranks for (+ gap analysis)",
        "description": "Last 7 days of SERP data. Pass app_id for gap analysis against your own app. Requires the Full plan. Cursor paginated (default 50).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Competitor's Sonar app UUID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "app_id",
            "in": "query",
            "description": "Your own app's Sonar UUID for gap analysis",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/Limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Competitor keywords (paginated)"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/products": {
      "post": {
        "tags": [
          "Write"
        ],
        "summary": "Create a product and start tracking its app(s)",
        "description": "A product is the cross-store unit (up to one iOS + one Android app). Requires the Full plan and a write-scope API key.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "apps"
                ],
                "properties": {
                  "apps": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 2,
                    "items": {
                      "type": "object",
                      "required": [
                        "store",
                        "store_id"
                      ],
                      "properties": {
                        "store": {
                          "type": "string",
                          "enum": [
                            "ios",
                            "android"
                          ]
                        },
                        "store_id": {
                          "type": "string"
                        },
                        "country": {
                          "type": "string",
                          "pattern": "^[a-z]{2}$"
                        }
                      }
                    }
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 120
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Product with linked apps — apps[].id are the Sonar app UUIDs"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/products/{id}/apps": {
      "post": {
        "tags": [
          "Write"
        ],
        "summary": "Link the second-store version of a product",
        "description": "Requires the Full plan and a write-scope API key. Each product holds at most one app per store.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Product UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "store",
                  "store_id"
                ],
                "properties": {
                  "store": {
                    "type": "string",
                    "enum": [
                      "ios",
                      "android"
                    ]
                  },
                  "store_id": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "pattern": "^[a-z]{2}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Linked app"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/products/{id}/competitors": {
      "post": {
        "tags": [
          "Write"
        ],
        "summary": "Track a competitor app under a product",
        "description": "The product must already have its own app in the same store. Requires the Full plan and a write-scope API key.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Product UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "store",
                  "store_id"
                ],
                "properties": {
                  "store": {
                    "type": "string",
                    "enum": [
                      "ios",
                      "android"
                    ]
                  },
                  "store_id": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "pattern": "^[a-z]{2}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Linked competitor app"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/tracked-keywords/{id}": {
      "patch": {
        "tags": [
          "Write"
        ],
        "summary": "Set or clear the note on a tracked keyword",
        "description": "id is the tracked-keyword UUID (the id field from GET /apps/{id}/keywords, not keyword_id). Requires the Full plan and a write-scope API key.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Tracked-keyword UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "note"
                ],
                "properties": {
                  "note": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 1000,
                    "description": "Note text; null or empty clears it"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated tracked keyword"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/api/v1/competitors/{id}/scan": {
      "post": {
        "tags": [
          "Write"
        ],
        "summary": "Run a keyword discovery scan on a competitor",
        "description": "Discovers keywords the competitor ranks for and records both apps' ranks. Heavy (fans out scraper calls; ~30s+). Requires the Full plan and a write-scope API key.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Competitor's Sonar app UUID",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "own_app_id"
                ],
                "properties": {
                  "own_app_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Your own app the scan compares against"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Counts of keywords discovered and ranked"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Apps",
      "description": "App lookup, search, scoring, and reviews"
    },
    {
      "name": "Keywords",
      "description": "Keyword research, difficulty, and suggestions"
    },
    {
      "name": "Workspace",
      "description": "Your tracked apps, keywords, rankings, and competitors (Full plan)"
    },
    {
      "name": "Write",
      "description": "Mutate your workspace — create products, track keywords/competitors, notes, scans (Full plan + write-scope key)"
    }
  ]
}