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

# Fetcher REST API

> Orient yourself in the Fetcher Manager API: bearer authentication, product scope, pagination, filtering, and the RFC 9457 error shape that all 12 operations share.

The **Manager** serves the Fetcher HTTP API. It carries 12 operations in two areas:

* **Extraction jobs** under `/v1/fetcher` — create a job, read a job.
* **Connections** under `/v1/management/connections` — the connection lifecycle, schema reads, connection tests, and the two product-assignment operations.

All 12 operations render under the **Fetcher** anchor in the [API Reference](/en/reference/introduction). This page covers what those operations share. It does not restate their request and response shapes.

<Note>
  The OpenAPI documents in this portal are render sources for the reference pages. They are not client contracts, and they are not a basis for SDK generation.
</Note>

## Authentication

***

Fetcher accepts a JWT bearer token:

```http theme={null}
Authorization: Bearer <token>
```

Authentication is a deployment choice. `PLUGIN_AUTH_ENABLED` turns the auth middleware on, and `PLUGIN_AUTH_ADDRESS` points it at the identity service. The Manager refuses to start when you enable auth and leave the address empty. Multi-tenant mode also requires effective authentication — the router refuses to build a tenant middleware without it. See [Configuration](/en/fetcher/fetcher-configuration).

Every one of the 12 operations declares `401` and `403`. Fetcher authorizes each request against the `fetcher` application, a resource (`connections` or `fetcher`), and an action that matches the HTTP method.

Five routes stay outside authentication so probes keep working: `/health`, `/readyz`, `/readyz/tenant/{id}`, `/metrics`, and `/version`.

## Product scope

***

Connection operations carry an `X-Product-Name` header. It names the product that owns the connection.

* **Create connection requires it.** Fetcher rejects a missing, empty, or whitespace-only value.
* **List connections treats it as optional.** With the header, you see one product's connections. Without it, you see every connection in scope.
* Fetcher lower-cases the value. It accepts letters, digits, underscores, and hyphens, up to 100 characters.

Extraction jobs do not use this header. A job names its owning product in `metadata.source`, which the create-job payload requires.

## Asynchronous jobs

***

`POST /v1/fetcher` answers `202 Accepted` and returns a job identifier with status `pending`. The Worker runs the extraction after the response.

Fetcher deduplicates job requests by a request hash over a **5-minute window**. A duplicate inside that window answers `200 OK` and returns the existing job instead of queueing a second one. A job that already failed does not suppress a retry — you can resubmit it.

To follow a job, poll `GET /v1/fetcher/{id}`, or subscribe to the terminal events described in [Job events](/en/fetcher/fetcher-job-events).

## Pagination

***

Both list operations — connections and unassigned connections — use offset pagination with the same query parameters.

| Parameter   | Default | Rules                                                                                      |
| ----------- | ------- | ------------------------------------------------------------------------------------------ |
| `page`      | `1`     | Page number. Must be 1 or greater.                                                         |
| `limit`     | `10`    | Items per page. Must be 1 or greater, and at most `MAX_PAGINATION_LIMIT` (100 as shipped). |
| `sortOrder` | `desc`  | `asc` or `desc`. Fetcher always sorts by creation date.                                    |
| `startDate` | —       | Inclusive lower bound on creation date, as `YYYY-MM-DD`.                                   |
| `endDate`   | —       | Inclusive upper bound on creation date, as `YYYY-MM-DD`.                                   |

A page response carries `items`, `page`, `limit`, and `total`.

```json theme={null}
{
  "items": [],
  "page": 1,
  "limit": 10,
  "total": 42
}
```

<Warning>
  A list request always applies a creation-date window. Send neither `startDate` nor `endDate`, and Fetcher applies the last month up to tomorrow. Older connections fall outside that window. Set both dates when you want a wider view.

  `MAX_PAGINATION_MONTH_DATE_RANGE` caps the width of that window at one month as shipped. Ask for a wider range and Fetcher moves `startDate` forward to fit the cap. It does not answer with an error.
</Warning>

Internal datasources — the ones an operator configures through `DATASOURCE_{NAME}_*` environment variables — appear only on page 1, ahead of the stored connections, and count toward `total`.

## Filtering

***

The connection list accepts two filters beyond the date window.

* **`type`** — one of `POSTGRESQL`, `MYSQL`, `ORACLE`, `SQL_SERVER`, or `MONGODB`. Fetcher upper-cases the value.
* **`metadata.<key>=<value>`** — an exact match on a metadata entry you stored with the connection. For example, `metadata.region=br`.

The unassigned list narrows by the date window alone. It answers one question — which connections still carry no product — so it takes no type or metadata filter.

Fetcher ignores an unknown query parameter rather than failing the request. Three cases still fail with `FET-0405`:

* A key that starts with `$`, which blocks query-operator injection.
* A key that starts with `_`, which blocks internal fields.
* A key longer than 64 characters, or a value longer than 256 characters.

## Errors

***

Every error answers `application/problem+json` and follows [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457).

```json theme={null}
{
  "type": "about:blank",
  "title": "Invalid payload",
  "status": 400,
  "detail": "empty request body",
  "code": "FET-0001",
  "errors": [
    { "location": "body.configName", "message": "is required" }
  ]
}
```

| Field      | What it carries                                                                             |
| ---------- | ------------------------------------------------------------------------------------------- |
| `type`     | URI reference to documentation for the problem. Defaults to `about:blank`.                  |
| `title`    | Short summary of the problem type. Stable across occurrences.                               |
| `status`   | The HTTP status code.                                                                       |
| `detail`   | Explanation specific to this occurrence.                                                    |
| `instance` | URI reference for this specific occurrence.                                                 |
| `code`     | Stable domain error code in the form `FET-NNNN`.                                            |
| `errors`   | Optional per-field details, each with a `location`, a `message`, and the offending `value`. |

Match on `code`, not on `title` or `detail`. The codes group by range:

| Range      | Meaning           | Examples                                                                                                                       |
| ---------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `FET-000x` | General outcomes  | `FET-0001` bad request, `FET-0002` internal error, `FET-0004` conflict, `FET-0005` not found                                   |
| `FET-04xx` | Request problems  | `FET-0403` invalid header, `FET-0405` invalid query parameter, `FET-0406` pagination limit exceeded, `FET-0414` forbidden host |
| `FET-10xx` | Business rules    | `FET-1002` entity conflict, `FET-1021` job in progress, `FET-1040` connection down                                             |
| `FET-106x` | Schema validation | `FET-1060` validation failed, `FET-1062` object not found                                                                      |

Fetcher redacts driver-level failures at its boundary. It discards the raw database error, so a connection string, a credential, or a driver internal never reaches a caller.

## Reading the spec from a running Manager

***

`SWAGGER_ENABLED=true` mounts a Scalar reference at `/swagger/docs` and the OpenAPI 3.1 document at `/swagger/openapi.json` and `/swagger/openapi.yaml`. Keep it off in production.

## Next steps

***

<CardGroup cols={2}>
  <Card title="API Reference" icon="code" href="/en/reference/introduction">
    The 12 operations, with full request and response shapes.
  </Card>

  <Card title="Job events" icon="bell" href="/en/fetcher/fetcher-job-events">
    React to `job.completed` and `job.failed` instead of polling.
  </Card>

  <Card title="Core concepts" icon="book" href="/en/fetcher/fetcher-core-concepts">
    Connections, schema discovery, extraction jobs, filters, and results.
  </Card>

  <Card title="Configuration" icon="gear" href="/en/fetcher/fetcher-configuration">
    The environment variables behind auth, pagination caps, and the API surface.
  </Card>
</CardGroup>
