# The app catalogue

`GET /v1/apps`

Lists every app we recognise by slug, with its category, App Store link and rating, **free**.

- **Auth:** API key ([Authentication](https://installgraph.com/docs/authentication.md))
- **Scope:** `apps:read`
- **Cost:** Free.

Use it to find an app's `slug` for the other endpoints, or to list one category with `category`.

Every app we recognise, by slug. Free. Scope `apps:read`.

With `q`, apps by name as merchants know them, ranked: exact `displayName`, then exact `brand`, exact alias, `displayName` by prefix, `brand` or alias by prefix, and last a word of the listing title; within each, most installed first. `q` is matched by prefix, ignoring case, spaces and punctuation (`judge.me`, `Judge Me` and `judgeme` are the same). Pages follow the ranking (pass back `nextCursor` with the same `q`).

## Request

```bash
curl "https://api.installgraph.com/v1/apps?category=email-sms&limit=1" \
  -H "Authorization: Bearer $INSTALLGRAPH_API_KEY"
```

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string | No | An app's name, brand, former title or abbreviation, or the start of one: `klaviyo`, `stoq`, `swym wish`, `revenuehunt`. At least 2 letters or digits. Example: `stoq`. |
| `category` | Category | No | One of 28 values (see [Data model](https://installgraph.com/docs/data-model.md)). |
| `limit` | integer | No | 1–500. Default `100`. |
| `cursor` | string | No | `pagination.nextCursor` from the previous page, unchanged, within 24 hours, with the same key's account and the same filters. |

## Response

`200`. The example's stores are fictional.

```json
{
  "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
  }
}
```

### Fields

| Field | Type | Description |
| --- | --- | --- |
| `data[].slug` | string | Example: `klaviyo`. |
| `data[].name` | string | The catalogue's name: our own for apps we curate, else the App Store listing title as written. Example: `Klaviyo`. |
| `data[].displayName` | string | What a merchant calls the app, read from its keyword-padded App Store title ("Preorder, Back In Stock ‑ STOQ" is `STOQ`). A developer's listings that share a brand keep the words that tell them apart (`Swym Wishlist Plus`). Equal to `name` until derived. Example: `Klaviyo`. |
| `data[].category` | Category | One of 28 values (see [Data model](https://installgraph.com/docs/data-model.md)). |
| `data[].kind` | string | `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`). One of `shopify-app`, `web`. |
| `data[].website` | string \| null | Example: `klaviyo.com`. |
| `data[].appStoreUrl` | string \| null | Example: `https://apps.shopify.com/klaviyo-email-marketing`. |
| `data[].iconUrl` | string \| null | App Store icon (Shopify CDN); append ?width=72&height=72 to resize. |
| `data[].rating` | number \| null | Average App Store rating, 1–5. |
| `data[].reviewCount` | integer \| null |  |
| `data[].brand` | string \| null | The vendor merchants know; null until derived. Example: `Swym`. |
| `data[].aliases` | string[] | Other names the app goes by: the listing title, former titles, Partner handles, abbreviations in the title (`RH`). |

Every keyed response also carries `meta` (`requestId`, `creditsUsed`, `creditsRemaining`, `freeRepulls`) and the `X-Credits-*` and `X-RateLimit-*` headers. See [Credits](https://installgraph.com/docs/credits.md) and [Rate limits](https://installgraph.com/docs/rate-limits.md).

Lists page with `limit` and `cursor`. See [Pagination](https://installgraph.com/docs/pagination.md).

## Errors

| Status | Code | Meaning | What to do |
| --- | --- | --- | --- |
| 400 | `invalid_request` | A parameter or body field is missing or malformed. | Fix the request; `message` names the field. Do not retry unchanged. |
| 400 | `invalid_cursor` | The `cursor` is not one this endpoint issued (edited, truncated, or from another list). | Pass `pagination.nextCursor` back unchanged, or start again without a cursor. |
| 401 | `missing_api_key` | No key was sent. | Send `Authorization: Bearer sfs_…` or `X-API-Key: sfs_…`. |
| 401 | `invalid_api_key` | The key is not one we issued. | Check for truncation or whitespace; keys are `sfs_` plus 32 letters and digits. |
| 401 | `api_key_revoked` | The key was revoked. | Make a new key at installgraph.com/account. |
| 403 | `insufficient_scope` | The key lacks this endpoint's scope. | Use a key with the scope the endpoint lists (`GET /v1/usage` shows yours). |
| 403 | `api_key_suspended` | The key is suspended. | Talk to us, quoting `requestId`. |
| 429 | `rate_limited` | Too many requests this minute. | Wait `Retry-After` seconds, then retry. |

All codes: [Errors](https://installgraph.com/docs/errors.md).
