---
title: Pinned results
slug: graph/docs/pinned-results
docTags: 
createdAt: 2026-07-30T20:30:19.480Z
---

Pinned results let you promote selected content when a user's search query matches a specific phrase. These items display at the top of the search results because they receive a higher boost weight than any organic match.

For example, when a user searches for "water," you want to promote bottled water products. To do this, define the search phrase and the content to promote in Optimizely Graph, and enable pinned results in the query using the `pinned` argument.

## Define pinned results in Optimizely Graph

Define pinned results in Optimizely Graph to control which items rise to the top of search results for chosen phrases, so merchandisers and content editors can guarantee visibility for priority content. Pinned items live inside collections you create through the Gateway REST endpoint, and each collection groups related pins for one editorial use case.

Optimizely Graph stores pinned results in a pinned results collection. Create multiple collections, but each pinned result must belong to a collection.

### Create a collection

To create a collection, send an authorized request to the GraphQL Gateway REST endpoint using your HMAC and secret keys using the following endpoint. For more information, go to [Pinned Results Endpoints](docId\:Ymt8R5EsKRYBHwqG3pJkL).

```http
POST /<GATEWAY_URL>/api/pinned/collections
```

Include the following values in the request body:

- `title` – Required. The name of the collection, used for management purposes.
- `key` – Required. A unique identifier for the collection that contains no whitespace, such as `seasonal-campaign`. GraphQL queries reference collections by this key, not by the collection ID.
- `isActive` – Set to `true` to enable the collection and its pinned items. Defaults to `false`, so set it explicitly if you want the collection to take effect immediately.

```json
{
  "title": "Seasonal campaign",
  "key": "seasonal-campaign",
  "isActive": true
}
```

The response returns the stored collection, including the generated `id`:

```json
{
  "id": "e4c0b166-ce40-4620-b872-35af8d4fab22",
  "title": "Seasonal campaign",
  "key": "seasonal-campaign",
  "isActive": true,
  "createdAt": "2026-09-30 10:12:04",
  "updatedAt": "2026-09-30 10:12:04"
}
```

Note both values. Use the `id` in the REST paths that add and manage pinned items, and use the `key` in the `pinned` argument of your GraphQL queries.

### Add a pinned item

Add a pinned item to bind a target content GUID to a trigger phrase inside an existing collection, so the item surfaces at the top of the result set when a user searches for that phrase.

When a collection exists, add items to it using the following endpoint:

```http
POST /<GATEWAY_URL>/api/pinned/collections/{collectionId}/items
```

Include these fields in the request body:

- `phrases` – Required. The single search phrase that triggers this pinned result. Matching is a case-insensitive comparison of the whole phrase against the `phrase` value in the query, not a partial or token match. To trigger the same content from several phrases, create one pinned item per phrase.
- `targetKey` – Required. The key that identifies the content to pin. In Optimizely CMS 13 and Optimizely CMS (SaaS), use the content's `_metadata.key`. In earlier CMS versions, use the content GUID from `ContentLink.GuidValue`.
- `language` – The language the pinned item applies to. Use a language code such as `en` or a full CMS locale such as `sv-SE` to match how the content stores its language. Use `null` (the default) to apply the item to all languages, or an empty string (`""`) for the neutral locale.
- `priority` – A number that orders pinned items relative to each other. A **higher** number ranks higher, so an item with `priority: 10` appears above an item with `priority: 1`. Defaults to `1000`.
- `isActive` – Set to `false` to deactivate the pinned item without deleting it. Defaults to `true`.

```json
{
  "phrases": "water",
  "targetKey": "12345678-abcd-1234-abcd-1234567890ab",
  "language": "en",
  "priority": 10,
  "isActive": true
}
```

Within one collection, the combination of `phrases`, `targetKey`, and `language` must be unique. A request that duplicates an existing combination fails.

To update an existing item, send the same body to `PUT /<GATEWAY_URL>/api/pinned/collections/{collectionId}/items/{id}`.

To find the `targetKey` in Optimizely CMS 13 or Optimizely CMS (SaaS), query `_metadata.key`:

```graphql
query {
  _Content(where: { _metadata: { displayName: { contains: "water" } } }) {
    items {
      _metadata {
        key
        displayName
      }
    }
  }
}
```

In earlier CMS versions, query `ContentLink.GuidValue` instead:

```graphql
query {
  Content(where: { Name: { contains: "water" } }) {
    items {
      Name
      ContentLink {
        GuidValue
      }
    }
  }
}
```

## Apply pinned results to query

Apply pinned results inside a GraphQL query to merge promoted items into a regular search response, so users see editorial picks at the top alongside organic matches. The `pinned` argument controls which phrase and which collections drive the promotion.

To apply pinned results, use the `pinned` argument in your GraphQL query.

```graphql
query MyQuery {
  Content(
    where: { _fulltext: { match: "water" } }
    locale: en
    pinned: { phrase: "water", collections: ["seasonal-campaign"] }
  ) {
    items {
      _score
      _id
      Name
      MainBody
      Status
    }
    total
  }
}
```

The `pinned` argument includes two fields:

- `phrase` – The user search query to match against the `phrases` value of your pinned items. If you omit this field or pass a blank value, Optimizely Graph applies no pinned results.
- `collections` – A list of collection **keys** to draw pinned items from. Pass the `key` you set when creating the collection, not the collection `id` or GUID. When you omit this field, Optimizely Graph evaluates all active collections.

Optimizely Graph only considers items whose collection and item are both active (`isActive: true`).

### How pinned results are ranked

Optimizely Graph applies at most **five** pinned items to a single query. When more than five items match the phrase, Optimizely Graph keeps the five with the highest `priority` and ignores the rest.

Among the applied items, a higher `priority` number ranks higher. Pinned items always score above every non-pinned result, so they occupy the top of the result set in priority order, followed by organic matches in their normal relevance order.

Because language is part of the match, always specify `locale` in the query. If you omit the locale, Optimizely Graph may evaluate pinned items across all languages and return unexpected results.

### Limitations

- Pinned results are not supported in nested queries. Use the `pinned` argument only on a top-level content query.
- Optimizely Graph pins internal content only. It has no equivalent for pinning an external URL.
- Optimizely Graph has no pinned-specific title, description, or display styling. Query the content's own fields and apply styling in your application.

## Example

The following example shows a reusable pinned-results query, so you can pass the search text and collection key at runtime instead of hard-coding them.

To make your query reusable, define variables for the search text and collection key as shown in the following sample:

```graphql
query MyQuery($searchText: String!, $collectionKey: String!, $locale: [Locales!]!) {
  Content(
    where: { _fulltext: { match: $searchText } }
    locale: $locale
    pinned: { phrase: $searchText, collections: [$collectionKey] }
  ) {
    items {
      _score
      _id
      Name
    }
  }
}
```

## Manage collections and items

The following endpoints manage pinned collections and their items. All of them require HMAC, Bearer, or Basic authentication.

| Operation                       | Endpoint                                                                                              |
| ------------------------------- | ----------------------------------------------------------------------------------------------------- |
| List collections                | `GET /api/pinned/collections` (supports `page` and `sort`, such as `sort=title:ASC`)                  |
| Get a collection                | `GET /api/pinned/collections/{collectionId}`                                                          |
| Update a collection             | `PUT /api/pinned/collections/{collectionId}`                                                          |
| Delete a collection             | `DELETE /api/pinned/collections/{collectionId}`                                                       |
| List items in a collection      | `GET /api/pinned/collections/{collectionId}/items` (supports `limit`, `offset`, `phrase`, and `sort`) |
| Get an item                     | `GET /api/pinned/collections/{collectionId}/items/{id}`                                               |
| Update an item                  | `PUT /api/pinned/collections/{collectionId}/items/{id}`                                               |
| Delete an item                  | `DELETE /api/pinned/collections/{collectionId}/items/{id}`                                            |
| Clear all items in a collection | `DELETE /api/pinned/collections/{collectionId}/items`                                                 |

A collection must be empty before you can delete it. Clear its items first, then delete the collection.
