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

# Ingest generic JSON events

> Push arbitrary JSON records (`StandardCustom` events) into the connector.
Each item's `data` field is stored verbatim. LLM enrichment does NOT run on
this path; use `/ingest/upload` for binaries that should be enriched.

<Snippet file="api/ingestion/ingest-custom.mdx" />


## OpenAPI

````yaml POST /v1/custom-connectors/{connector_id}/ingest
openapi: 3.1.0
info:
  title: Adapter API
  description: Connect and sync data from any SaaS tool.
  version: 0.1.0
servers:
  - url: https://api.adapter.com
security:
  - ApiKeyAuth: []
tags:
  - name: connections
    description: Manage OAuth connections to data sources.
paths:
  /v1/custom-connectors/{connector_id}/ingest:
    post:
      tags:
        - ingestion
      summary: Ingest generic JSON events
      description: >-
        Push arbitrary JSON records (`StandardCustom` events) into the
        connector.

        Each item's `data` field is stored verbatim. LLM enrichment does NOT run
        on

        this path; use `/ingest/upload` for binaries that should be enriched.
      operationId: ingest_custom
      parameters:
        - name: connector_id
          in: path
          required: true
          schema:
            type: string
            title: Connector Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IngestRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestResponse'
        '402':
          description: >-
            Ingest fully rejected — the workspace is over a tier quota
            (documents / storage / per-document size). Partial batches instead
            return 200 with a `rejected` list. Not transient; upgrade or free
            space rather than retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuotaExceededErrorModel'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    IngestRequest:
      properties:
        items:
          items:
            $ref: '#/components/schemas/IngestItem'
          type: array
          maxItems: 500
          minItems: 1
          title: Items
          description: >-
            Events to ingest, at most 500 per request. Chunk larger loads into
            multiple requests.
        force:
          type: boolean
          title: Force
          description: >-
            Re-process items even when their content is byte-identical to what
            was previously ingested for the same external_id. Without this,
            unchanged re-pushes are acknowledged but skipped (reported in
            `unchanged`).
          default: false
      type: object
      required:
        - items
      title: IngestRequest
    IngestResponse:
      properties:
        status:
          type: string
          title: Status
          description: Always 'accepted' (a fully-rejected ingest returns 402).
          examples:
            - accepted
        events:
          type: integer
          title: Events
          description: Number of events accepted.
          examples:
            - 1
        external_ids:
          items:
            type: string
          type: array
          title: External Ids
          description: external_id of each accepted event, in submission order.
          examples:
            - - c1f4…
        rejected:
          items:
            $ref: '#/components/schemas/RejectedItem'
          type: array
          title: Rejected
          description: >-
            Items refused at admission on a partial-accept (some over a tier
            quota). Empty on full accept; a fully-rejected ingest returns 402
            instead.
        unchanged:
          items:
            type: string
          type: array
          title: Unchanged
          description: >-
            external_id of each accepted item whose content was byte-identical
            to the previously ingested version and was therefore not
            re-processed. Pass force=true to override.
      type: object
      required:
        - status
        - events
      title: IngestResponse
    QuotaExceededErrorModel:
      properties:
        error_code:
          type: string
          const: quota_exceeded
          title: Error Code
          default: quota_exceeded
        message:
          type: string
          title: Message
          default: 'Ingest rejected: this workspace is over its plan quota.'
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Details
          description: >-
            Carries `rejected`: the refused items as `{external_id, resource,
            reason}` (resource ∈ documents/storage/doc_size).
      type: object
      title: QuotaExceededErrorModel
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    IngestItem:
      properties:
        external_id:
          anyOf:
            - type: string
            - type: 'null'
          title: External Id
        data:
          title: Data
        metadata:
          anyOf:
            - additionalProperties:
                type: string
              type: object
            - type: 'null'
          title: Metadata
          description: >-
            Per-item key/value metadata merged with the connector's metadata
            (item wins on key conflict). String values only. Lands on
            `event.metadata` and is visible to downstream subscribers and
            triggers.
          examples:
            - batch: '2026-06-01'
              env: staging
      type: object
      title: IngestItem
    RejectedItem:
      properties:
        external_id:
          type: string
          title: External Id
          description: external_id of the rejected item.
          examples:
            - ext-123
        resource:
          type: string
          title: Resource
          description: 'Which cap was hit: ''documents'', ''storage'', or ''doc_size''.'
          examples:
            - storage
        reason:
          type: string
          title: Reason
          description: Machine-readable rejection reason.
          default: quota_exceeded
          examples:
            - quota_exceeded
      type: object
      required:
        - external_id
        - resource
      title: RejectedItem
      description: >-
        An item refused at ingest admission because a tier quota was exceeded —
        appears

        in a partial-accept batch response (some items admitted, some over the
        cap). A

        *fully* rejected ingest instead returns 402 (see QuotaExceededError).
        Only

        populated when quota enforcement is on (monitor mode admits everything).
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: Pass your `pk_live_...` API key as a Bearer token.

````