---
title: Index API
description: Using WP Engine Smart Search Index API for indexing records
url: https://developers.wpengine.com/docs/smart-search/graphql-api/indexing/
image: https://developers.wpengine.com/og/docs/smart-search/graphql-api/indexing.png
---

# Index API

The public API includes mutations:

- [index](https://developers.wpengine.com/docs/smart-search/graphql-api/indexing/#creating-or-updating-a-document) mutation for creating or updating a document
- [bulkIndex](https://developers.wpengine.com/docs/smart-search/graphql-api/indexing/#creating-or-updating-multiple-documents) mutation for creating or updating multiple document
- [delete](https://developers.wpengine.com/docs/smart-search/graphql-api/indexing/#deleting-a-document) mutation for deleting a document
- [deleteAll](https://developers.wpengine.com/docs/smart-search/graphql-api/indexing/#deleting-all-documents) mutation for deleting all documents

To use a mutation, you need to [authenticate](https://developers.wpengine.com/docs/smart-search/graphql-api/indexing/#authentication).

---

## Authentication

Clients calling the API mutations are required to add an authentication header with the valid authentication token.

```
Authorization: Bearer {ACCESS_TOKEN}
```

Data needed to consume API can be found in your WP Admin area in the WP Engine Smart Search tab under `Settings`.

![WP Engine Smart Search Settings](https://developers.wpengine.com/_astro/as-plugin-settings.Bs9gXCGQ_Z2idWUG.webp)

---

## Creating or Updating a Document

To create or update a document in the index using the mutation, you need to:

1. Use the `index` mutation.

2. Provide a `DocumentInput` object as a parameter.

3. In the `DocumentInput` object, provide the necessary document data as a `JSON` object.

4. To ensure a document has a unique identifier in the `DocumentInput` object, follow these guidelines:

   - The `id` field of the `DocumentInput` object should be used to provide a unique identifier for the document. This field is required for updating a document.
   - If an `id` is provided in the `DocumentInput` object, the system checks whether a document with that `id` already exists. If it does, the existing document is updated with the new data instead of creating a new document.
   - In cases where no `id` is provided in the `DocumentInput` object, the system automatically generates a unique identifier for the document. This ensures that each document has a unique identifier, even if one is not explicitly provided. By following these guidelines, you can effectively handle document creation and updates, ensuring uniqueness of identifiers and appropriate handling based on the presence of an `id` in the `DocumentInput` object.
   - The `data` field is required and contains all the index data.

5. Optionally, you can include metadata by using the `meta` field. This allows you to provide additional information that will be logged on the server. Metadata can be helpful for analyzing and understanding the logs more effectively. Meta data includes optional fields:

   - `system` - should be the name of the client “Atlas Search v0.2.24”
   - `action` - the name of the action performed e. g. “manual-index”
   - `source` - hostname from where action has been performed e. g. “atlasce.wpengine.com”

### GraphQL example to create a document

```graphql
mutation CreateIndexDocument($input: DocumentInput!) {
  index(input: $input) {
    success
    code
    message
    document {
      id
      data
    }
  }
}
```

GraphQL Variables

```json
{
  "input": {
    "data": {
      "ID": 1,
      "post_title": "Post Title",
      "post_excerpt": "Post Excerpt",
      "post_content": "Post Content",
      "post_date": "11-06-2023T12:33:00",
      "post_type": "post",
      "post_status": "publish"
    },
    "meta": {
      "system": "Atlas Search v0.2.24",
      "action": "manual-index",
      "source": "cms.themessenger.com"
    }
  }
}
```

Mutation Response

```json
{
  "data": {
    "index": {
      "success": true,
      "code": "200",
      "message": "Document was indexed successfully",
      "document": {
        "id": "yMI9vogB0FEetE6QV9fh",
        "data": {
          "ID": 1,
          "post_title": "Post Title",
          "post_excerpt": "Post Excerpt",
          "post_content": "Post Content",
          "post_date": "11-06-2023T12:33:00",
          "post_type": "post",
          "post_status": "publish"
        }
      }
    }
  }
}
```

In this example, we’re creating a new document with fields: `ID, post_title, post_excerpt, post_content, post_date, post_type, post_status`. The mutation returns a `DocumentMutationResponse` object that includes fields:

- `success` - a boolean says if operation is successful or not
- `code` - string with number of response code (200 - is success)
- `message` - human readable operation status
- `document` with `id` and `data`.

To create a new document with a provided `id` or update an existing document, you can use the index mutation. The behavior depends on whether a document with the provided id already exists:

- If a document with the provided `id` doesn’t exist, a new document will be created with the specified `id`.
- If a document with the provided `id` already exists, the existing document will be updated with the new data.

To create a new document with a provided `id` or update an existing document, you need to provide the `id` of the document you want to update in the `DocumentInput` object.

### GraphQL example to update a document

```graphql
mutation UpdateIndexDocument($input: DocumentInput!) {
  index(input: $input) {
    success
    code
    message
    document {
      id
      data
    }
  }
}
```

GraphQL Variables

```json
{
  "input": {
    "id": "yMI9vogB0FEetE6QV9fh",
    "data": {
      "post_title": "Post with updated title"
    },
    "meta": {
      "system": "Atlas Search v0.2.24",
      "action": "manual-index",
      "source": "cms.themessenger.com"
    }
  }
}
```

Mutation Response

```json
{
  "data": {
    "index": {
      "success": true,
      "code": "200",
      "message": "Document was indexed successfully",
      "document": {
        "id": "yMI9vogB0FEetE6QV9fh",
        "data": {
          "post_title": "Post with updated title"
        }
      }
    }
  }
}
```

In this example, we’re updating an existing document with the `id` of `yMI9vogB0FEetE6QV9fh`. We are mutating `post_title` field of the document. The mutation returns a `DocumentMutationResponse` object.

The same behavior would occur even if the document did not already exist. In that case, it would be created with the provided `id` and the `DocumentMutationResponse` would include this `id`.

> **Caution**
>
> Rest of the fields not specified in the input will be removed. In this case it will remove `ID, post_excerpt, post_content, post_date, post_type, post_status` and only `post_title` will be added.

### Indexing third party data

It is recommended to have a data structure to tag third party data so that it can be filtered later if needed. Otherwise, by default, the search query considers every document in the index.

To index third party data, provision a WP environment with smart search. Then, by using the url and access_token found on the WP Smart Search settings page, configure the third party data client with these credentials and then calling the index API.

Once the application is running the headless app, use the find api to query for documents held in the index.

The only way to obtain a license at the moment is to purchase a plan that has the smart-search entitlement.

### Code sample

The following is an example written in javascript which queries a “space” endpoint and indexes the first record via the WP Engine Smart Search API.

```javascript
const spaceUrl =
  'https://www.space.com/api/product_search?first_edition=true&ship_to_country=USA&minimum_price=50';
const spaceHeaders = {
  'X-API-KEY': 'YOUR_SPACE_API_KEY',
};
const spacePayload = {
  method: 'GET',
  headers: spaceHeaders,
};
const smartSearchEndpoint = 'YOUR_SMART_SEARCH_URL';
const smartSearchHeaders = {
  'Content-Type': 'application/json',
  Authorization: 'Bearer YOUR_SMART_SEARCH_TOKEN',
};


// First lets fetch data from the space endpoint
fetch(spaceUrl, spacePayload)
  .then((response) => response.json())
  .then((data) => {
    // Here lets get the first document returned in the response
    const firstDocument = data.data[0];
    // lets image the data structure is the following
    // { "id": 12345, "title": "hello" }
    // lets create a custom id by prepending 'space:'
    const documentId = `space:${firstDocument.id}`;
    // assign our variables for the index request


    // add space as the root of the document
    const variables = {
      input: {
        id: documentId,
        data: {
          space: firstDocument,
        },
      },
    };
    // This is the graphql mutation for indexing  documents
    // a link to the API documentation can be found at the top
    // of this document
    const mutation = `
    mutation CreateIndexDocument($input: DocumentInput!) {
      index(input: $input) {
        success
        code
        message
        document {
          id
          data
        }
      }
    }
  `;
    const payload = {
      method: 'POST',
      headers: smartSearchHeaders,
      body: JSON.stringify({
        query: mutation,
        variables: variables,
      }),
    };
    // Send the GraphQL request which will index  the first document
    return fetch(smartSearchEndpoint, payload);
  })
  .then((response) => response.json())
  .then((data) => {
    if (data.errors) {
      throw new Error(data.errors[0].message);
    } else {
      console.log(data);
    }
  })
  .catch((error) => console.error('Error:', error));
```

```json
{
  "post_title": "Star Wars",
  "post_contents": "Star Wars conent",
  "post_type": "metadata"
}
```

![Third Party Data Diagram](https://developers.wpengine.com/_astro/third-party-data.J3zVlmrU_ZGtw8W.webp)

### Sample query filtering for just metadata content

```graphql
query FindSimpleQuery {
  find(query: "Star Wars", filter: "post_type:metadata") {
    total
    documents {
      id
      data
    }
  }
}
```

These query appendages could happen under the hood or just considering all content

```graphql
query FindSimpleQuery {
  find(query: "Star Wars", filter: "post_type:post,metadata") {
    total
    documents {
      id
      data
    }
  }
}
```

---

## Creating or Updating multiple Documents

To create or update multiple documents in one API call you need to:

1. Use the `bulkIndex` mutation.

2. Provide a `BulkIndexInput` object as a parameter.

3. In the `BulkIndexInput` object, provide the necessary document data as a `JSON` object.

4. To ensure that each document has a unique identifier in the `BulkIndexInput` object, follow these guidelines:

   - The `id` field of a `BulkIndexInput` document object should be used to provide a unique identifier for each document. This field is required for updating a document.
   - If an `id` is provided in the `BulkIndexInput` document object, the system checks whether a document with that `id` already exists. If it does, the existing document is updated with the new data instead of creating a new document.
   - In cases where no `id` is provided in the `BulkIndexInput` document object, the system automatically generates a unique identifier for the document. This ensures that each document has a unique identifier, even if one is not explicitly provided. By following these guidelines, you can effectively handle document creation and updates, ensuring uniqueness of identifiers and appropriate handling based on the presence of an `id` in the `DocumentInput` object.
   - The `data` field is required and contains all the index data.

5. Optionally, you can include metadata by using the `meta` field. This allows you to provide additional information that will be logged on the server. Metadata can be helpful for analyzing and understanding the logs more effectively. Meta data includes optional fields:

   - `system` - should be the name of the client “Atlas Search v0.2.24”
   - `action` - the name of the action performed e. g. “manual-index”
   - `source` - hostname from where action has been performed e. g. “atlasce.wpengine.com”

### GraphQL example to create multiple documents

```graphql
mutation CreateBulkIndexDocuments($input: BulkIndexInput!) {
  bulkIndex(input: $input) {
    code
    success
    documents {
      id
    }
  }
}
```

GraphQL Variables

```json
{
  "input": {
    "documents": [
      {
        "data": {
          "ID": 1,
          "post_title": "Post Title",
          "post_excerpt": "Post Excerpt",
          "post_content": "Post Content",
          "post_date": "11-06-2023T12:33:00",
          "post_type": "post",
          "post_status": "publish"
        }
      },
      {
        "data": {
          "ID": 2,
          "post_title": "Post Title2",
          "post_excerpt": "Post Excerpt2",
          "post_content": "Post Content2",
          "post_date": "11-08-2023T12:33:00",
          "post_type": "post",
          "post_status": "publish"
        }
      }
    ]
  }
}
```

Mutation Response

```json
{
  "data": {
    "bulkIndex": {
      "code": "200",
      "success": true,
      "documents": [
        {
          "id": "9932_pABTRDKaIXj6AyZ"
        },
        {
          "id": "-N32_pABTRDKaIXj6AyZ"
        }
      ]
    }
  }
}
```

In this example, we’re creating two new documents with fields: `ID, post_title, post_excerpt, post_content, post_date, post_type, post_status`. The mutation returns a `BulkIndexMutationResponse` object that includes fields:

- `success` - a boolean says if operation is successful or not
- `code` - string with number of response code (200 - is success)
- `message` - human-readable operation status
- `document` with `id`.

To create a new documents with a provided `id` or update an existing document, you can still use the `bulkIndex` mutation. The behavior depends on whether a document with the provided id already exists:

- If a document with the provided `id` doesn’t exist, a new document will be created with the specified `id`.
- If a document with the provided `id` already exists, the existing document will be updated with the new data.

To create a new document with a provided `id` or update an existing document, you need to provide the `id` of the document you want to update in the `BulkIndexInput` object.

### GraphQL example to update multiple documents

```graphql
mutation UpdateBulkIndexDocuments($input: BulkIndexInput!) {
  bulkIndex(input: $input) {
    code
    success
    documents {
      id
    }
  }
}
```

GraphQL Variables

```json
{
  "input": {
    "documents": [
      {
        "id": "post:1",
        "data": {
          "ID": 1,
          "post_title": "Changed Post Title",
          "post_excerpt": "Post Excerpt",
          "post_content": "Post Content",
          "post_date": "11-06-2023T12:33:00",
          "post_type": "post",
          "post_status": "publish"
        }
      },
      {
        "id": "post:2",
        "data": {
          "ID": 2,
          "post_title": "Changed Post Title2",
          "post_excerpt": "Post Excerpt2",
          "post_content": "Post Content2",
          "post_date": "11-08-2023T12:33:00",
          "post_type": "post",
          "post_status": "publish"
        }
      }
    ]
  },
  "meta": {
    "system": "Atlas Search v0.2.24",
    "action": "manual-index",
    "source": "cms.themessenger.com"
  }
}
```

Mutation Response

```json
{
  "data": {
    "bulkIndex": {
      "code": "200",
      "success": true,
      "documents": [
        {
          "id": "post:1"
        },
        {
          "id": "post:2"
        }
      ]
    }
  }
}
```

In this example, we’re updating an existing documents with the `id`s of `post:1`, `post:2`. We are mutating `post_title` field of the document. The mutation returns a `BulkIndexMutationResponse` object.

The same behavior would occur even if a document did not already exist. In that case, it would be created with the provided `id` and the `BulkIndexMutationResponse` would include this `id`.

**IMPORTANT Rest of the fields not specified in the input will be removed.**\
In this case it will remove `ID, post_excerpt, post_content, post_date, post_type, post_status` and only `post_title` will be added.

---

## Deleting a Document

To delete a document from the index, you need to:

1. Use the `delete` mutation.

2. Provide the `id` of the document you want to delete.

3. Optionally provide metadata by using the `meta` field. This allows you to provide additional information that will be logged on the server. Including metadata can be helpful for analyzing and understanding the logs more effectively. Meta data includes optional fields:

   - `system` - should be the name of the client “Atlas Search v0.2.24”
   - `action` - the name of the action performed e. g. “manual-index”
   - `source` - hostname from where action has been performed e. g. “atlasce.wpengine.com”

### GraphQL example to delete a document

```graphql
mutation deleteDocument($id: ID!, $meta: MetaInput) {
  delete(id: $id, meta: $meta) {
    code
    success
    message
    document {
      id
      data
    }
  }
}
```

GraphQL Variables

```json
{
  "id": "yMI9vogB0FEetE6QV9fh",
  "meta": {
    "system": "Atlas Search v0.2.24",
    "action": "manual-delete",
    "source": "cms.themessenger.com"
  }
}
```

GraphQL Response

```json
{
  "data": {
    "delete": {
      "code": "200",
      "success": true,
      "message": "Document was deleted successfully",
      "document": {
        "id": "yMI9vogB0FEetE6QV9fh",
        "data": {}
      }
    }
  }
}
```

We are deleting a document with the `id` of `yMI9vogB0FEetE6QV9fh`.\
The mutation returns a `DocumentMutationResponse` object that includes the `id` and `data` fields of the deleted document.

---

## Deleting All Documents

To delete all documents from the index you need to:

1. Use `deleteAll` mutation.
2. Optionally provide metadata by using the `meta` field. This allows you to provide additional information that will be logged on the server. Including metadata can be helpful for analyzing and understanding the logs more effectively.

### GraphQL Example to Delete All Documents

```graphql
mutation deleteAllDocuments($meta: MetaInput) {
  deleteAll(meta: $meta) {
    code
    success
    message
  }
}
```

GraphQL Variables

```json
{
  "meta": {
    "system": "Atlas Search v0.2.24",
    "action": "reset-data",
    "source": "cms.themessenger.com"
  }
}
```

GraphQL Response

```json
{
  "data": {
    "deleteAll": {
      "code": "200",
      "success": true,
      "message": "Delete all documents was successful"
    }
  }
}
```

## Was this helpful?

Thanks for the feedback!

```json
{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://developers.wpengine.com/#website","name":"WP Engine Product Documentation","url":"https://developers.wpengine.com/","description":"Resources for developing, deploying, and scaling on WP Engine.","inLanguage":"en-US","keywords":["API documentation","product documentation","headless WordPress","managed WordPress hosting"],"publisher":{"@id":"https://wpengine.com/#organization"}}]}
```
