inite-ai Indexer work API

The external-indexer protocol (scope `indexer:write`): poll → claim → read content → submit candidates / fail. See docs/indexer-protocol.md.

Operations 6

POST /v1/documents/{id}/candidates Stage an external indexer's candidate batch #
GET /v1/indexer/work Poll for pending external work items #
POST /v1/indexer/work/{runId}/claim Claim a pending work item #
GET /v1/indexer/work/{runId}/content Read the claimed document's stored content #
POST /v1/indexer/work/{runId}/fail Release or permanently fail a claim #
POST /v1/indexer/work/{runId}/heartbeat Renew a claim lease #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/inite-ai:inite-ai-indexer-work-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

inite-ai-indexer-work-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  description: 'Generated from the zod wire contracts (`pnpm openapi:build` — scripts/build-openapi.ts); do not edit by hand. Excluded on purpose: the operator/ops surface (jobs, leases, policy, stats, maintenance, GDPR cascades), which is indexed in docs/api.md, and the MCP transport `ALL /mcp/{companyId}`, which is JSON-RPC over Streamable HTTP rather than REST — MCP clients discover it through `tools/list` (docs/mcp.md). Scopes are plain bearer-key grants, not OAuth flows — each operation states its required scope.'
  license:
    identifier: AGPL-3.0-or-later
    name: AGPL-3.0-or-later
  summary: 'The community-facing platform surface: the memory core (fact ingest, search, multi-hop, synthesize, entity and fact reads), the Domain Pack registry and tenant pack admin, the document pipeline, the external-indexer work protocol, the raw-substrate driver, the evidence substrate, and source reputation reads.'
  title: INITE Brain — Platform Indexer work API
  version: 2.6.0
servers:
- description: Hosted instance (placeholder — self-hosted deployments serve the same paths on their own origin).
  url: https://brain.inite.ai
security:
- bearerAuth: []
tags:
- description: 'The external-indexer protocol (scope `indexer:write`): poll → claim → read content → submit candidates / fail. See docs/indexer-protocol.md.'
  name: Indexer work
paths:
  /v1/documents/{id}/candidates:
    post:
      description: 'A remote indexer that read a stored document submits its reading here. With `runId` + `claimToken` the submission fulfils a claimed work item; without them it opens its own run (claimless flow). Candidates are grounded against the stored text; the Brain commits once every run for the document is settled. Max 200 items per kind. Throttled to 10 requests/min per credential. Part of the document pipeline — answers `503 feature_disabled` until `DOCUMENT_INGEST_ENABLED=1`. Source: src/documents/external-candidates.controller.ts.


        Required scope: `indexer:write`.'
      operationId: submitDocumentCandidates
      parameters:
      - description: The document id.
        in: path
        name: id
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmitCandidatesRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmitCandidatesResponse'
          description: Staged (and possibly committed).
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/FeatureDisabled'
      summary: Stage an external indexer's candidate batch
      tags:
      - Indexer work
  /v1/indexer/work:
    get:
      description: 'Pending indexer runs routed to this tenant’s installed external packs. Protocol: docs/indexer-protocol.md. Part of the document pipeline — answers `503 feature_disabled` until `DOCUMENT_INGEST_ENABLED=1`. Source: src/documents/indexer-work.controller.ts.


        Required scope: `indexer:write`.'
      operationId: listIndexerWork
      parameters:
      - description: Only work for this external pack.
        in: query
        name: packId
        required: false
        schema:
          type: string
      - description: Max items to return.
        in: query
        name: limit
        required: false
        schema:
          type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IndexerWorkListResponse'
          description: Claimable work items.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '503':
          $ref: '#/components/responses/FeatureDisabled'
      summary: Poll for pending external work items
      tags:
      - Indexer work
  /v1/indexer/work/{runId}/claim:
    post:
      description: 'Atomically transitions the run to claimed and returns the claimToken that fences all subsequent calls. Heartbeat within leaseSeconds or the claim is reaped as abandoned. Part of the document pipeline — answers `503 feature_disabled` until `DOCUMENT_INGEST_ENABLED=1`.


        Required scope: `indexer:write`.'
      operationId: claimIndexerWork
      parameters:
      - description: The work item (indexer run) id.
        in: path
        name: runId
        required: true
        schema:
          type: string
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClaimWorkResponse'
          description: The claim.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '503':
          $ref: '#/components/responses/FeatureDisabled'
      summary: Claim a pending work item
      tags:
      - Indexer work
  /v1/indexer/work/{runId}/content:
    get:
      description: 'Serves the verbatim stored chunks of the claimed document — only for documents whose ingest routed to this tenant’s installed external packs. Part of the document pipeline — answers `503 feature_disabled` until `DOCUMENT_INGEST_ENABLED=1`.


        Required scope: `indexer:write`.'
      operationId: getIndexerWorkContent
      parameters:
      - description: The claimed work item id.
        in: path
        name: runId
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkContentResponse'
          description: The document content.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '503':
          $ref: '#/components/responses/FeatureDisabled'
      summary: Read the claimed document's stored content
      tags:
      - Indexer work
  /v1/indexer/work/{runId}/fail:
    post:
      description: 'Default RELEASES the item back to ''pending'' (transient trouble, shutdown mid-work); `permanent: true` marks the run ''failed'' — no longer offered. Part of the document pipeline — answers `503 feature_disabled` until `DOCUMENT_INGEST_ENABLED=1`.


        Required scope: `indexer:write`.'
      operationId: failIndexerWork
      parameters:
      - description: The claimed work item id.
        in: path
        name: runId
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FailWorkRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FailWorkResponse'
          description: The outcome.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '503':
          $ref: '#/components/responses/FeatureDisabled'
      summary: Release or permanently fail a claim
      tags:
      - Indexer work
  /v1/indexer/work/{runId}/heartbeat:
    post:
      description: 'Extends the lease of a claimed work item. Part of the document pipeline — answers `503 feature_disabled` until `DOCUMENT_INGEST_ENABLED=1`.


        Required scope: `indexer:write`.'
      operationId: heartbeatIndexerWork
      parameters:
      - description: The claimed work item id.
        in: path
        name: runId
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HeartbeatWorkRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HeartbeatWorkResponse'
          description: The renewed lease.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '503':
          $ref: '#/components/responses/FeatureDisabled'
      summary: Renew a claim lease
      tags:
      - Indexer work
components:
  schemas:
    SubmittedFact:
      additionalProperties: false
      properties:
        clause:
          type: string
        confidence:
          type: number
        endTime:
          description: YYYY-MM-DD the value stopped holding; absent = still holds.
          type: string
        entityIndex:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        eventTime:
          description: YYYY-MM-DD the value began to hold; absent = from when the document says it.
          type: string
        object:
          type: string
        predicate:
          description: Must be namespaced `<indexerId>__*` or a core predicate.
          type: string
      required:
      - entityIndex
      - predicate
      - object
      type: object
    ClaimWorkResponse:
      additionalProperties: false
      properties:
        claimToken:
          type: string
        documentId:
          type: string
        leaseSeconds:
          exclusiveMinimum: 0
          maximum: 9007199254740991
          type: integer
        packId:
          type: string
        packVersion:
          type: string
        runId:
          type: string
      required:
      - runId
      - documentId
      - packId
      - packVersion
      - claimToken
      - leaseSeconds
      type: object
    WorkContentResponse:
      additionalProperties: false
      properties:
        chunkCount:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        chunks:
          items:
            $ref: '#/components/schemas/WorkContentChunk'
          type: array
        documentId:
          type: string
        kind:
          type: string
        occurredAt:
          type: string
        vertical:
          type: string
      required:
      - documentId
      - kind
      - vertical
      - occurredAt
      - chunkCount
      - chunks
      type: object
    GroundingDrop:
      additionalProperties: false
      properties:
        detail:
          type: string
        index:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        kind:
          enum:
          - entity
          - fact
          - relation
          type: string
        reason:
          enum:
          - ungrounded_entity
          - ungrounded_value
          - orphan_reference
          type: string
      required:
      - kind
      - index
      - reason
      - detail
      type: object
    CommitCounts:
      additionalProperties: false
      properties:
        committed:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        merged:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        pending:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        rejected:
          maximum: 9007199254740991
          minimum: 0
          type: integer
      required:
      - pending
      - committed
      - merged
      - rejected
      type: object
    IndexerWorkListResponse:
      additionalProperties: false
      properties:
        work:
          items:
            $ref: '#/components/schemas/IndexerWorkItem'
          type: array
      required:
      - work
      type: object
    HeartbeatWorkRequest:
      additionalProperties: false
      properties:
        claimToken:
          maxLength: 64
          type: string
      required:
      - claimToken
      type: object
    SubmittedRelation:
      additionalProperties: false
      properties:
        confidence:
          type: number
        endTime:
          description: YYYY-MM-DD the relation stopped holding; absent = still holds.
          type: string
        eventTime:
          description: YYYY-MM-DD the relation began to hold; absent = from when the document says it.
          type: string
        fromEntityIndex:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        kind:
          type: string
        toEntityIndex:
          maximum: 9007199254740991
          minimum: 0
          type: integer
      required:
      - fromEntityIndex
      - toEntityIndex
      - kind
      type: object
    ErrorResponse:
      description: Standard NestJS error envelope.
      properties:
        error:
          type: string
        message:
          anyOf:
          - type: string
          - items:
              type: string
            type: array
        statusCode:
          type: integer
      required:
      - statusCode
      - message
      type: object
    HeartbeatWorkResponse:
      additionalProperties: false
      properties:
        leaseSeconds:
          exclusiveMinimum: 0
          maximum: 9007199254740991
          type: integer
        runId:
          type: string
      required:
      - runId
      - leaseSeconds
      type: object
    WorkContentChunk:
      additionalProperties: false
      properties:
        seq:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        text:
          type: string
      required:
      - seq
      - text
      type: object
    FailWorkRequest:
      additionalProperties: false
      properties:
        claimToken:
          maxLength: 64
          type: string
        error:
          description: Optional diagnostic recorded on the run row (truncated server-side).
          maxLength: 2000
          type: string
        permanent:
          description: Default (false/absent) RELEASES the item back to 'pending'; true marks the run 'failed' — no longer offered, still claimable by runId.
          type: boolean
      required:
      - claimToken
      type: object
    IndexerWorkItem:
      additionalProperties: false
      properties:
        createdAt:
          type: string
        docHasContent:
          type: boolean
        documentId:
          type: string
        packId:
          type: string
        packVersion:
          type: string
        runId:
          type: string
      required:
      - runId
      - documentId
      - packId
      - packVersion
      - createdAt
      - docHasContent
      type: object
    SubmittedEntity:
      additionalProperties: false
      properties:
        canonical:
          type: string
        externalId:
          description: 'The system-of-record''s own id for the entity (a CRM contact id): the authoritative identity — same id ⇒ same entity whatever the name; never merged by name alone.'
          maxLength: 256
          type: string
        name:
          type: string
        type:
          type: string
      required:
      - name
      type: object
    FailWorkResponse:
      additionalProperties: false
      properties:
        runId:
          type: string
        status:
          enum:
          - released
          - failed
          type: string
      required:
      - runId
      - status
      type: object
    SubmitCandidatesRequest:
      additionalProperties: false
      properties:
        claimToken:
          maxLength: 64
          type: string
        entities:
          items:
            $ref: '#/components/schemas/SubmittedEntity'
          type: array
        facts:
          items:
            $ref: '#/components/schemas/SubmittedFact'
          type: array
        indexerId:
          description: The pack id this indexer is registered as (mode 'external').
          maxLength: 64
          type: string
        packVersion:
          description: Optional claim of the pack version; must match the installed one.
          maxLength: 32
          type: string
        relations:
          items:
            $ref: '#/components/schemas/SubmittedRelation'
          type: array
        runId:
          description: A claimed work item this submission fulfils. Provided together with claimToken or not at all (claimless flow opens its own run).
          maxLength: 128
          type: string
        scenes:
          description: Pack-schema-conforming scene hypotheses (0110). Rejected 400 unless PACK_MEMORY_PROJECTIONS_ENABLED; schemaId must be one of the submitting pack's declared memoryModel.sceneSchemas ids.
          items:
            additionalProperties: false
            properties:
              confidence:
                type: number
              gist:
                description: Scene gist text (≤2000 chars).
                type: string
              label:
                description: Short human label (≤200 chars).
                type: string
              occurredFrom:
                description: ISO datetime; provided together with occurredTo, from ≤ to.
                type: string
              occurredTo:
                type: string
              schemaId:
                description: ∈ the pack's memoryModel.sceneSchemas[].id.
                type: string
            required:
            - schemaId
            - label
            - gist
            type: object
          type: array
        sourceVersion:
          additionalProperties: false
          description: The revision of the external system of record these claims were read at. Rejected 400 unless PACK_SOURCE_VERSION_STALENESS. Rides into every committed fact's source.sourceVersion, and sweeps the pack's DERIVABLE facts (memoryModel.verificationRules with requires=source_version_match) that were read at an older revision, marking them stale for re-verification.
          properties:
            readAt:
              description: ISO 8601 datetime the derivation read that revision.
              type: string
            ref:
              description: The line within that system — a branch/ref, a matter id, a study series.
              maxLength: 200
              type: string
            system:
              description: 'System of record the claims were read from: ''git'', ''dms'', ''ehr'', ''ledger'', …'
              maxLength: 32
              type: string
            version:
              description: The exact revision read — a commit sha, a document revision id.
              maxLength: 200
              type: string
          required:
          - system
          - ref
          - version
          - readAt
          type: object
        stateDeltas:
          description: Lifecycle-transition claims (0110) riding scenes of this submission (sceneIndex). Validated against the pack's memoryModel.stateModels; declared transitions stay advisory (never a gate).
          items:
            additionalProperties: false
            properties:
              confidence:
                type: number
              from:
                description: Declared state of the model, when known.
                type: string
              sceneIndex:
                description: Index into this submission's `scenes` array.
                maximum: 9007199254740991
                minimum: 0
                type: integer
              stateModelId:
                description: ∈ the pack's memoryModel.stateModels[].id.
                type: string
              subject:
                description: The subject whose lifecycle moved (≤256 chars).
                type: string
              to:
                description: Declared state of the model.
                type: string
            required:
            - sceneIndex
            - stateModelId
            - subject
            - to
            type: object
          type: array
      required:
      - indexerId
      - entities
      - facts
      type: object
    FeatureDisabledResponse:
      description: Answered by every document-pipeline route while DOCUMENT_INGEST_ENABLED is off.
      properties:
        error:
          const: feature_disabled
          type: string
        message:
          type: string
      required:
      - error
      - message
      type: object
    SubmitCandidatesResponse:
      additionalProperties: false
      properties:
        commit:
          anyOf:
          - additionalProperties: false
            properties:
              committed:
                type: boolean
              counts:
                $ref: '#/components/schemas/CommitCounts'
              deferred:
                type: boolean
            required:
            - deferred
            - committed
            - counts
            type: object
          - type: 'null'
          description: null when the document vanished between staging and commit.
        dropped:
          items:
            $ref: '#/components/schemas/GroundingDrop'
          type: array
        packId:
          type: string
        packVersion:
          type: string
        runId:
          type: string
        staged:
          additionalProperties: false
          properties:
            entities:
              maximum: 9007199254740991
              minimum: 0
              type: integer
            facts:
              maximum: 9007199254740991
              minimum: 0
              type: integer
            relations:
              maximum: 9007199254740991
              minimum: 0
              type: integer
            scenes:
              maximum: 9007199254740991
              minimum: 0
              type: integer
            stateDeltas:
              maximum: 9007199254740991
              minimum: 0
              type: integer
          required:
          - entities
          - facts
          - relations
          type: object
        ungrounded:
          description: true when the document has no stored content — spans unverifiable.
          type: boolean
      required:
      - runId
      - packId
      - packVersion
      - staged
      - dropped
      - ungrounded
      - commit
      type: object
  responses:
    TooManyRequests:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Per-credential throttle exceeded.
    NotFound:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: No such resource in this tenant.
    BadRequest:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Validation failed.
    Unauthorized:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Missing or unknown bearer key.
    FeatureDisabled:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/FeatureDisabledResponse'
      description: The document pipeline is dark (DOCUMENT_INGEST_ENABLED off).
    Conflict:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: State conflict — e.g. a lost/mismatched claim token, an already claimed work item, or an immutable-version republish.
    Forbidden:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: The key lacks the required scope.
  securitySchemes:
    bearerAuth:
      description: 'API key (`Authorization: Bearer <key>`); its SHA-256 must be registered in BRAIN_API_KEYS. Keys carry scopes (`brain:read`, `brain:write`, `brain:admin`, `brain:read_pii`, `registry:publish`, `registry:curate`, `indexer:write`) — each operation states the scope it requires. Not an OAuth flow.'
      scheme: bearer
      type: http