> ## Documentation Index
> Fetch the complete documentation index at: https://backstage.spotify.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# API Client

> Use the fully-typed Soundcheck REST API client to programmatically interact with checks, tracks, campaigns, fact collectors, exemptions, results, and facts from your own backend code.

## Overview

The `@spotify/backstage-plugin-soundcheck-client` package exposes a fully-typed REST API client generated from the Soundcheck OpenAPI spec. It lets you programmatically interact with every Soundcheck endpoint from your own Backstage backend modules, custom plugins, or scripts -- without manually constructing HTTP requests.

## Installation

```sh theme={"theme":{"light":"github-light","dark":"dracula"}}
yarn workspace backend add @spotify/backstage-plugin-soundcheck-client
```

## Creating the client

Use `createSoundcheckApiClient` to instantiate the client. It requires a Backstage `discoveryApi` for service-to-service URL resolution and accepts an optional `fetchApi` for custom fetch behavior (e.g., service-to-service auth).

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
import { createSoundcheckApiClient } from '@spotify/backstage-plugin-soundcheck-client';

const client = createSoundcheckApiClient({
  discoveryApi, // from @backstage/core-plugin-api or backend plugin environment
  fetchApi, // optional -- defaults to cross-fetch
});
```

<Info>
  If you're calling the Soundcheck API from another backend plugin, you can
  obtain `discoveryApi` and `fetchApi` from the plugin environment provided by
  `coreServices`.
</Info>

## Available endpoint groups

The client provides methods for the following endpoint groups:

| Group               | Methods                                                                                                                                                                       |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Checks**          | `getChecks`, `getCheck`, `createChecks`, `updateCheck`, `deleteCheck`, `executeChecks`                                                                                        |
| **Check status**    | `getCheckStatus`, `getCheckStatusHistory`, `getCheckStatusWithFilter`, `getCheckStatusHistoryWithFilter`                                                                      |
| **Tracks**          | `getTracks`, `getTrack`, `createTracks`, `updateTrack`, `deleteTrack`, `getTrackEntities`                                                                                     |
| **Certifications**  | `getCertifications`, `getCertificationStatus`, `getCertificationStatusHistory`, `getCertificationStatusWithFilter`, `getCertificationStatusHistoryWithFilter`, `certifyWorld` |
| **Campaigns**       | `getCampaigns`, `getCampaign`, `createCampaigns`, `updateCampaign`, `deleteCampaign`, `getCampaignEntities`                                                                   |
| **Fact collectors** | `getFactCollectors`, `getFactCollector`, `createFactCollectors`, `updateFactCollector`, `deleteFactCollector`, `triggerFactCollection`                                        |
| **Exemptions**      | `getExemptions`, `getRevokedExemptions`, `createExemption`, `revokeExemption`, `restoreExemption`                                                                             |
| **Results**         | `getResults`, `submitResults`, `deleteResults`                                                                                                                                |
| **Facts**           | `submitFacts`                                                                                                                                                                 |

Every method is fully typed -- parameter shapes (path, query, body) and response types are inferred from the OpenAPI spec, so your editor will provide autocompletion and type-checking out of the box.

## Usage examples

### Reading data

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
// List all checks
const checksResponse = await client.getChecks({});
const checks = await checksResponse.json();

// Get a single track by ID
const trackResponse = await client.getTrack({
  path: { trackId: 'my-track' },
});
const track = await trackResponse.json();

// Get check results for an entity
const resultsResponse = await client.getResults({
  query: { entityRef: 'component:default/my-service' },
});
const results = await resultsResponse.json();

// List campaigns
const campaignsResponse = await client.getCampaigns({ query: {} });
const campaigns = await campaignsResponse.json();

// List fact collectors
const collectorsResponse = await client.getFactCollectors({});
const collectors = await collectorsResponse.json();

// Get exemptions for a specific check
const exemptionsResponse = await client.getExemptions({
  query: { checkId: 'has-pagerduty' },
});
const exemptions = await exemptionsResponse.json();
```

### Writing data

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
// Submit facts from an external source
await client.submitFacts({
  body: {
    facts: [
      {
        factRef: 'my-collector:default/my-fact',
        entityRef: 'component:default/my-service',
        data: { version: '2.0.1' },
      },
    ],
  },
});

// Submit check results from an external system
await client.submitResults({
  body: {
    results: [
      {
        checkId: 'my-external-check',
        entityRef: 'component:default/my-service',
        state: 'passed',
      },
    ],
  },
  query: { returnUpdatedResults: true },
});

// Trigger on-demand fact collection
await client.triggerFactCollection({
  body: {
    entityRefs: ['component:default/my-service'],
  },
});
```

### Authentication

All methods accept an optional `options` parameter with a bearer token for service-to-service authentication:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
const response = await client.getChecks({}, { token: myServiceToken });
```

## Using generated types

Generated model types are available under the `SoundcheckApiTypes` namespace:

```ts theme={"theme":{"light":"github-light","dark":"dracula"}}
import { SoundcheckApiTypes } from '@spotify/backstage-plugin-soundcheck-client';

type Check = SoundcheckApiTypes.Check;
type Track = SoundcheckApiTypes.Track;
type Campaign = SoundcheckApiTypes.Campaign;
```

<Tip>
  For the full list of available endpoints and their parameters, see the [API
  Reference](/plugins/soundcheck/api-reference/checks/get-checks).
</Tip>
