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

# Partner API

> Run an AI-visibility scan of any company from your own product, and receive the result as it firms up.

The Partner API is a different product from the [public API](https://docs.getsurfaced.ai/api/public-api.md). It is for partners embedding Surfaced's competitor scan in their own tools: give it a company, get back how that company appears in AI answers.

It needs a partner key, issued per partner. A Surfaced account key will not work here, and a partner key will not work on the public API.

## Authentication

```bash theme={null}
curl https://www.getsurfaced.ai/api/partner/competitor-scan \
  -H "Authorization: Bearer gsk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ ... }'
```

Two kinds of key:

* **`gsk_live_`** runs real scans, persists them and counts against your rate limit.
* **`gsk_test_`** validates the request exactly as live would, then returns a deterministic sandbox result marked `sandbox: true`. Nothing is stored and no rate limit is consumed.

Build against the test key. It fails on the same malformed requests the live key does, so a client that works against it works in production.

## The flow

**1. Start a scan**

`POST /api/partner/competitor-scan` returns an id.

**2. Poll, or receive a webhook**

`GET /api/partner/competitor-scan/{id}` returns the current state. Signed webhooks deliver the same payloads without polling.

**3. Read the result**

A scan produces up to two generations of payload, distinguished by `revision`.

## Progressive delivery

This is the part to design for. A scan does not go from nothing to a final answer: it emits a **preliminary** payload as soon as it has something usable, and may follow with a revised one as the slower parts land.

So your integration should expect to receive the same scan twice, with the later revision superseding the earlier. Render the preliminary result, then update it. Treating the first payload as final gives your users a thinner answer than they paid for; waiting for the second makes the scan feel broken.

## Other endpoints

* `GET /api/partner/scans` lists what you have run.
* `GET /api/partner/usage` gives your consumption against the rate limit.

The generated reference beside this page carries every field, every status and the webhook payload shapes, straight from the live specification.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.