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

# Add or retry a document

> Add a document using exactly one of `content` (raw text; `name` required) or `url` (file URL, max 20 MB). Alternatively, provide `document_id` alone to retry an existing document synchronously, without creating or renaming one. For a cloud drive document, retry downloads the current remote version of only that file, even when unchanged, charges normal sync credits, preserves the previous index on failure and never imports or deletes other files. The workspace must retain cloud drive sync access and no sync may already be running. Discovery is bounded to 500 files; a target beyond that listing limit returns 422. Other source types retry their retained file or website; a purged upload without a remote source cannot be retried. Creation returns 201 with the final document, including status `error` when ingestion fails. Retry returns 200 with processing counts; failures return a non-2xx error with a safe customer message. **Required scope:** `knowledge:write` and a workspace role allowed to write (unrestricted keys retain full scope access).



## OpenAPI

````yaml /api-reference/openapi.json post /knowledge-bases/{id}/documents
openapi: 3.1.0
info:
  title: Famulor API
  version: 1.0.0
  description: >-
    REST API for Famulor. Authenticate with an API key (`fam_...`, created under
    **Settings → API Keys**) or an OAuth 2.0 access token (`fam_at_...`) as a
    Bearer token.


    Every response uses a consistent envelope: `{ "data": ... , "meta": { ... }
    }` on success and `{ "error": { "code", "message" } }` on failure. List
    endpoints paginate with `?limit=` (default 50, max 200) and `?offset=`;
    `meta.pagination.total` carries the total match count.


    REST operations require API Access through the workspace plan or a recurring
    add-on. Without it, regular operations return `403 api_access_required`. The
    invoice-payment and billing-portal operations remain available with a valid
    `billing:write` credential after a failed plan payment so an authorized
    owner, admin, or billing member can recover billing.


    The same customer-facing capabilities are available as MCP tools at
    `https://app.famulor.io/mcp` (Model Context Protocol, streamable HTTP) using
    the same credentials, scopes, and workspace access. MCP availability is
    controlled separately by Connect AI / MCP, not by API Access.
servers:
  - url: https://app.famulor.io/api/v1
    description: Hosted platform.
  - url: https://{domain}/api/v1
    description: White-label tenant domain — same paths, tenant branding.
    variables:
      domain:
        default: app.famulor.io
        description: Your white-label tenant domain.
security:
  - bearerAuth: []
tags:
  - name: Account
    description: Self-inspection of the calling credential.
  - name: Migrations
    description: Preview and import data from supported legacy platforms.
  - name: Assistants
    description: Create and manage voice assistants.
  - name: Tools
    description: >-
      Reusable tools (HTTP APIs and external MCP servers) assistants can call
      mid-conversation.
  - name: Voices
    description: Browse the text-to-speech voice library.
  - name: Calls
    description: Start outbound calls and read call history, transcripts and recordings.
  - name: History
    description: Unified conversation history across calls, messaging and assistant emails.
  - name: Campaigns
    description: Outbound calling campaigns with a compliant power dialer.
  - name: Leads
    description: Manage Audience contacts across campaigns, channels and Call QA metrics.
  - name: Segments
    description: >-
      Saved, dynamic lead filters — reusable audience definitions used for
      Audience search and campaign lead assignment.
  - name: Suppression
    description: Cross-channel marketing opt-outs and active workspace suppression records.
  - name: Callbacks
    description: >-
      Scheduled callbacks booked by the Schedule callback tool across voice,
      chat, and email.
  - name: Phone Numbers
    description: Marketplace numbers and customer-provided numbers.
  - name: Famulor Loop
    description: >-
      Personal business-phone access, directory, presence, devices, and Loop
      call recents.
  - name: SIP Trunks
    description: Bring your own SIP provider and numbers.
  - name: Carrier Connections
    description: Connect a supported carrier account and import its existing phone numbers.
  - name: Knowledge Bases
    description: RAG knowledge bases and documents for assistants.
  - name: Settings
    description: Workspace-level settings such as caller-memory defaults.
  - name: Billing
    description: Balance and minutes ledger of the key owner.
  - name: Automations
    description: >-
      Native workspace automations — list, create, update, trigger. Plan gate:
      automation_platform.
  - name: Milian Missions
    description: Recurring jobs that Milian runs unattended on schedule.
  - name: Integrations
    description: >-
      Calendar integrations (Cal.com, Calendly, Acuity Scheduling, Google
      Calendar, Outlook, native booking engine). Assign them to assistants to
      provide availability and booking tools, plus provider-supported
      appointment lookup, cancellation, and rescheduling.
  - name: Bookings
    description: >-
      Native booking engine — event types with weekly availability, public
      booking pages at /book/{workspace}/{slug}, and the bookings they produce.
  - name: Dashboards
    description: >-
      Custom analytics dashboards, reusable widgets, and tenant-scoped
      performance analytics. Requires the custom_dashboards plan feature.
  - name: Catalog
    description: >-
      Read-only platform catalogs — available models, supported assistant
      languages, and prompt templates.
  - name: Simulations
    description: Assistant simulation tests (plan-gated).
  - name: Versions
    description: Assistant configuration version history.
  - name: Caller IDs
    description: Outbound caller ID verification.
  - name: Widgets
    description: Web widget connectors.
  - name: Messaging
    description: >-
      Telegram, Slack, and Messenger text bots linked to assistants (Chat SDK).
      Includes conversation delay, inactivity end, and conversation-ended
      webhooks.
  - name: QA
    description: Cohort AI Quality Assurance runs over call transcripts.
  - name: White Label
    description: >-
      Manage the customers of your white-label workspace on their behalf — list,
      register, mint access tokens, log in, log out, and transfer credits.
      Available to reseller workspaces with white-label access, and to platform
      admins (scoped to direct platform customers). Requires `platform:read` /
      `platform:write`.
  - name: API Keys
    description: >-
      Self-service API keys for the calling workspace or a same-brand workspace
      where the credential's user is owner/admin. A key can only mint further
      keys with a scope subset of its own.
  - name: Workspaces
    description: >-
      List visible workspaces, create an additional workspace for the key owner,
      and mint a dedicated credential for a selected owner/admin workspace.
  - name: SMS
    description: Outbound SMS from workspace phone numbers.
paths:
  /knowledge-bases/{id}/documents:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Knowledge base ID.
    post:
      tags:
        - Knowledge Bases
      summary: Add or retry a document
      description: >-
        Add a document using exactly one of `content` (raw text; `name`
        required) or `url` (file URL, max 20 MB). Alternatively, provide
        `document_id` alone to retry an existing document synchronously, without
        creating or renaming one. For a cloud drive document, retry downloads
        the current remote version of only that file, even when unchanged,
        charges normal sync credits, preserves the previous index on failure and
        never imports or deletes other files. The workspace must retain cloud
        drive sync access and no sync may already be running. Discovery is
        bounded to 500 files; a target beyond that listing limit returns 422.
        Other source types retry their retained file or website; a purged upload
        without a remote source cannot be retried. Creation returns 201 with the
        final document, including status `error` when ingestion fails. Retry
        returns 200 with processing counts; failures return a non-2xx error with
        a safe customer message. **Required scope:** `knowledge:write` and a
        workspace role allowed to write (unrestricted keys retain full scope
        access).
      operationId: addKnowledgeDocument
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/KnowledgeDocumentCreate'
            examples:
              text:
                summary: Raw text
                value:
                  name: FAQ
                  content: |-
                    Q: What are your opening hours?
                    A: Mon-Fri 9:00-18:00...
                  description: Answers to common questions
              url:
                summary: File URL
                value:
                  url: https://example.com/files/manual.pdf
              retry:
                summary: Retry an existing document
                value:
                  document_id: 44444444-4444-4444-8444-444444444444
      responses:
        '200':
          description: >-
            The existing document was processed successfully. No new document
            was created.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/KnowledgeDocumentProcessResult'
              example:
                data:
                  document_id: 44444444-4444-4444-8444-444444444444
                  chunk_count: 12
                  total_chunks: 12
                  truncated: false
        '201':
          description: The processed document.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/KnowledgeDocument'
              example:
                data:
                  id: kd1b2c3d-0000-4000-8000-000000000061
                  knowledge_base_id: kb1b2c3d-0000-4000-8000-000000000060
                  name: FAQ
                  description: Answers to common questions
                  source_type: text
                  source_url: null
                  status: ready
                  error_message: null
                  chunk_count: 12
                  mime_type: text/plain
                  size_bytes: 20480
                  created_at: '2026-07-01T12:00:00Z'
                  updated_at: '2026-07-01T12:00:30Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: An active plan or enough sync credits is required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >-
            The source is already syncing or the document changed during
            processing. Retry later.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '422':
          description: >-
            The file format, size or source folder listing prevents retry. Check
            the source and try again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: >-
            Document processing failed. The previous searchable index is
            preserved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '503':
          description: Document processing is temporarily unavailable. Retry later.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  schemas:
    KnowledgeDocumentCreate:
      type: object
      description: >-
        Create a document from exactly one of content or url, or retry an
        existing document by supplying document_id alone. All operations process
        synchronously. Creation returns a document (201); retry returns
        processing counts (200).
      properties:
        name:
          type: string
          description: >-
            Document name. Required for `content` sources; defaults to the file
            name for `url` sources.
        content:
          type: string
          description: Raw text content.
        url:
          type: string
          description: Public file URL to ingest.
        description:
          type:
            - string
            - 'null'
        document_id:
          type: string
          format: uuid
          description: Existing document to retry. Omit content, url, name and description.
      oneOf:
        - required:
            - content
            - name
          not:
            anyOf:
              - required:
                  - url
              - required:
                  - document_id
        - required:
            - url
          not:
            anyOf:
              - required:
                  - content
              - required:
                  - document_id
        - required:
            - document_id
          not:
            anyOf:
              - required:
                  - content
              - required:
                  - url
              - required:
                  - name
              - required:
                  - description
    KnowledgeDocumentProcessResult:
      type: object
      required:
        - document_id
        - chunk_count
        - total_chunks
        - truncated
      properties:
        document_id:
          type: string
          format: uuid
        chunk_count:
          type: integer
          minimum: 0
          description: Number of indexed chunks after this run.
        total_chunks:
          type: integer
          minimum: 0
          description: Number of chunks extracted from the source.
        truncated:
          type: boolean
          description: >-
            Whether text processing stopped at its per-run limit. Table rows are
            never partially indexed.
    KnowledgeDocument:
      type: object
      properties:
        id:
          type: string
          format: uuid
        knowledge_base_id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type:
            - string
            - 'null'
        source_type:
          type: string
          description: '`text` or `url`.'
        source_url:
          type:
            - string
            - 'null'
        status:
          type: string
          description: >-
            `ready` once chunking + embeddings finished, `error` if ingestion
            failed.
        error_message:
          type:
            - string
            - 'null'
        chunk_count:
          type: integer
        mime_type:
          type:
            - string
            - 'null'
        size_bytes:
          type:
            - integer
            - 'null'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - knowledge_base_id
        - name
        - source_type
        - status
        - chunk_count
        - created_at
        - updated_at
    ErrorEnvelope:
      type: object
      description: Error envelope returned by every /api/v1 endpoint on failure.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - forbidden
                - api_access_required
                - not_found
                - invalid_request
                - rate_limited
                - conflict
                - telephony_configuration_error
                - telephony_unavailable
                - destination_forbidden
                - internal_error
              description: Stable, machine-readable error code.
            message:
              type: string
              description: Human-readable description of the error.
  responses:
    BadRequest:
      description: Invalid request body or parameters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: invalid_request
              message: '"to_number" is required (E.164 format, e.g. +4930123456).'
    Unauthorized:
      description: Missing, invalid, expired or revoked API key / access token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: unauthorized
              message: Invalid API key.
    Forbidden:
      description: >-
        The credential lacks the required scope or role, or the workspace does
        not have the required capability.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            scopeDenied:
              summary: Required scope is missing
              value:
                error:
                  code: forbidden
                  message: >-
                    This API key is missing the required scope
                    "assistants:write".
            apiAccessRequired:
              summary: API Access is not available
              value:
                error:
                  code: api_access_required
                  message: >-
                    API Access is not available for this workspace. Review
                    Settings → Plan.
    NotFound:
      description: Resource not found (or it belongs to another workspace).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: not_found
              message: Assistant not found
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: >-
        API key (`fam_...`, created under **Settings → API Keys**) or an OAuth
        2.0 access token (`fam_at_...`). REST operations also require API Access
        for the credential's workspace. Keys can be restricted to scopes such as
        `assistants:read`, `calls:write`, `campaigns:write`, `automations:read`,
        `dashboards:read`, `dashboards:write`, `leads:write`, `segments:write`,
        `loop:read`, `loop:write`, `phone_numbers:write`, `sip_trunks:write`,
        `knowledge:write`, `voices:read`, `billing:read`, `billing:write`,
        `settings:write`, `platform:read`, `platform:write`; a `*:write` scope
        implies the matching `*:read`. Automation and dashboard endpoints also
        accept the legacy `calls:*` scope. Keys without scope restrictions have
        full access within the workspace's available capabilities.

````