Skip to content

Document Connector

Upload, list, and manage document files through the Document Connector.

This page also covers ontology-aware upload fields (ontologyIds, ontologyMode, documentGroup) used to scope and tag data in the knowledge graph.

Base URL

BASE_URL = "https://api.fermi.dev/public/v1"

All endpoints are relative to this base URL.

Authentication

All endpoints require authentication. Use a service actor token:

Authorization: Bearer <service-actor-token>

Required Scopes:

  • connectors:read - For read endpoints
  • connectors:write - For write endpoints

Upload Documents

POST /connect/integrations/documents/upload

Upload one or more document files.

Headers:

Authorization: Bearer <token>
Content-Type: multipart/form-data

Form-Data Fields

Key Type Required Description
files file[] Yes One or more files to upload
description string No Friendly description for this upload
ontologyIds string[] or JSON string No Ontology IDs to apply (max 8). Example: ["legal_ontology_v1","finance_ontology_v1"]
ontologyMode string No strict or guided. If ontologyIds is provided and mode is omitted, defaults to strict
documentGroup string No Logical grouping label (lowercase letters, numbers, _, -) used for downstream filtering

!!! note "Payload meaning" - ontologyIds: selects which custom ontologies are active for this upload. - ontologyMode: - strict = hard filter (non-matching chunks/entities are removed before brain write) - guided = soft lens (all content is kept; matching content is annotated) - documentGroup: optional partition key to group related uploads, nodes, and chunks.

cURL Example (with ontologies)

curl --request POST \
  --url ${BASE_URL}/connect/integrations/documents/upload \
  --header 'authorization: Bearer <token>' \
  --header 'content-type: multipart/form-data' \
  --form 'description=Merger agreement upload' \
  --form 'ontologyIds=["legal_ontology_v1","finance_ontology_v1"]' \
  --form 'ontologyMode=strict' \
  --form 'documentGroup=corporate_deals' \
  --form files=@/path/to/TEST_DOCUMENT_MERGER_AGREEMENT.txt

Response

{
  "success": true,
  "connectionId": "61c54aa8-631d-477a-a73a-08707c4c4659",
  "connectionIds": ["61c54aa8-631d-477a-a73a-08707c4c4659"],
  "uploadedCount": 1,
  "totalDocuments": 1,
  "totalSize": 353047,
  "documents": [
    {
      "id": "2d33dcee-4f48-45a8-a175-54be3a284ec4",
      "fileName": "TEST_DOCUMENT_MERGER_AGREEMENT.txt",
      "fileSize": 353047,
      "mimeType": "text/plain",
      "s3Key": "...",
      "s3Path": "...",
      "uploadedAt": "2026-04-30T09:30:13.708Z"
    }
  ],
  "ontologyIds": ["legal_ontology_v1", "finance_ontology_v1"],
  "ontologyMode": "strict",
  "documentGroup": "corporate_deals"
}

connectionId is the first created connection. connectionIds lists every connection created for this upload (one per non-SOP file). Ontology and SOP fields are omitted unless you send those optional form fields.

Ontology-Aware Upload Behavior

What is filtered and tagged

After upload, the processing pipeline resolves ontology definitions and applies them in build_brain:

  • Entities: matched by entity_type / entity_subtype and/or ontology terms in text.
  • Chunks: matched by chunk text + section metadata + extracted entity strings.
  • Events / Workflows / Facts (full brain mode): matched by node text fields.

When matched, nodes can include:

  • category: first matched ontology display name
  • categories: all matched ontology display names
  • ontology_ids, ontology_mode, ontology_term_hits

Strict vs Guided mode

Mode Behavior
strict Non-matching chunks/entities are filtered out before writing to Neo4j and indexing
guided All chunks/entities are retained; only matching ones get ontology annotations

Multiple ontologies on one upload

If you provide multiple ontologyIds, each node is evaluated against each ontology:

  • node can match one, many, or none
  • categories stores all matches
  • category stores first match

Upload validation behavior

  • Unknown ontologyIds fail document processing early in intake with error_code=ontology_not_found
  • ontologyMode without ontologyIds returns 400
  • More than 8 ontology IDs returns 400

Get Documents for a Connection

GET /connect/integrations/documents/upload?connectionId={connectionId}

Return the documents stored on a documents connection.

Headers:

Authorization: Bearer <token>

Query Parameters:

Parameter Type Required Description
connectionId string Yes Documents connection ID

cURL Example:

curl --request GET \
  --url "${BASE_URL}/connect/integrations/documents/upload?connectionId=61c54aa8-631d-477a-a73a-08707c4c4659" \
  --header "Authorization: Bearer <token>"

Response:

{
  "connectionId": "61c54aa8-631d-477a-a73a-08707c4c4659",
  "documents": [
    {
      "id": "2d33dcee-4f48-45a8-a175-54be3a284ec4",
      "fileName": "background.jpeg",
      "fileSize": 77202,
      "mimeType": "image/jpeg",
      "s3Key": "...",
      "s3Path": "...",
      "uploadedAt": "2025-12-04T19:48:13.708Z"
    }
  ],
  "totalSize": 353047,
  "totalDocuments": 2,
  "lastUpdated": "2025-12-04T19:48:13.708Z"
}

List Uploaded Document Connections

GET /connect/integrations/connections?providerConfigKey=documents

List all document upload connections.

Headers:

Authorization: Bearer <token>

cURL Example:

curl --request GET \
  --url "${BASE_URL}/connect/integrations/connections?providerConfigKey=documents" \
  --header "Authorization: Bearer <token>"

Response:

{
  "connections": [
    {
      "id": 517,
      "connection_id": "5c096330-fc54-4144-bfec-6bd344da9586",
      "provider_config_key": "documents",
      "syncStatus": "completed",
      "metadata": {
        "documents": [
          {
            "id": "b4e99161-8135-4b9f-a14c-ef970ab0516a",
            "fileName": "Brochure - 4155 Fairview St_.pdf",
            "fileSize": 3731719
          }
        ],
        "totalDocuments": 1,
        "totalSize": 3731719
      }
    }
  ],
  "total": 1
}

Get Connection by Connection ID

GET /connect/integrations/connections/{connectionId}

Get details of a specific document connection.

Headers:

Authorization: Bearer <token>

cURL Example:

curl --request GET \
  --url "${BASE_URL}/connect/integrations/connections/61c54aa8-631d-477a-a73a-08707c4c4659" \
  --header "Authorization: Bearer <token>"

Response:

{
  "id": 551,
  "connection_id": "61c54aa8-631d-477a-a73a-08707c4c4659",
  "provider_config_key": "documents",
  "metadata": {
    "syncStatus": "failed",
    "totalDocuments": 2,
    "documents": [
      { "fileName": "background.jpeg", "mimeType": "image/jpeg" },
      { "fileName": "image.png", "mimeType": "image/png" }
    ]
  }
}

Delete Connection

DELETE /connect/integrations/connection/{connectionId}?providerConfigKey=documents

Delete a specific document connection. This DELETE currently returns 502 on the public path. Headers:

Authorization: Bearer <token>

Query Parameters:

Parameter Type Required Description
providerConfigKey string Yes Must be "documents"

cURL Example:

curl --request DELETE \
  --url "${BASE_URL}/connect/integrations/connection/6a0f618b-5bd5-4402-9451-10af666bd18a?providerConfigKey=documents" \
  --header "Authorization: Bearer <token>"

Response:

{
  "success": true
}

Error Responses:

Status Code Description
400 Missing required identity headers or parameters
404 Connection not found
500 Failed to delete connection or backend error

Example Error Response:

{
  "error": "Failed to delete resource from backend",
  "details": "Connection is currently being synced"
}

Endpoints Summary

Method Endpoint Description
POST /connect/integrations/documents/upload Upload files (supports ontology fields)
GET /connect/integrations/documents/upload?connectionId= Get documents for a connection
GET /connect/integrations/connections?providerConfigKey=documents List document uploads
GET /connect/integrations/connections/{connectionId} Get connection details
DELETE /connect/integrations/connection/{connectionId}?providerConfigKey=documents Delete connection

Next Steps