---
title: "Search games"
method: GET
path: "/v2/marketplace/search"
tags: ["marketplace"]
---

# Search games

`GET /v2/marketplace/search`

Search for games in the Microsoft Store.

**Response Structure:**
- `content`: Search results with matching games
- `code`: HTTP status code from upstream

## Market and device family

`market` and `deviceFamily` are optional and default to `US` and
`Windows.Desktop` - omit them and behaviour is unchanged.

Both affect results. `deviceFamily=Windows.Xbox` drops PC-only entries such as demos;
`market` changes both availability and ordering.

**Note:** `locale` comes from your account setting, while `market` defaults to `US`
regardless. If your account locale is, say, `hu-HU`, the default request is
`market=US&locale=hu-HU` - a mismatched pair that measurably worsens result relevance.
If your account locale is not US English, pass a matching `market` (e.g.
`?market=HU`). The default is left as `US` so existing integrations do not shift
underneath them.

## Pagination

Responses include `Payload.NextUri`, which contains a `cursor` query parameter.
Extract that `cursor` value and pass it back to get the next page, keeping your other
parameters identical:

```
GET /v2/marketplace/search?q=halo
GET /v2/marketplace/search?q=halo&cursor=bz0wJmI9OU5WM0wyMzRWR1hE...
```

Pass only the `cursor` value, not the whole `NextUri`.

Keep following `NextUri` until it stops coming back. Two things to be aware of on
cursor pages:

- `FilterOptions` is returned on the first page only, so treat it as optional.
- Per-product fields that depend on promotions (`StrikethroughPrice`,
  `SubscriptionDiscountMessageTemplate`, `SkusSummary[].IncludedWith`) appear only for
  products that are on sale or included with a subscription. They are absent otherwise
  on any page - do not rely on them being present.

## Result relevance

This endpoint is backed by the Microsoft Store search, which always returns roughly 20
cards and pads the tail with recommendations once it runs out of genuine matches. A
search for a game with few close matches will return mostly unrelated titles, and the
upstream exposes no relevance score to filter on.

If you want strict matching, use `GET /v2/marketplace/autosuggest`, which matches on
title and returns only real matches.

## Getting title IDs

Search results carry a `ProductId`, not an Xbox title ID. Pass `enrich=titleid` to
attach an `XboxTitleId` field to every result:

```
GET /v2/marketplace/search?q=halo&enrich=titleid
```

`XboxTitleId` is `null` for products that genuinely have none - add-ons, bundles and
some PC-only listings. In a typical 20-result page around 16 resolve and 4 come back
`null`. This also makes it possible to tell apart two listings of the same game that
are otherwise identical by title.

The field is only present when you ask for it. Without `enrich=titleid` the response
has no `XboxTitleId` key at all, which keeps the default response byte-for-byte what
it was before.

Enrichment costs an additional upstream catalog lookup, so it is off by default.

## Query parameters

- `q` string, required
- `market` string
- `deviceFamily` string
- `cursor` string
- `enrich` string

## Response `200`

Search results

- ApiResponse — Standard API response wrapper. All endpoints return responses in this format.
  - `content` unknown, required
  - `code` integer, required — HTTP status code from the upstream API. Common values: 200 (success), 400 (bad request), 401 (unauthorized), 404 (not found), 410 (deprecated/gone), 429 (rate limited), 500 (server error)

## Other responses

- `401` — Invalid or missing API key
- `429` — Rate limit exceeded

---

[API](https://skmtc.dev/xbl/apis/openxbl-api.md) · [All operations](https://skmtc.dev/xbl/apis/openxbl-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/xbl/openxbl-api/revisions/e5df7bdca559/schema)
