---
title: "Run an ingest"
method: POST
path: "/v2/workspaces/{id}/connectors/{cid}/ingest"
tags: ["Connectors"]
---

# Run an ingest

`POST /v2/workspaces/{id}/connectors/{cid}/ingest`

## Request

- Base URL: `https://api.infolang.ai`
- URL: `https://api.infolang.ai/v2/workspaces/{id}/connectors/{cid}/ingest`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer
  - HTTP bearer

Pulls documents in scope and writes them into the connection's target namespace. SYNCHRONOUS and BOUNDED: one call ingests at most 20 documents. When the scope holds more, the response carries `next_cursor` and `done: false` — call again with `?cursor=<next_cursor>` until `done` is true.

Per-document failures (a PDF, an oversized file, a permission error) are reported in `documents_skipped` and do NOT fail the run. A failed WRITE does: `status` becomes `error` and `error` is set.

Requires BOTH `connectors:write` and `ingest:write` — it uses a stored third-party credential AND writes memories. Chunks are written through the same `/v1/execute` batching path as file ingest, so they are metered identically.

Requires the `connectors:write` scope. Accepts all three lanes: a session JWT (bounded by the caller's role on this workspace) or an `il_*` machine credential whose own scope set, workspace set and validity window cover it — both ceilings apply and neither can raise the other, so a credential carrying `connectors:write` is still refused where the role does not permit it.

A credential with no scope record resolves to `LEGACY_DEFAULT`, which does NOT include `connectors:write` — mint a key with it explicitly (`POST /v2/workspaces/{id}/keys`).

## Path parameters

- `id` string, required
- `cid` string, required

## Query parameters

- `cursor` string

## Response `200`

What this run ingested, and whether the scope is exhausted

- object
  - `connection_id` string, required
  - `namespace` string, required
  - `status` string, required
  - `documents_total` number, required
  - `documents_ingested` number, required
  - `documents_skipped` object[], required
    - `name` string, required
    - `reason` string, required
  - `chunks_written` number, required
  - `tokens_ingested` number, required
  - `synced_count` number, required
  - `last_sync_at` string, required
  - `next_cursor` string
  - `done` boolean, required
  - `error` string

## Other responses

- `401`: Missing/invalid credential, or `credential_expired` — the credential is outside its `[not_before, expires_at)` window and must be replaced
- `403`: `insufficient_scope` — the credential's own scope set, or the caller's role on this workspace, does not cover the scope this route requires (the missing scope is named in the message). Or `forbidden` — the credential is not scoped to this workspace, or holds no grant on it
- `404`: No such connector in this workspace
- `409`: `connector_not_active` (not authorized yet), `connector_scope_unset` (no source scope), `connector_not_authorized`, `connector_credential_unreadable`, or `provider_not_configured`
- `502`: The provider refused, or a memory write failed upstream

---

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