DocuHelix

API Reference

DocuHelix API

Base URL: https://api.docuhelix.com

POST/api/v1/auth/token

Exchange credentials for an access token

Authenticate with your API client credentials to obtain a short-lived JWT access token. The token is valid for 30 minutes.

Headers

HeaderRequiredValue
Content-TypeYesapplication/json
X-Tenant-IDYesYour organization UID

Request body

FieldTypeRequiredDescription
client_idstringYesAPI client identifier issued by your DocuHelix admin
client_secretstringYesAPI client secret

Request example

bash
curl -X POST https://api.docuhelix.com/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD" \
  -d '{
    "client_id": "01J9ABC123DEF456GHI789JKLM",
    "client_secret": "sk_live_a1b2c3d4e5f6g7h8i9j0..."
  }'

Response 200

json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 1800
}
FieldTypeDescription
access_tokenstringJWT token for subsequent requests
token_typestringAlways "bearer"
expires_inintegerToken lifetime in seconds

Error responses

400
missing_tenant

The X-Tenant-ID header is required.

401
invalid_credentials

Invalid client credentials.

403
client_disabled

API client has been deactivated.

429

Rate limit exceeded (10 requests/minute).

POST/api/v1/ingestion/documents

Submit a document for ingestion

Upload a document file for asynchronous processing. The API stages the file, queues it for classification and promotion, and returns immediately with a tracking identifier.

Required scope:Ingest Documents

Headers

HeaderRequiredValue
AuthorizationYesBearer <access_token>
X-Tenant-IDYesYour organization UID
Idempotency-KeyNoUnique key to prevent duplicate submissions

Request body (multipart/form-data)

FieldTypeRequiredDescription
filefileYesDocument file (max 500 MB). PDF, Word, Excel, PowerPoint, CSV, TXT, PNG, JPEG, TIFF.
filenamestringNoOverride the original filename (max 255)
industry_keystringNoIndustry identifier, e.g. "mortgage" (max 80)
industry_uidstringNoIndustry ULID (26 chars, validated)
cabinet_uidstringNoTarget cabinet ULID (26 chars)
cabinet_namestringNoTarget cabinet name, resolved to UID (max 255)
module_keystringNoMetadata module key (max 80)
external_sourcestringNoSending system name, e.g. "salesforce" (max 200)
external_reference_idstringNoYour system's unique ID for this document (max 200)
external_entity_typestringNoEntity type in your system (max 100)
external_entity_idstringNoEntity ID in your system (max 200)
raw_document_typestringNoYour classification label (max 100)
metadataJSON stringNoCustom key-value metadata
notesstringNoInternal notes (max 5000)

Request example

bash
curl -X POST https://api.docuhelix.com/api/v1/ingestion/documents \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD" \
  -H "Idempotency-Key: los-2026-04-03-loan-78432-cd" \
  -F "file=@closing-disclosure.pdf" \
  -F "industry_key=mortgage" \
  -F "cabinet_uid=01JABC123CABINET456UIDXYZ" \
  -F "module_key=closing-documents" \
  -F "external_source=loan-origination-system" \
  -F "external_reference_id=LOAN-2026-04-00183" \
  -F "external_entity_type=Loan" \
  -F "external_entity_id=loan-78432" \
  -F 'metadata={"loan_number":"2026-04-00183","borrower":"Jane Doe"}'

Response 201

json
{
  "data": {
    "uid": "01JNQR7V3KXMSW8YBT4FH6PZEA",
    "org_uid": "01J8KP4QXRN3MV5YZWT6H2ABCD",
    "api_client_uid": "01J9ABC123DEF456GHI789JKLM",
    "correlation_uid": "01JNQR7V3KXMSW8YBT4FH6PZEB",
    "status": "processing",
    "content_sha256": "a3f2b8c1d4e5f6a7b8c9...f0a1",
    "original_filename": "closing-disclosure.pdf",
    "external_source": "loan-origination-system",
    "external_reference_id": "LOAN-2026-04-00183",
    "external_entity_type": "Loan",
    "external_entity_id": "loan-78432",
    "raw_document_type": "Closing Disclosure",
    "industry_key": "mortgage",
    "industry_uid": null,
    "cabinet_uid": "01JABC123CABINET456UIDXYZ",
    "module_key": "closing-documents",
    "received_at": "2026-04-03T21:15:00.000000Z",
    "processed_at": null,
    "created_at": "2026-04-03T21:15:00.000000Z",
    "updated_at": "2026-04-03T21:15:00.000000Z"
  }
}

Response fields

FieldTypeDescription
uidstringIngestion request tracking ID (ULID)
org_uidstringOrganization UID
api_client_uidstringAPI client that submitted the request
correlation_uidstringCorrelation ID for distributed tracing
statusstringProcessing status: received, processing, processed, rejected, failed
content_sha256stringSHA-256 hash of the uploaded file
original_filenamestringOriginal filename
external_sourcestring | nullExternal system identifier
external_reference_idstring | nullReference ID in external system
external_entity_typestring | nullEntity type in external system
external_entity_idstring | nullEntity ID in external system
raw_document_typestring | nullDocument classification label
industry_keystring | nullIndustry identifier
industry_uidstring | nullIndustry ULID
cabinet_uidstring | nullTarget cabinet ULID
module_keystring | nullMetadata module key
received_atdatetimeWhen the request was received
processed_atdatetime | nullWhen processing began
created_atdatetimeRecord creation timestamp
updated_atdatetimeRecord update timestamp

Error responses

400
validation_error

The file field is required.

401
missing_token

Bearer token is required.

401
invalid_token

Token is invalid or expired.

403
insufficient_scope

Token does not have the documents:ingest scope.

403
tenant_mismatch

Invalid tenant identifier.

422
validation_error

Cabinet not found in this organization.

429

Rate limit exceeded (60 requests/minute).

500
server_error

An unexpected error occurred.

GET/api/v1/org

Get organization context

Returns the authenticated organization context including industries, scopes, and client identity. Use this to confirm your integration is connected correctly and discover available industries.

Required scope:Read Organization

Headers

HeaderRequiredValue
AuthorizationYesBearer <access_token>
X-Tenant-IDYesYour organization UID

Request example

bash
curl https://api.docuhelix.com/api/v1/org \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"

Response 200

json
{
  "data": {
    "org_uid": "01J8KP4QXRN3MV5YZWT6H2ABCD",
    "api_client_uid": "01J9ABC123DEF456GHI789JKLM",
    "scopes": ["documents:ingest", "org:read", "cabinets:read"],
    "industries": [
      { "uid": "01JABC...", "key": "mortgage", "name": "Mortgage & Lending" },
      { "uid": "01JDEF...", "key": "legal", "name": "Legal Services" }
    ]
  }
}

Response fields

FieldTypeDescription
org_uidstringOrganization UID from the authenticated token
api_client_uidstringAuthenticated API client UID
scopesstring[]Scopes granted to this API client
industriesobject[]Industries attached to this organization
industries[].uidstringIndustry ULID
industries[].keystringMachine-readable industry key
industries[].namestringHuman-readable industry name

Error responses

401
missing_token

Bearer token is required.

403
insufficient_scope

Token does not have the org:read scope.

GET/api/v1/ingestions/{uid}

Get ingestion status

Check the asynchronous processing status of a previously submitted document. Returns classification progress, confidence scores, and promotion details when available.

Required scope:Read Ingestions

Path parameters

ParameterTypeDescription
uidstringThe ingestion request UID returned from the ingestion endpoint

Request example

bash
curl https://api.docuhelix.com/api/v1/ingestions/01JNQR7V3KXMSW8YBT4FH6PZEA \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"

Response 200

json
{
  "data": {
    "ingestion_request_uid": "01JNQR7V3KXMSW8YBT4FH6PZEA",
    "status": "published",
    "original_filename": "closing-disclosure.pdf",
    "content_sha256": "a3f2b8c1d4e5f6...",
    "received_at": "2026-04-03T21:15:00.000000Z",
    "processed_at": "2026-04-03T21:15:01.000000Z",
    "classification": {
      "status": "classified",
      "suggested_industry": { "uid": "01JABC...", "name": "Mortgage & Lending" },
      "suggested_cabinet": { "uid": "01JCAB...", "name": "Active Loans" },
      "suggested_module_key": "closing_disclosure",
      "confidence": { "industry": 1.0, "cabinet": 0.95, "module": 1.0 }
    },
    "promotion": {
      "status": "promoted",
      "document_uid": "01JDOC...",
      "version_uid": "01JVER..."
    },
    "last_error": null,
    "updated_at": "2026-04-03T21:15:05.000000Z"
  }
}

Response fields

FieldTypeDescription
ingestion_request_uidstringTracking identifier
statusstringProcessing status: received, processing, processed, rejected, failed
original_filenamestringOriginal uploaded filename
content_sha256stringSHA-256 file hash
received_atdatetimeWhen the ingestion was received
processed_atdatetime | nullWhen processing began
classificationobject | nullClassification details (available after processing)
classification.statusstringpending, classified, needs_review, unresolved, failed
classification.suggested_industryobject | nullAI/rule-suggested industry with uid and name
classification.suggested_cabinetobject | nullAI/rule-suggested cabinet with uid and name
classification.suggested_module_keystring | nullSuggested document type
classification.confidenceobjectConfidence scores (0.0–1.0) for industry, cabinet, module
promotionobject | nullPromotion details (available after classification)
promotion.statusstringnot_promoted, promoted, failed
promotion.document_uidstring | nullCreated document UID (when promoted)
promotion.version_uidstring | nullCreated version UID (when promoted)
last_errorstring | nullMost recent error message

Error responses

401
missing_token

Bearer token is required.

403
insufficient_scope

Token does not have the ingestions:read scope.

404
not_found

Ingestion not found.

GET/api/v1/cabinets

List cabinets

Search and list document cabinets for the authenticated organization. Use this to discover valid cabinet_uid values for explicit routing during ingestion.

Required scope:Read Cabinets

Query parameters

ParameterTypeDescription
industry_uidstringFilter by industry ULID
qstringSearch cabinets by name (max 255)
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 25, max: 100)

Request example

bash
curl "https://api.docuhelix.com/api/v1/cabinets?industry_uid=01JABC..." \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"

Response 200

json
{
  "data": [
    {
      "uid": "01JCAB123ACTIVE456LOANS789",
      "name": "Active Loans",
      "industry_uid": "01JABC...",
      "description": "Documents for active loan files"
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 25,
    "total": 1
  }
}

Error responses

401
missing_token

Bearer token is required.

403
insufficient_scope

Token does not have the cabinets:read scope.

GET/api/v1/document-types

List document types

List available document types (module keys) for the authenticated organization. Use this to discover valid module_key values for explicit routing during ingestion.

Required scope:Read Document Types

Query parameters

ParameterTypeDescription
qstringSearch by name or key (max 255)

Request example

bash
curl "https://api.docuhelix.com/api/v1/document-types?q=closing" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"

Response 200

json
{
  "data": [
    { "uid": "01JMOD...", "key": "closing_disclosure", "name": "Closing Disclosure" },
    { "uid": "01JMOD...", "key": "closing_statement", "name": "Closing Statement" }
  ]
}

Error responses

401
missing_token

Bearer token is required.

403
insufficient_scope

Token does not have the document-types:read scope.

GET/api/v1/documents

List documents

Search and list documents for the authenticated organization. Supports filtering by cabinet, document type, and text search.

Required scope:Read Documents

Query parameters

ParameterTypeDescription
qstringSearch by document title (max 255)
cabinet_uidstringFilter by cabinet ULID
module_keystringFilter by document type key
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 25, max: 100)

Request example

bash
curl "https://api.docuhelix.com/api/v1/documents?module_key=contract&per_page=10" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"

Response 200

json
{
  "data": [
    {
      "uid": "01JDOC...",
      "title": "NDA-2026-Partnership.pdf",
      "cabinet_uid": "01JCAB...",
      "cabinet_name": "Active Loans",
      "module_key": "contract",
      "created_by_type": "api_client",
      "created_at": "2026-04-03T21:15:05.000000Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 10,
    "total": 1
  }
}

Response fields

FieldTypeDescription
uidstringDocument ULID
titlestring | nullDocument title
cabinet_uidstringCabinet the document belongs to
cabinet_namestring | nullHuman-readable cabinet name
module_keystring | nullDocument type key
created_by_typestringCreator type: user or api_client
created_atdatetimeWhen the document was created

Error responses

401
missing_token

Bearer token is required.

403
insufficient_scope

Token does not have the documents:read scope.

Error envelope

All error responses use the same structure:

json
{
  "error": {
    "code": "error_code",
    "message": "Human-readable description",
    "details": {
      "field_name": ["Validation message"]
    }
  }
}
FieldTypeDescription
codestringMachine-readable error code
messagestringHuman-readable description
detailsobject | nullField-level validation errors (when applicable)