---
title: "Preview Source"
method: POST
path: "/api/v1/sources/{source_id}/preview"
tags: ["Sources"]
---

# Preview Source

`POST /api/v1/sources/{source_id}/preview`

## Request

- Base URL: `http://localhost:3009`
- URL: `http://localhost:3009/api/v1/sources/{source_id}/preview`
- Auth: HTTP bearer

Preview the records that would be ingested for the given source payload, without persisting anything. Use this to validate filters / list selections before committing to Create.

Per-source body shapes and field semantics live in `/docs/source-detail/{source_id}.txt`. The route schema only enforces that the body is a JSON object; per-source validation runs inside the handler and surfaces as 400 with a specific message and, when multiple fields fail, an `errors[]` array of `{field, message}` entries.

Results are typically capped at 100 rows (source-specific — e.g. Slack returns up to 10). `metadata.total_results` is the count returned in this preview; it is omitted when the source cannot count the matches. When `metadata.capped` is true, more rows exist upstream but were omitted due to preview limits.

**Trimming the response.** Pass a top-level `limit` (positive integer) to cap how many rows come back — useful when you only need to eyeball the shape of a row rather than the whole sample. `limit` is a response-shaping knob applied by this endpoint: it does not reduce what the source fetches upstream, and it never changes `metadata.total_results`. When it drops rows, `metadata.capped` is true.

## Path parameters

- `source_id` string, required

## Request body

- SourcePreviewBody: Per-source preview body. Shape depends on `source_id` — see the provider README under `modules/sources/` (and optionally `/docs/source-detail/{source_id}.txt`). Validated at the handler level; the schema only enforces that the body is a JSON object. One key is source-agnostic: `limit` (optional, positive integer) caps how many rows come back. It is consumed by the preview endpoint and never reaches the source, so it works on every source type and does not reduce upstream fetching or change `metadata.total_results`.
  - `limit` integer: Optional cap on rows returned. Response-shaping only — the source still fetches its normal preview sample, `metadata.total_results` is unchanged, and `metadata.capped` becomes true when rows are dropped.

## Response `200`

Default Response

- object
  - `status` integer
  - `data` SourcePreviewResponse: Preview result envelope. `data` is capped per source (at most 100 rows — e.g. find_job_postings returns up to 25, Slack up to 10). `metadata.total_results` is the upstream count. Per-row keys depend on the source.
    - `data` object[], required: Preview rows. Each row's keys depend on the source's payload.
    - `metadata` object, required
      - `total_results` integer: Total matching records in this preview response. Omitted when the source cannot count them.
      - `capped` boolean: When true, more rows exist upstream but were omitted due to preview limits. Omitted when not applicable.

## Other responses

- `400`: Per-source validation failed (missing or invalid payload fields).
- `401`: Unauthorized — missing or invalid API key
- `403`: Forbidden. `code` says which permission refused: ROLE_FORBIDDEN (your role), INSUFFICIENT_SCOPE (the API key's scopes), WORKFLOW_FORBIDDEN (no access to the workflow), KEY_WORKFLOW_FORBIDDEN (the API key's workflow restriction).
- `404`: Unknown `source_id` — see the param description for supported slugs.
- `424`: The user is not connected to the integration this source depends on.
- `429`: Too Many Requests — rate limit exceeded. Check `Retry-After` header for seconds until the limit resets.

---

[API](https://skmtc.dev/floqer/apis/floqer-public-api.md) - [All operations](https://skmtc.dev/floqer/apis/floqer-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/floqer/apis/floqer-public-api/revisions/fce50dc07b20?raw)
