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

# Overview

> Use an SDK or call Filament's API directly, with authentication, tenancy, and pagination

Filament's API is [ConnectRPC](https://connectrpc.com), generated from the
protobuf definitions in `protos/ingestion/v1/`, `protos/metrics/v1/`, and
`protos/auth/v1/`.
`ingestion.v1.IngestionService` (connectors, connections, pipelines, runs) and
`metrics.v1.MetricsService` (dashboard aggregations) share one listener with
`auth.v1.AuthService` (authentication and team management). The built-in web
app and the SDKs use this same API.

Every RPC has a Connect HTTP POST route at `/{package.Service}/{Method}`:

```
POST /ingestion.v1.IngestionService/CreatePipeline
POST /metrics.v1.MetricsService/QueryTimeseries
```

The `server` binary serves these services on `SERVER_ADDR` (default `:8080`).
The `standalone` binary and the embeddable `app.Run` library serve the same API
on `INGESTION_ADDR` (default `:8080`).

## Protocols

The servers listen for HTTP/1.1 in plaintext. That determines which of the
three ConnectRPC wire protocols work against a default deployment.

| Protocol | Works out of the box |
| - | - |
| Connect (JSON or binary) | Yes (plain HTTP/1.1 POST) |
| gRPC-Web | Yes (HTTP/1.1) |
| gRPC | No (needs HTTP/2) |

Plain gRPC needs HTTP/2 end to end. The shipped binaries listen plaintext
without h2c, so a stock gRPC client fails against them directly. Serving
native gRPC requires enabling HTTP/2 on the backend listener as well as on
any proxy in front of it. TLS termination at a proxy alone does not enable
HTTP/2 on the backend. Connect and gRPC-Web clients need nothing extra.

The Connect protocol is ordinary JSON over POST, so any HTTP client works:

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
curl -X POST http://localhost:8080/ingestion.v1.IngestionService/ListConnectors \
  -H "Content-Type: application/json" \
  -H "Connect-Protocol-Version: 1" \
  -d '{"kind": "CONNECTOR_KIND_SOURCE"}'
```

For authenticated deployments, also send `Authorization: Bearer <token>`.

## OpenAPI

Run `buf generate` (or `just proto`) from the repository root to regenerate
the Go bindings and `api/openapi.json`. The pinned
[protoc-gen-connect-openapi](https://github.com/sudorandom/protoc-gen-connect-openapi)
plugin in `buf.gen.yaml` exports OpenAPI 3.1 for the existing unary Connect
JSON endpoints. Buf runs this plugin remotely; generation requires network
access to the Buf Schema Registry.

The specification describes request and response types, Connect headers,
and error responses. Fern uses it to generate the SDKs, with method
names and authentication metadata configured in `fern/`. The SDK calls the
existing Connect JSON endpoints directly.

Run `just sdks` from the repository root to regenerate the OpenAPI
specification and configured SDKs. This requires Buf and Fern login.
Use `just proto-check` to check generated API files against their committed
versions.

## SDKs

Generated clients wrap this API for [Python](/pages/guides/sdks/python) and
[TypeScript](/pages/guides/sdks/typescript). Both cover the unary methods;
streaming `TailRun` requires a client with Connect streaming support and is
not included.

## Authentication

When an identity provider is configured, the API accepts its bearer tokens
or Filament's session cookie. Only the auth configuration, login, token
minting, logout, registration, and invitation acceptance procedures are
public.

Without an identity provider, the API is unauthenticated. Keep such
deployments private or protect them at the network layer.

## Tenancy

Authenticated requests use the tenant resolved from the caller's identity.
With authentication disabled, every request uses the server's configured
default tenant. Request bodies and query parameters do not select a tenant.

## Errors

Failures are standard [Connect error codes](https://connectrpc.com/docs/protocol#error-codes).
These are the codes you will actually see.

| Code | When |
| - | - |
| `invalid_argument` | Malformed request |
| `unauthenticated` | Missing, invalid, or expired credentials when authentication is enabled |
| `permission_denied` | The caller lacks the required role |
| `not_found` | No row for the id, or an unknown connector name on `GetConnector` |
| `failed_precondition` | The operation is valid but the state refuses it |
| `aborted` | Optimistic-lock conflict on `version` |
| `already_exists` | `CreatePipelineSchedule` on a pipeline that already has one |
| `unimplemented` | The RPC or feature is unavailable in this deployment |

Some specifics worth knowing:

* `invalid_argument` covers missing required fields, an invalid graph on
  `CreatePipelineVersion`, a bad cron expression, and an undecodable
  pagination cursor.
* `failed_precondition` covers deleting a connection a pipeline still
  references, updating a deleted connection, a secret that fails to resolve,
  and `TailRun` without an event bus.
* `aborted` means the `version` on an update no longer matches the stored
  row. Re-read and retry.
* `unimplemented` covers `MetricsService` without a metrics store and
  discovery or column RPCs on connectors that don't support them.

Validation of connector configs is the exception. `ValidateConfig` and
`ValidatePipeline` return validation problems in their response bodies rather
than as RPC errors, so a form can display every failure together.

## Pagination

List RPCs take an optional `PaginationRequest`.

| Field | Behavior |
| - | - |
| `page_size` | Default 25 when unset. Values above 1000 are clamped to 1000 |
| `cursor` | Opaque token from a previous response. Do not construct one |

The response's `PaginationResponse` carries `total` plus `previous_cursor` and
`next_cursor` when more pages exist in that direction. Omitting `pagination`
entirely returns every row, which is convenient for scripts but expensive on
large tables.

## Health

Three plain HTTP endpoints sit beside the RPC routes on the same listener:

* `GET /livez`: always 200 while the process is up
* `GET /startupz`: 200 once dependencies are connected and modules are mounted
* `GET /readyz`: 200 after startup while Postgres and NATS/JetStream answer; the
  server also ensures the default tenant exists

The control plane serves the same endpoints on `HEALTH_ADDR` (default `:8081`).

## API areas

<CardGroup cols={2}>
  <Card title="Connectors" href="/pages/api-reference/service/connectors">
    The catalog of registered sources and sinks, with config validation and resource discovery.
  </Card>

  <Card title="Connections" href="/pages/api-reference/service/connections">
    Reusable, tenant-scoped sources and sinks with managed secrets.
  </Card>

  <Card title="Pipelines" href="/pages/api-reference/service/pipelines">
    Mutable metadata over immutable graph versions, plus schedules.
  </Card>

  <Card title="Runs" href="/pages/api-reference/service/runs">
    Compiling, listing, and live-tailing pipeline executions.
  </Card>

  <Card title="Metrics" href="/pages/api-reference/service/metrics">
    The read-only aggregation service behind the dashboard.
  </Card>
</CardGroup>


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