{
  "openapi": "3.1.0",
  "info": {
    "title": "Installgraph API",
    "version": "1.0.0",
    "description": "Which apps, scripts and pixels Shopify storefronts run, read from each store's homepage once a week.\n\n**Authentication.** Send your key as `Authorization: Bearer sfs_…` (or `X-API-Key: sfs_…`). To use the\nAPI from a browser's address bar, add `?key=sfs_…` to the URL instead. That is simpler but less safe: the\nURL, key included, stays in your browser history, so don't share such links, and regenerate the key if one\nleaks. A header wins when both are sent.\n\n**CSV.** Add `.csv` to any keyed endpoint's path (`/v1/apps/klaviyo/companies.csv`) to get the same data\nas a CSV download, charged the same. Nested fields become dotted columns (`industry.category`) and lists\nare joined with \"; \". On a list, the next page's cursor is in the `X-Next-Cursor` header.\n\n**Credits.** 1 credit unlocks 1 store: a row in an app's list, or a store's full stack from a domain\nlookup. `include=history` on a lookup (install and removal dates) and each store in `/v1/events` cost 1\nmore. Re-pulling a store for the same kind of request within 7 days is free (`meta.freeRepulls` counts\nthem). Counts (`/v1/apps/{slug}/companies/count`), the catalogue, usage and pricing are free, and so is\nany error or empty page. A page the balance cannot cover is cut to the rows you can pay for, and\n`pagination.nextCursor` resumes after the last one. Keys made at sign-up share their account's balance.\nEvery response carries `X-Credits-Charged` and, except for unlimited keys, `X-Credits-Remaining`;\n`meta.creditsUsed` and `meta.creditsRemaining` repeat them.\n\n**When credits run out**, billed endpoints answer `402 insufficient_credits` with `error.offers`: the\ncheapest pack and its buy link, and the Talk to us link, so an agent can act on it or pass it to a person.\nAn account may unlock at most 40,000 distinct stores per 30 days (`402 usage_cap_reached`) and buy at most\n$1,000 of packs per 30 days (`402 spend_cap_reached`); beyond that, Talk to us.\n\n**Getting a key.** Sign up at https://installgraph.com/login and copy the key from your dashboard. Prices are at\n`GET /v1/pricing`, no key needed.\n\n**Rate limits.** Each key may make a set number of requests a minute (60 unless agreed otherwise). Every\nresponse carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (epoch seconds);\nover the limit, `429 rate_limited` with `Retry-After` in seconds.\n\n**Pagination.** List endpoints take `limit` (1–500, default 100) and `cursor`. Pass back\n`pagination.nextCursor` unchanged, with the same filters, until it is `null`. Cursors are positions, not\noffsets: rows added while you page do not shift or repeat earlier rows. A page can hold fewer rows than\n`limit` while `hasMore` is still true. A cursor is opaque and signed: it works for 24 hours, only for keys\nof the account it was issued to, and only with the same path and filters (`limit` may change). Anything\nelse is `400 invalid_cursor`. To resume the event stream after longer, pass `since` with the last\n`detectedAt` you read.\n\n**Free preview.** Until an account buys its first pack, `/v1/apps/{slug}/companies` and `/v1/events`\nread only the first 50 rows of each list in its fixed order (by domain; by `detectedAt`), and filters\nsuch as `country` or `since` select within those 50 rows. `meta.preview` says so on every such page, and\n`pagination.hasMore` is `false` at its end. The count endpoint always gives the full number.\n\n**Errors.** Every error is `{ \"error\": { \"code\", \"message\", \"requestId\" } }`. Branch on `code`; quote\n`requestId` when asking for support. The one exception is a `.csv` link opened in a browser tab (a request\nthat accepts `text/html`): its error comes back as plain text, with the same status.\n\n**How detection works.** One GET of each store's homepage, no browser. Evidence types: `webPixel` (the\napp's Shopify web pixel, identified by its Partner app id: the strongest evidence), `themeAppExtension`\n(an app embed in the theme), `appProxy` (a link to the app's pages on the store's own domain, under\n`/apps/`), `customPixel` (a custom pixel the merchant named for the vendor whose code\nit holds, such as Elevar's checkout tracking), `script` (a ScriptTag, a third-party script on the page,\nor one a snippet in the theme loads), `html` (markup the app writes). Apps injected only at runtime by a\ntag manager are not seen.\n",
    "contact": {
      "name": "Installgraph",
      "url": "https://installgraph.com/talk-to-us"
    }
  },
  "servers": [
    {
      "url": "https://api.installgraph.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerKey": []
    },
    {
      "headerKey": []
    },
    {
      "queryKey": []
    }
  ],
  "tags": [
    {
      "name": "Companies",
      "description": "One store's stack."
    },
    {
      "name": "Apps",
      "description": "The catalogue, and the stores running each app."
    },
    {
      "name": "Events",
      "description": "Installs and removals over time."
    },
    {
      "name": "Account",
      "description": "Your key's credits and usage, and the filter vocabularies."
    },
    {
      "name": "Billing",
      "description": "Prices, sign-up and buying credits. Accounts, sign-in and Checkout are on installgraph.com."
    },
    {
      "name": "Public",
      "description": "Keyless aggregate counts for landing pages. Nothing about a single store; that needs a key."
    }
  ],
  "paths": {
    "/v1/companies/{domain}": {
      "get": {
        "tags": [
          "Companies"
        ],
        "operationId": "getCompany",
        "summary": "A store's current stack",
        "description": "The apps a store ran at its latest healthy scan, with its theme, country and currency. `domain` is\nnormalized (scheme, `www.`, path and port are dropped), so `https://www.allbirds.com/` works.\nCosts 1 credit, free again within 7 days. A 404 (no store found) is free up to 2 × your lookups\nthat found a store in the last 30 days + 100, then costs 1 credit (`X-Credits-Charged` on the 404;\na 402 when out of credits). Until your account has bought credits, a domain we know of but have not\nscanned yet answers with the same 404 as one we have never heard of. `include=history` adds the store's install\nand removal events (`history`, newest first, up to 500) for 1 credit more. Scope `companies:read`.\n",
        "parameters": [
          {
            "name": "domain",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "allbirds.com"
            }
          },
          {
            "name": "include",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "history"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The company",
            "headers": {
              "X-Credits-Charged": {
                "$ref": "#/components/headers/CreditsCharged"
              },
              "X-Credits-Remaining": {
                "$ref": "#/components/headers/CreditsRemaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Company"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": {
                    "domain": "example.com",
                    "name": "Example Apparel Co.",
                    "myshopifyDomain": "example-apparel.myshopify.com",
                    "country": "US",
                    "region": "north-america",
                    "industry": {
                      "category": "Apparel",
                      "subcategory": "Footwear",
                      "path": "/Apparel/Footwear",
                      "confidence": "high"
                    },
                    "pricePoint": {
                      "aovBand": "100-200",
                      "label": "$100–200",
                      "confidence": "medium",
                      "medianProductPriceUsd": 128,
                      "productPriceRangeUsd": [
                        95,
                        165
                      ],
                      "productPricesSeen": 24
                    },
                    "currency": "USD",
                    "locale": "en",
                    "status": "live",
                    "theme": {
                      "name": "Dawn",
                      "version": "15.2.0",
                      "themeStoreId": 887,
                      "customName": "Dawn - spring",
                      "since": "2026-03-02T04:11:09.000Z"
                    },
                    "lastScannedAt": "2026-11-02T03:40:12.000Z",
                    "lastHealthyScanAt": "2026-11-02T03:40:12.000Z",
                    "customPixelCount": 2,
                    "apps": [
                      {
                        "slug": "klaviyo",
                        "name": "Klaviyo",
                        "category": "email-sms",
                        "firstSeenAt": "2026-01-12T05:02:44.000Z",
                        "lastSeenAt": "2026-11-02T03:40:12.000Z",
                        "evidence": [
                          "webPixel",
                          "themeAppExtension"
                        ]
                      },
                      {
                        "slug": "judge-me",
                        "name": "Judge.me",
                        "category": "reviews",
                        "firstSeenAt": "2026-01-12T05:02:44.000Z",
                        "lastSeenAt": "2026-11-02T03:40:12.000Z",
                        "evidence": [
                          "themeAppExtension",
                          "script"
                        ]
                      }
                    ]
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                    "creditsUsed": 1,
                    "creditsCharged": 1,
                    "creditsRemaining": 49,
                    "freeRepulls": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/get-company"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/companies/example.com\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\""
          }
        ]
      }
    },
    "/v1/apps/{slug}/companies/count": {
      "get": {
        "tags": [
          "Apps"
        ],
        "operationId": "countAppCompanies",
        "summary": "How many stores run an app (free)",
        "description": "The number of stores `/v1/apps/{slug}/companies` would list with the same filters. Free and unlimited,\nso you can narrow a query before paying for rows. Scope `companies:read`.\n",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "klaviyo"
            }
          },
          {
            "$ref": "#/components/parameters/country"
          },
          {
            "$ref": "#/components/parameters/region"
          },
          {
            "$ref": "#/components/parameters/industry"
          },
          {
            "$ref": "#/components/parameters/aov"
          }
        ],
        "responses": {
          "200": {
            "description": "The count",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "app": {
                          "type": "string"
                        },
                        "count": {
                          "type": "integer"
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": {
                    "app": "klaviyo",
                    "count": 1284
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                    "creditsUsed": 0,
                    "creditsCharged": 0,
                    "creditsRemaining": 47,
                    "freeRepulls": 0
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/count-app-companies"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/apps/klaviyo/companies/count?country=GB&industry=Apparel\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\""
          }
        ]
      }
    },
    "/v1/pricing": {
      "get": {
        "tags": [
          "Billing"
        ],
        "operationId": "getPricing",
        "summary": "Prices, packs and rules (no key)",
        "security": [],
        "description": "Machine-readable pricing, the same as installgraph.com/pricing. CORS open.",
        "responses": {
          "200": {
            "description": "`{ data: { unit, prices, rules, free, packs, autoTopUp, limits, talkToUs, signUp } }`",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "unit": "1 credit unlocks 1 store: a row in an app's list, or a store's full app stack from a domain lookup.",
                    "prices": {
                      "GET /v1/companies/{domain}": {
                        "creditsPerStore": 1,
                        "note": "Full app stack. `include=history` adds 1."
                      }
                    },
                    "rules": {
                      "chargedOnlyForStoresFound": true,
                      "freeRepullDays": 7,
                      "countsFree": true,
                      "creditsExpire": true,
                      "creditExpiryDays": 365,
                      "refundable": false
                    },
                    "free": {
                      "instantCredits": 25,
                      "verifiedEmailCredits": 25,
                      "note": "The verified-email credits are granted once per company email domain."
                    },
                    "packs": [
                      {
                        "id": "starter",
                        "name": "Starter",
                        "priceUsd": 50,
                        "credits": 500,
                        "usdPer1000Stores": 100,
                        "buyUrl": "https://installgraph.com/account?buy=starter"
                      }
                    ],
                    "autoTopUp": {
                      "default": "off",
                      "spendCapUsd": 1000,
                      "spendCapDays": 30
                    },
                    "limits": {
                      "storesPerWindow": 40000,
                      "windowDays": 30
                    },
                    "talkToUs": "https://installgraph.com/talk-to-us",
                    "signUp": {
                      "endpoint": "POST /v1/keys",
                      "body": {
                        "email": "you@company.com"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/get-pricing"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/pricing\""
          }
        ]
      }
    },
    "/v1/billing/purchase": {
      "post": {
        "tags": [
          "Billing"
        ],
        "operationId": "agentPurchase",
        "summary": "Buy a credit pack on the saved card",
        "description": "Buys `starter` ($50, 500 credits), `growth` ($150, 2,500), `pro` ($400, 10,000) or `scale` ($1,000,\n40,000) on the card saved at the account's first checkout. Off until the account owner turns on\nagent purchases and sets per-purchase and 30-day limits (`403 purchase_not_allowed`).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "pack"
                ],
                "properties": {
                  "pack": {
                    "type": "string",
                    "enum": [
                      "starter",
                      "growth",
                      "pro",
                      "scale"
                    ]
                  }
                }
              },
              "example": {
                "pack": "starter"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "`{ data: { pack, credits, priceUsd, balance } }`",
            "content": {
              "application/json": {
                "example": {
                  "data": {
                    "pack": "starter",
                    "credits": 500,
                    "priceUsd": 50,
                    "balance": 546
                  }
                }
              }
            }
          },
          "402": {
            "description": "`payment_failed` or `spend_cap_reached`"
          },
          "403": {
            "description": "`purchase_not_allowed`"
          },
          "409": {
            "description": "`no_payment_method`"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/agent-purchase"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl -X POST \"https://api.installgraph.com/v1/billing/purchase\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"pack\":\"starter\"}'"
          }
        ]
      }
    },
    "/v1/apps": {
      "get": {
        "tags": [
          "Apps"
        ],
        "operationId": "listApps",
        "summary": "The app catalogue",
        "description": "Every app we recognise, by slug. Free. Scope `apps:read`.",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Category"
            }
          },
          {
            "$ref": "#/components/parameters/limit"
          },
          {
            "$ref": "#/components/parameters/cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of apps, by slug",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/App"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "slug": "klaviyo",
                      "name": "Klaviyo",
                      "category": "email-sms",
                      "website": "klaviyo.com",
                      "appStoreUrl": "https://apps.shopify.com/klaviyo-email-marketing",
                      "iconUrl": "https://cdn.shopify.com/app-store/listing_images/klaviyo/icon.png",
                      "rating": 4.6,
                      "reviewCount": 2730
                    }
                  ],
                  "pagination": {
                    "nextCursor": "eyJrIjoiYXBwcyIsInMiOiJrbGF2aXlvIn0",
                    "hasMore": true
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                    "creditsUsed": 0,
                    "creditsCharged": 0,
                    "creditsRemaining": 46,
                    "freeRepulls": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/list-apps"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/apps?category=email-sms&limit=1\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\""
          }
        ]
      }
    },
    "/v1/apps/{slug}/companies": {
      "get": {
        "tags": [
          "Apps"
        ],
        "operationId": "listAppCompanies",
        "summary": "Stores running an app",
        "description": "Stores whose latest healthy scan found the app, by domain. 1 credit per row. Scope `companies:read`.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "klaviyo"
            }
          },
          {
            "$ref": "#/components/parameters/country"
          },
          {
            "$ref": "#/components/parameters/region"
          },
          {
            "$ref": "#/components/parameters/industry"
          },
          {
            "$ref": "#/components/parameters/aov"
          },
          {
            "$ref": "#/components/parameters/limit"
          },
          {
            "$ref": "#/components/parameters/cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of stores",
            "headers": {
              "X-Credits-Charged": {
                "$ref": "#/components/headers/CreditsCharged"
              },
              "X-Credits-Remaining": {
                "$ref": "#/components/headers/CreditsRemaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AppCompany"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "domain": "example.net",
                      "name": "Example Knitwear",
                      "country": "GB",
                      "region": "europe",
                      "industry": {
                        "category": "Apparel",
                        "subcategory": "Knitwear",
                        "path": "/Apparel/Knitwear",
                        "confidence": "medium"
                      },
                      "pricePoint": {
                        "aovBand": "50-100",
                        "label": "$50–100",
                        "confidence": "medium",
                        "medianProductPriceUsd": 72,
                        "productPriceRangeUsd": [
                          58,
                          94
                        ],
                        "productPricesSeen": 18
                      },
                      "currency": "GBP",
                      "status": "live",
                      "lastScannedAt": "2026-11-01T22:15:03.000Z",
                      "firstSeenAt": "2026-02-08T09:30:00.000Z",
                      "lastSeenAt": "2026-11-01T22:15:03.000Z",
                      "evidence": [
                        "webPixel"
                      ]
                    },
                    {
                      "domain": "example.org",
                      "name": "Example Outdoor",
                      "country": "GB",
                      "region": "europe",
                      "industry": {
                        "category": "Apparel",
                        "subcategory": null,
                        "path": "/Apparel",
                        "confidence": "low"
                      },
                      "pricePoint": null,
                      "currency": "GBP",
                      "status": "live",
                      "lastScannedAt": "2026-10-31T18:02:51.000Z",
                      "firstSeenAt": "2026-05-19T11:47:20.000Z",
                      "lastSeenAt": "2026-10-31T18:02:51.000Z",
                      "evidence": [
                        "themeAppExtension",
                        "script"
                      ]
                    }
                  ],
                  "pagination": {
                    "nextCursor": "eyJrIjoiYXBwLWNvbXBhbmllcyIsImQiOiJleGFtcGxlLm9yZyJ9",
                    "hasMore": true
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                    "creditsUsed": 2,
                    "creditsCharged": 2,
                    "creditsRemaining": 47,
                    "freeRepulls": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/list-app-companies"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/apps/klaviyo/companies?country=GB&industry=Apparel&limit=2\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\""
          }
        ]
      }
    },
    "/v1/events": {
      "get": {
        "tags": [
          "Events"
        ],
        "operationId": "listEvents",
        "summary": "Installs and removals",
        "description": "The change stream, oldest first, so you can read it forward: page with the cursor, and resume a later\nread with `since` set to the last `detectedAt` you have (cursors last 24 hours). An\nevent is reported by the scan that saw the change: the change happened between `previousScanAt`\nand `detectedAt`. A store's first scan reports no installs (we cannot say when they happened), and\nremovals are only inferred from a scan that read the whole live page. Each event carries the\nstore's current country, region and industry. With `country`, `region` or `industry`, a page can\nhold fewer than `limit` events while `hasMore` is true. 1 credit per row. Scope `events:read`.\n",
        "parameters": [
          {
            "name": "app",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "klaviyo"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "installed",
                "removed"
              ]
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "Events detected at or after this time (ISO 8601).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "until",
            "in": "query",
            "description": "Events detected before this time (ISO 8601).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "$ref": "#/components/parameters/country"
          },
          {
            "$ref": "#/components/parameters/region"
          },
          {
            "$ref": "#/components/parameters/industry"
          },
          {
            "$ref": "#/components/parameters/aov"
          },
          {
            "$ref": "#/components/parameters/limit"
          },
          {
            "$ref": "#/components/parameters/cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of events",
            "headers": {
              "X-Credits-Charged": {
                "$ref": "#/components/headers/CreditsCharged"
              },
              "X-Credits-Remaining": {
                "$ref": "#/components/headers/CreditsRemaining"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/RequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Event"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "evt_6720a4c3f1b2",
                      "type": "removed",
                      "domain": "example.com",
                      "app": {
                        "slug": "klaviyo",
                        "name": "Klaviyo",
                        "category": "email-sms"
                      },
                      "detectedAt": "2026-10-12T04:20:31.000Z",
                      "previousScanAt": "2026-10-05T03:58:10.000Z",
                      "lastSeenAt": "2026-10-05T03:58:10.000Z",
                      "country": "US",
                      "region": "north-america",
                      "industry": {
                        "category": "Apparel",
                        "subcategory": "Footwear",
                        "path": "/Apparel/Footwear",
                        "confidence": "high"
                      },
                      "pricePoint": {
                        "aovBand": "100-200",
                        "label": "$100–200",
                        "confidence": "medium",
                        "medianProductPriceUsd": 128,
                        "productPriceRangeUsd": [
                          95,
                          165
                        ],
                        "productPricesSeen": 24
                      }
                    }
                  ],
                  "pagination": {
                    "nextCursor": "eyJrIjoiZXZlbnRzIiwiaWQiOiJldnRfNjcyMGE0YzNmMWIyIn0",
                    "hasMore": true
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                    "creditsUsed": 1,
                    "creditsCharged": 1,
                    "creditsRemaining": 46,
                    "freeRepulls": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/list-events"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/events?app=klaviyo&type=removed&since=2026-10-01T00%3A00%3A00Z&limit=1\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\""
          }
        ]
      }
    },
    "/v1/industries": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "listIndustries",
        "summary": "The industry taxonomy, regions and order-value bands",
        "description": "The values `industry` and `region` accept. Industries are the Store Leads category taxonomy at two\nlevels (26 categories, 182 subcategories); each store's industry is our own reading of its\nhomepage. Regions group the countries stores sell from. Free; any key.\n",
        "responses": {
          "200": {
            "description": "Industries and regions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "industries": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "example": "Apparel"
                              },
                              "path": {
                                "type": "string",
                                "example": "/Apparel"
                              },
                              "subcategories": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "string",
                                      "example": "Footwear"
                                    },
                                    "path": {
                                      "type": "string",
                                      "example": "/Apparel/Footwear"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "regions": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "$ref": "#/components/schemas/Region"
                              },
                              "name": {
                                "type": "string",
                                "example": "North America"
                              },
                              "countries": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        },
                        "aovBands": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "example": "100-200"
                              },
                              "label": {
                                "type": "string",
                                "example": "$100–200"
                              }
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": {
                    "industries": [
                      {
                        "name": "Apparel",
                        "path": "/Apparel",
                        "subcategories": [
                          {
                            "name": "Footwear",
                            "path": "/Apparel/Footwear"
                          }
                        ]
                      }
                    ],
                    "regions": [
                      {
                        "id": "north-america",
                        "name": "North America",
                        "countries": [
                          "US",
                          "CA"
                        ]
                      }
                    ],
                    "aovBands": [
                      {
                        "id": "100-200",
                        "label": "$100–200"
                      }
                    ]
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                    "creditsUsed": 0,
                    "creditsCharged": 0,
                    "creditsRemaining": 46,
                    "freeRepulls": 0
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/list-industries"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/industries\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\""
          }
        ]
      }
    },
    "/v1/public/stats": {
      "get": {
        "tags": [
          "Public"
        ],
        "operationId": "getPublicStats",
        "summary": "App popularity by category, region and industry",
        "security": [],
        "description": "No key. Recomputed daily over every store we scanned. Per app category: how many stores run any\napp in it, and its ten most installed apps, each broken down by region and top-level industry\n(`unknown` for stores without a country or an industry reading yet). 30 requests a minute per IP;\ncacheable for an hour.\n",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Category"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "computedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "companies": {
                          "type": "integer"
                        },
                        "byRegion": {
                          "$ref": "#/components/schemas/Breakdown"
                        },
                        "byIndustry": {
                          "$ref": "#/components/schemas/Breakdown"
                        },
                        "regions": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Region id to name."
                        },
                        "categories": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "category": {
                                "$ref": "#/components/schemas/Category"
                              },
                              "companies": {
                                "type": "integer"
                              },
                              "byRegion": {
                                "$ref": "#/components/schemas/Breakdown"
                              },
                              "byIndustry": {
                                "$ref": "#/components/schemas/Breakdown"
                              },
                              "apps": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "slug": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    },
                                    "kind": {
                                      "type": "string",
                                      "enum": [
                                        "shopify-app",
                                        "web"
                                      ]
                                    },
                                    "companies": {
                                      "type": "integer"
                                    },
                                    "share": {
                                      "type": "number",
                                      "description": "Share of all stores counted, 0–1."
                                    },
                                    "byRegion": {
                                      "$ref": "#/components/schemas/Breakdown"
                                    },
                                    "byIndustry": {
                                      "$ref": "#/components/schemas/Breakdown"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "computedAt": "2026-11-06T02:00:00.000Z",
                    "companies": 412806,
                    "byRegion": {
                      "north-america": 221034,
                      "europe": 109877,
                      "asia-pacific": 52410,
                      "latin-america": 14988,
                      "middle-east-africa": 9877,
                      "unknown": 4620
                    },
                    "byIndustry": {
                      "Apparel": 88312,
                      "Beauty & Fitness": 51207,
                      "unknown": 30114
                    },
                    "regions": {
                      "north-america": "North America",
                      "europe": "Europe"
                    },
                    "categories": [
                      {
                        "category": "email-sms",
                        "companies": 198440,
                        "byRegion": {
                          "north-america": 112307,
                          "europe": 50122
                        },
                        "byIndustry": {
                          "Apparel": 47210
                        },
                        "apps": [
                          {
                            "slug": "klaviyo",
                            "name": "Klaviyo",
                            "category": "email-sms",
                            "companies": 96120,
                            "share": 0.2328,
                            "byRegion": {
                              "north-america": 58014
                            },
                            "byIndustry": {
                              "Apparel": 24877
                            }
                          }
                        ]
                      }
                    ]
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14"
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/get-public-stats"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/public/stats?category=email-sms\""
          }
        ]
      }
    },
    "/v1/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getUsage",
        "summary": "Your balance and recent usage",
        "description": "Free, and needs no scope.",
        "responses": {
          "200": {
            "description": "The key's balance, prices and usage",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Usage"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": {
                    "key": {
                      "prefix": "sfs_01234567",
                      "owner": "you@company.com",
                      "name": "Default",
                      "scopes": [
                        "companies:read",
                        "apps:read",
                        "events:read"
                      ]
                    },
                    "credits": {
                      "balance": 46,
                      "unlimited": false
                    },
                    "rateLimit": {
                      "perMinute": 60,
                      "remaining": 59,
                      "resetAt": "2026-11-06T10:15:00.000Z"
                    },
                    "prices": {
                      "GET /v1/companies/{domain}": {
                        "perRequest": 1
                      },
                      "GET /v1/apps/{slug}/companies": {
                        "perRow": 1
                      }
                    },
                    "last30Days": {
                      "since": "2026-10-07T10:14:12.000Z",
                      "requests": 3,
                      "credits": 4,
                      "byEndpoint": [
                        {
                          "endpoint": "GET /v1/apps/{slug}/companies",
                          "requests": 1,
                          "rows": 2,
                          "credits": 2
                        },
                        {
                          "endpoint": "GET /v1/companies/{domain}",
                          "requests": 1,
                          "rows": 1,
                          "credits": 1
                        },
                        {
                          "endpoint": "GET /v1/events",
                          "requests": 1,
                          "rows": 1,
                          "credits": 1
                        }
                      ]
                    },
                    "recent": [
                      {
                        "at": "2026-11-06T10:14:02.000Z",
                        "type": "usage",
                        "amount": -1,
                        "credits": 1,
                        "balanceAfter": 46,
                        "endpoint": "GET /v1/events",
                        "rows": 1,
                        "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                        "note": null
                      },
                      {
                        "at": "2026-11-05T16:20:41.000Z",
                        "type": "grant",
                        "amount": 25,
                        "credits": 25,
                        "balanceAfter": 50,
                        "endpoint": null,
                        "rows": null,
                        "requestId": null,
                        "note": "Verified email"
                      }
                    ]
                  },
                  "meta": {
                    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
                    "creditsUsed": 0,
                    "creditsCharged": 0,
                    "creditsRemaining": 46,
                    "freeRepulls": 0
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "externalDocs": {
          "url": "https://installgraph.com/docs/reference/get-usage"
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl",
            "source": "curl \"https://api.installgraph.com/v1/usage\" \\\n  -H \"Authorization: Bearer $INSTALLGRAPH_API_KEY\""
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer sfs_…`"
      },
      "headerKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      },
      "queryKey": {
        "type": "apiKey",
        "in": "query",
        "name": "key",
        "description": "`?key=sfs_…`, for a URL opened in a browser. Read only when no header is sent."
      }
    },
    "parameters": {
      "limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500,
          "default": 100
        }
      },
      "country": {
        "name": "country",
        "in": "query",
        "description": "ISO 3166-1 alpha-2 country the store sells from (Shopify's `Shopify.country`).",
        "schema": {
          "type": "string",
          "example": "US",
          "pattern": "^[A-Za-z]{2}$"
        }
      },
      "region": {
        "name": "region",
        "in": "query",
        "description": "A world region, i.e. its countries. Combined with `country`, both must hold.",
        "schema": {
          "$ref": "#/components/schemas/Region"
        }
      },
      "industry": {
        "name": "industry",
        "in": "query",
        "description": "A top-level industry (`Apparel`, which also matches stores placed at that level only) or a subcategory (`Apparel/Footwear`). `GET /v1/industries` lists them.",
        "schema": {
          "type": "string",
          "example": "Apparel/Footwear"
        }
      },
      "aov": {
        "name": "aov",
        "in": "query",
        "description": "One or more typical order-value bands in USD, comma-separated (`100-200,200-500`). `GET /v1/industries` lists them.",
        "schema": {
          "type": "string",
          "example": "100-200"
        }
      },
      "cursor": {
        "name": "cursor",
        "in": "query",
        "description": "`pagination.nextCursor` from the previous page, unchanged, within 24 hours, with the same key's account and the same filters.",
        "schema": {
          "type": "string"
        }
      }
    },
    "headers": {
      "CreditsCharged": {
        "schema": {
          "type": "integer"
        },
        "description": "Credits this request cost."
      },
      "CreditsRemaining": {
        "schema": {
          "type": "integer"
        },
        "description": "Balance after this request. Absent for unlimited keys."
      },
      "RateLimitLimit": {
        "schema": {
          "type": "integer"
        },
        "description": "Requests allowed per minute."
      },
      "RateLimitRemaining": {
        "schema": {
          "type": "integer"
        },
        "description": "Requests left in this minute."
      },
      "RateLimitReset": {
        "schema": {
          "type": "integer"
        },
        "description": "Epoch seconds when the window resets."
      },
      "RequestId": {
        "schema": {
          "type": "string"
        },
        "description": "Quote this when asking for support."
      }
    },
    "responses": {
      "BadRequest": {
        "description": "`invalid_request` (a bad parameter) or `invalid_cursor`",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "`missing_api_key`, `invalid_api_key` or `api_key_revoked`",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "`insufficient_credits` (the balance cannot cover one row or lookup) or `usage_cap_reached` (40,000 stores in 30 days). Nothing was charged. `error.offers` holds the cheapest pack's buy link and Talk to us.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "`insufficient_scope` (the key lacks this endpoint's scope) or `api_key_suspended`",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "`not_found`: no data for this domain or app (or not scanned yet). Free, except domain lookups past the free-miss allowance (1 credit; see `GET /v1/companies/{domain}`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "`rate_limited`. Wait `Retry-After` seconds.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "requestId"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "invalid_cursor",
                  "invalid_email",
                  "missing_api_key",
                  "invalid_api_key",
                  "api_key_revoked",
                  "insufficient_credits",
                  "usage_cap_reached",
                  "spend_cap_reached",
                  "payment_failed",
                  "insufficient_scope",
                  "api_key_suspended",
                  "purchase_not_allowed",
                  "not_found",
                  "method_not_allowed",
                  "account_exists",
                  "no_payment_method",
                  "rate_limited",
                  "internal_error",
                  "not_configured",
                  "service_unavailable"
                ]
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              }
            }
          }
        }
      },
      "Meta": {
        "type": "object",
        "required": [
          "requestId",
          "creditsCharged",
          "creditsRemaining"
        ],
        "properties": {
          "requestId": {
            "type": "string"
          },
          "creditsUsed": {
            "type": "integer",
            "description": "Credits this request cost."
          },
          "creditsCharged": {
            "type": "integer",
            "description": "The same as creditsUsed (the original name)."
          },
          "freeRepulls": {
            "type": "integer",
            "description": "Stores served free because you unlocked them in the last 7 days."
          },
          "preview": {
            "type": "object",
            "description": "Present when an account that has never bought a pack reads a list, which is cut to its first `rows` rows.",
            "properties": {
              "rows": {
                "type": "integer",
                "example": 50
              },
              "message": {
                "type": "string"
              }
            }
          },
          "creditsRemaining": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Null for unlimited keys."
          }
        }
      },
      "Pagination": {
        "type": "object",
        "required": [
          "nextCursor",
          "hasMore"
        ],
        "properties": {
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasMore": {
            "type": "boolean"
          }
        }
      },
      "Category": {
        "type": "string",
        "enum": [
          "ads-pixel",
          "analytics",
          "tag-management",
          "server-side-tracking",
          "attribution",
          "email-sms",
          "reviews",
          "loyalty",
          "subscriptions",
          "search",
          "upsell-personalisation",
          "popups",
          "support-chat",
          "consent",
          "accessibility",
          "shipping-protection",
          "returns-tracking",
          "fraud",
          "payments-bnpl",
          "affiliate",
          "wishlist",
          "back-in-stock",
          "translation",
          "page-builder",
          "ab-testing",
          "cross-border",
          "product-feeds",
          "other"
        ]
      },
      "Region": {
        "type": "string",
        "enum": [
          "north-america",
          "latin-america",
          "europe",
          "middle-east-africa",
          "asia-pacific"
        ]
      },
      "Industry": {
        "type": "object",
        "description": "Our reading of what the store sells, from its homepage, in the Store Leads taxonomy.",
        "required": [
          "category",
          "subcategory",
          "path",
          "confidence"
        ],
        "properties": {
          "category": {
            "type": "string",
            "example": "Apparel"
          },
          "subcategory": {
            "type": [
              "string",
              "null"
            ],
            "example": "Footwear",
            "description": "Null when the store fits a category but none of its subcategories (a general bookshop)."
          },
          "path": {
            "type": "string",
            "example": "/Apparel/Footwear",
            "description": "`/Books & Literature` alone when there is no subcategory."
          },
          "confidence": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "high",
              "medium",
              "low",
              null
            ]
          }
        }
      },
      "PricePoint": {
        "type": "object",
        "description": "The store's typical order value, in USD bands so it reads the same in every country. Our own reading of\nthe homepage: the product prices shown there (converted from the store's currency), and what is sold.\n",
        "required": [
          "aovBand",
          "label",
          "confidence",
          "medianProductPriceUsd",
          "productPriceRangeUsd",
          "productPricesSeen"
        ],
        "properties": {
          "aovBand": {
            "type": "string",
            "enum": [
              "under-25",
              "25-50",
              "50-100",
              "100-200",
              "200-500",
              "500-1000",
              "1000-plus"
            ]
          },
          "label": {
            "type": "string",
            "example": "$100–200"
          },
          "confidence": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "high",
              "medium",
              "low",
              null
            ]
          },
          "medianProductPriceUsd": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Median product price on the homepage, in USD."
          },
          "productPriceRangeUsd": {
            "type": [
              "array",
              "null"
            ],
            "description": "Interquartile range of homepage product prices, in USD.",
            "items": {
              "type": "integer"
            }
          },
          "productPricesSeen": {
            "type": "integer"
          }
        }
      },
      "Breakdown": {
        "type": "object",
        "description": "Store counts by region id or industry name, with `unknown` for stores lacking one.",
        "additionalProperties": {
          "type": "integer"
        }
      },
      "Evidence": {
        "type": "string",
        "enum": [
          "webPixel",
          "themeAppExtension",
          "appProxy",
          "customPixel",
          "script",
          "html"
        ]
      },
      "Status": {
        "type": "string",
        "description": "The latest scan's verdict: `live`, `password` (behind a password page), `closed` (store\nunavailable), `not_shopify` (the domain no longer serves a Shopify store), or `unreachable` (we\ncould not read the page this time). Apps are from the latest `live` scan (`lastHealthyScanAt`).\n",
        "enum": [
          "live",
          "password",
          "closed",
          "not_shopify",
          "unreachable"
        ]
      },
      "AppSummary": {
        "type": "object",
        "required": [
          "slug",
          "name",
          "category",
          "kind"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "example": "klaviyo"
          },
          "name": {
            "type": "string",
            "example": "Klaviyo"
          },
          "category": {
            "$ref": "#/components/schemas/Category"
          },
          "kind": {
            "type": "string",
            "enum": [
              "shopify-app",
              "web"
            ],
            "description": "`shopify-app`: an app installed from Shopify. `web`: a website technology installed outside Shopify, by pasting its tag into the theme or through a tag manager (Google Tag Manager, Meta Pixel, Hotjar). A vendor with both has one entry of each (`meta-pixel` and `meta-facebook-instagram-app`)."
          }
        }
      },
      "App": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AppSummary"
          },
          {
            "type": "object",
            "required": [
              "website",
              "appStoreUrl",
              "iconUrl",
              "rating",
              "reviewCount"
            ],
            "properties": {
              "website": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "klaviyo.com"
              },
              "appStoreUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "example": "https://apps.shopify.com/klaviyo-email-marketing"
              },
              "iconUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "App Store icon (Shopify CDN); append ?width=72&height=72 to resize."
              },
              "rating": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Average App Store rating, 1–5."
              },
              "reviewCount": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          }
        ]
      },
      "CompanyApp": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AppSummary"
          },
          {
            "type": "object",
            "required": [
              "firstSeenAt",
              "lastSeenAt",
              "evidence"
            ],
            "properties": {
              "firstSeenAt": {
                "type": "string",
                "format": "date-time",
                "description": "First scan that found it."
              },
              "lastSeenAt": {
                "type": "string",
                "format": "date-time",
                "description": "Latest scan that found it."
              },
              "evidence": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Evidence"
                }
              }
            }
          }
        ]
      },
      "Company": {
        "type": "object",
        "required": [
          "domain",
          "name",
          "myshopifyDomain",
          "country",
          "region",
          "industry",
          "pricePoint",
          "currency",
          "locale",
          "status",
          "theme",
          "lastScannedAt",
          "lastHealthyScanAt",
          "customPixelCount",
          "apps"
        ],
        "properties": {
          "domain": {
            "type": "string",
            "example": "allbirds.com"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "myshopifyDomain": {
            "type": [
              "string",
              "null"
            ],
            "example": "allbirds.myshopify.com"
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "example": "US"
          },
          "region": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Region"
              },
              {
                "type": "null"
              }
            ]
          },
          "industry": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Industry"
              },
              {
                "type": "null"
              }
            ]
          },
          "pricePoint": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PricePoint"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "type": [
              "string",
              "null"
            ],
            "example": "USD"
          },
          "locale": {
            "type": [
              "string",
              "null"
            ],
            "example": "en"
          },
          "status": {
            "$ref": "#/components/schemas/Status"
          },
          "theme": {
            "type": [
              "object",
              "null"
            ],
            "required": [
              "name",
              "version",
              "themeStoreId",
              "customName",
              "since"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "The theme's own name (schema name), e.g. Dawn."
              },
              "version": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "themeStoreId": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Shopify Theme Store id, for a store theme."
              },
              "customName": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "What the merchant named their copy."
              },
              "since": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "First scan on this theme."
              }
            }
          },
          "lastScannedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastHealthyScanAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "customPixelCount": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Custom pixels in Shopify's Customer events."
          },
          "apps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompanyApp"
            }
          }
        }
      },
      "AppCompany": {
        "type": "object",
        "required": [
          "domain",
          "name",
          "country",
          "region",
          "industry",
          "pricePoint",
          "currency",
          "status",
          "lastScannedAt",
          "firstSeenAt",
          "lastSeenAt",
          "evidence"
        ],
        "properties": {
          "domain": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "region": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Region"
              },
              {
                "type": "null"
              }
            ]
          },
          "industry": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Industry"
              },
              {
                "type": "null"
              }
            ]
          },
          "pricePoint": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PricePoint"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/Status"
          },
          "lastScannedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "firstSeenAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastSeenAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "evidence": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Evidence"
            }
          }
        }
      },
      "Event": {
        "type": "object",
        "required": [
          "id",
          "type",
          "domain",
          "app",
          "detectedAt",
          "previousScanAt",
          "lastSeenAt",
          "country",
          "region",
          "industry",
          "pricePoint"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "installed",
              "removed"
            ]
          },
          "domain": {
            "type": "string"
          },
          "app": {
            "$ref": "#/components/schemas/AppSummary"
          },
          "detectedAt": {
            "type": "string",
            "format": "date-time",
            "description": "The scan that saw the change."
          },
          "previousScanAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The healthy scan before it."
          },
          "lastSeenAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "For a removal, the last scan that still saw the app."
          },
          "country": {
            "type": [
              "string",
              "null"
            ],
            "description": "The store's current country."
          },
          "region": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Region"
              },
              {
                "type": "null"
              }
            ]
          },
          "industry": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Industry"
              },
              {
                "type": "null"
              }
            ]
          },
          "pricePoint": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PricePoint"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "Usage": {
        "type": "object",
        "required": [
          "key",
          "credits",
          "rateLimit",
          "prices",
          "last30Days",
          "recent"
        ],
        "properties": {
          "key": {
            "type": "object",
            "properties": {
              "prefix": {
                "type": "string",
                "example": "sfs_Ab12Cd34"
              },
              "owner": {
                "type": "string"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "scopes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "companies:read",
                    "apps:read",
                    "events:read"
                  ]
                }
              }
            }
          },
          "credits": {
            "type": "object",
            "properties": {
              "balance": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Null for unlimited keys."
              },
              "unlimited": {
                "type": "boolean"
              }
            }
          },
          "rateLimit": {
            "type": "object",
            "properties": {
              "perMinute": {
                "type": "integer"
              },
              "remaining": {
                "type": "integer"
              },
              "resetAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "prices": {
            "type": "object",
            "description": "Credits per endpoint, `{ perRequest }` or `{ perRow }`.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "perRequest": {
                  "type": "integer"
                },
                "perRow": {
                  "type": "integer"
                }
              }
            }
          },
          "last30Days": {
            "type": "object",
            "properties": {
              "since": {
                "type": "string",
                "format": "date-time"
              },
              "requests": {
                "type": "integer",
                "description": "Billed requests (free ones are not recorded)."
              },
              "credits": {
                "type": "integer"
              },
              "byEndpoint": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "endpoint": {
                      "type": "string"
                    },
                    "requests": {
                      "type": "integer"
                    },
                    "rows": {
                      "type": "integer"
                    },
                    "credits": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "recent": {
            "type": "array",
            "description": "The latest 50 ledger entries, newest first.",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "usage",
                    "grant",
                    "purchase",
                    "refund",
                    "adjustment"
                  ]
                },
                "amount": {
                  "type": "integer",
                  "description": "Change to the balance."
                },
                "credits": {
                  "type": "integer"
                },
                "balanceAfter": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "endpoint": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "rows": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "requestId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "note": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "externalDocs": {
    "url": "https://installgraph.com/docs",
    "description": "Guides and reference, each page also as Markdown (append .md)"
  }
}
