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

# API Response Shapes and Data Formats

> The Hog API uses predictable response shapes for sync, async, and operation polling flows.

The Hog API keeps response shapes stable for each endpoint so you can parse results and correlate requests reliably. This page describes the common sync, async, and polling patterns.

## The `X-Request-Id` header

Every authenticated response includes an `X-Request-Id` HTTP header containing a UUID that uniquely identifies the request. This value is also mirrored inside the response body as `meta.requestId`. Save it when you contact support — it lets the team locate the exact request in logs instantly.

```bash theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Example response header
X-Request-Id: 3f7a1c2e-88b4-4d0e-a1f5-0c9e2b3d7f4a
```

## Sync response (HTTP 200)

Fast operations complete within the request lifecycle and return HTTP 200. When an endpoint uses an envelope, the `data` field holds the endpoint-specific payload.

```json theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
// HTTP 200 — synchronous result
{
  "data": {
    // endpoint-specific payload, e.g. an array of companies or a context object
  },
  "meta": {
    "requestId": "3f7a1c2e-88b4-4d0e-a1f5-0c9e2b3d7f4a"
  }
}
```

## Async accepted response (HTTP 202)

Long-running operations — batch enrichment, search, and deep research — are accepted immediately and processed in the background. The response contains everything you need to poll for the result.

```json theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
// HTTP 202 — async job accepted
{
  "id": "op_01HZ9K2QW3RV4M5N6P7Q8R9S0T",
  "operationId": "op_01HZ9K2QW3RV4M5N6P7Q8R9S0T",
  "status": "queued",
  "pollUrl": "https://developer.thehog.ai/api/operations/op_01HZ9K2QW3RV4M5N6P7Q8R9S0T",
  "meta": {
    "requestId": "3f7a1c2e-88b4-4d0e-a1f5-0c9e2b3d7f4a"
  }
}
```

| Field            | Type   | Description                                       |
| ---------------- | ------ | ------------------------------------------------- |
| `id`             | string | Unique ID for the background job                  |
| `operationId`    | string | Unique ID for the background job                  |
| `status`         | string | Always `"queued"` on acceptance                   |
| `pollUrl`        | string | Fully-qualified URL to poll for status and result |
| `meta.requestId` | string | Correlates to the `X-Request-Id` header           |

Use `pollUrl` directly in subsequent `GET` requests. See [Operation status response](#operation-status-response-get-apioperationsid) below for the shape returned while polling.

## Operation status response (`GET /api/operations/:id`)

Poll this endpoint after receiving a 202 to check progress and retrieve the result when the job finishes.

```json theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
// In-progress operation
{
  "id": "op_01HZ9K2QW3RV4M5N6P7Q8R9S0T",
  "status": "processing",
  "progress": 45, // 0–100, or null when not yet tracked
  "result": null, // null until status is "succeeded"
  "error": null // null unless status is "failed"
}
```

```json theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Completed operation
{
  "id": "op_01HZ9K2QW3RV4M5N6P7Q8R9S0T",
  "status": "succeeded",
  "progress": 100,
  "result": {
    // endpoint-specific result payload
  },
  "error": null
}
```

```json theme={null} theme={"theme":{"light":"github-light","dark":"github-dark"}}
// Failed operation
{
  "id": "op_01HZ9K2QW3RV4M5N6P7Q8R9S0T",
  "status": "failed",
  "progress": null,
  "result": null,
  "error": {
    "message": "No results were found for the given input."
  }
}
```

### Operation statuses

<CardGroup cols={2}>
  <Card title="queued" icon="clock">
    The job has been accepted and is waiting for a worker to pick it up.
  </Card>

  <Card title="processing" icon="spinner">
    A worker is actively running the job. Check `progress` (0–100) for completion
    percentage.
  </Card>

  <Card title="succeeded" icon="circle-check">
    The job finished successfully. Read the result from the `result` field.
  </Card>

  <Card title="failed" icon="circle-xmark">
    The job encountered an unrecoverable error. Details are in the `error` field.
  </Card>

  <Card title="partial_success" icon="triangle-exclamation">
    The job completed but some sub-tasks did not succeed. `result` contains
    whatever was produced.
  </Card>

  <Card title="cancelled" icon="ban">
    The job was cancelled before it completed.
  </Card>
</CardGroup>

| Field      | Type            | Description                                                          |
| ---------- | --------------- | -------------------------------------------------------------------- |
| `id`       | string          | Operation ID matching the `operationId` from the 202 response        |
| `status`   | string          | Current status (see table above)                                     |
| `progress` | integer \| null | Completion percentage (0–100), or `null` if not yet tracked          |
| `result`   | object \| null  | Result payload when `status` is `"succeeded"` or `"partial_success"` |
| `error`    | object \| null  | Error detail when `status` is `"failed"`                             |

### Search result metadata

Search operations return a `result` object with `data` and `meta` fields when they finish. For people search scoped to target accounts, the metadata can include safe target-account status fields:

| Field                     | Values                                                                                                                | Meaning                                                                                                                                                                                      |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `targetAccountSearchMode` | `linkedin_company_page`, `profile_current_company`, `unavailable`                                                     | How the search constrained people to the requested account.                                                                                                                                  |
| `targetAccountOutcome`    | `provided_linkedin_handle`, `verified_linkedin_handle`, `unverified_or_conflicting_linkedin_candidates`, `unresolved` | The LinkedIn company-handle resolution outcome. Use `targetAccountSearchMode` to see whether people were matched through a company page, current profile company text, or no available path. |
| `providerOutcome`         | `hit`, `empty_clean`, `empty_partial_failure`                                                                         | Whether the selected provider returned usable rows, returned no rows, or completed with partial provider failure.                                                                            |
| `message`                 | string                                                                                                                | A short user-facing explanation for empty or unavailable paths.                                                                                                                              |

People returned from a target-account search can include `companyMatchEvidence`:

| Value                 | Meaning                                                                        |
| --------------------- | ------------------------------------------------------------------------------ |
| `company_page`        | The person matched via a LinkedIn company page constraint.                     |
| `profile_current_job` | The person matched via current profile company text for the requested account. |

The operation response does not expose raw company candidates, candidate scores, provider run IDs, actor inputs, model IDs, pricing rows, COGS, or detailed resolver diagnostics.
