﻿---
title: Best practices for Scout API tests
description: Best practices specific to Scout API tests. Use the right fixture for the right purpose: Prefer tests that read like “call endpoint X as role Y, assert...
url: https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/api-best-practices
products:
  - Kibana
---

# Best practices for Scout API tests
Best practices specific to Scout **API tests**.
<tip>
  For guidance that applies to both UI and API tests, see the [general Scout best practices](https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/best-practices). Scout is built on Playwright, so the official [Playwright Best Practices](https://playwright.dev/docs/best-practices) also apply.
</tip>


## Validate endpoints with `apiClient`

Use the right fixture for the right purpose:

| Fixture                       | Use for                                                                                                                                               |
|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `apiClient`                   | The endpoint under test (with scoped credentials from [API auth](https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/api-auth)) |
| `apiServices`                 | Setup/teardown and side effects                                                                                                                       |
| `kbnClient`, `esClient`, etc. | Lower-level setup when `apiServices` doesn’t have a suitable helper                                                                                   |

Prefer tests that read like “call endpoint X as role Y, assert outcome”.
<dropdown title="Example">
  ```ts
  import { expect } from '@kbn/scout/api';

  apiTest.beforeAll(async ({ requestAuth, apiServices }) => {
    await apiServices.myFeature.createTestData();
    viewerCredentials = await requestAuth.getApiKeyForViewer();
  });

  apiTest('returns data for viewer', async ({ apiClient }) => {
    const response = await apiClient.get('api/my-feature/data', {
      headers: { ...COMMON_HEADERS, ...viewerCredentials.apiKeyHeader },
    });

    expect(response).toHaveStatusCode(200);
    expect(response.body.items).toHaveLength(3);
  });
  ```
</dropdown>

This pattern validates both endpoint behavior and the [permission model](/elastic/kibana/tree/main/extend/scout/best-practices#test-with-minimal-permissions-avoid-admin-when-possible).

## Choose the right auth pattern

Scout supports two authentication methods for API tests. Choose based on endpoint type:

| Endpoint type                | Auth method          | Fixture                        |
|------------------------------|----------------------|--------------------------------|
| Public APIs (`api/*`)        | API key              | `requestAuth` + `apiKeyHeader` |
| Internal APIs (`internal/*`) | Cookie-based session | `samlAuth` + `cookieHeader`    |

See [API authentication](https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/api-auth) for details and examples.

## Validate the response body (not just status)

Status code assertions are necessary but not sufficient. Also validate shape and key fields.
<dropdown title="Examples">
  ❌ **Don’t:** assert only the status code:
  ```ts
  apiTest('returns autocomplete definitions', async ({ apiClient }) => {
    const response = await apiClient.get('api/console/api_server', {
      headers: { ...COMMON_HEADERS, ...viewerCredentials.apiKeyHeader },
    });

    expect(response).toHaveStatusCode(200);
  });
  ```
  ✔️ **Do:** validate shape and key fields too:
  ```ts
  apiTest('returns autocomplete definitions', async ({ apiClient }) => {
    const response = await apiClient.get('api/console/api_server', {
      headers: { ...COMMON_HEADERS, ...viewerCredentials.apiKeyHeader },
    });

    expect(response).toHaveStatusCode(200);
    expect(response.body).toMatchObject({
      es: {
        endpoints: expect.any(Object),
        globals: expect.any(Object),
        name: 'es',
      },
    });
  });
  ```
</dropdown>


## Related guides

- [General best practices](https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/best-practices) — apply to both UI and API tests
- [Write API tests](https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/write-api-tests)
- [API authentication](https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/api-auth)
- [API services](https://docs-v3-preview.elastic.dev/elastic/kibana/tree/main/extend/scout/api-services)
- [Parallelism notes for API tests](/elastic/kibana/tree/main/extend/scout/parallelism#api-tests-and-parallelism)