/api/v1/auth/tokenExchange 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
| Header | Required | Value |
|---|---|---|
Content-Type | Yes | application/json |
X-Tenant-ID | Yes | Your organization UID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
client_id | string | Yes | API client identifier issued by your DocuHelix admin |
client_secret | string | Yes | API client secret |
Request example
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
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 1800
}| Field | Type | Description |
|---|---|---|
access_token | string | JWT token for subsequent requests |
token_type | string | Always "bearer" |
expires_in | integer | Token lifetime in seconds |
Error responses
missing_tenantThe X-Tenant-ID header is required.
invalid_credentialsInvalid client credentials.
client_disabledAPI client has been deactivated.
Rate limit exceeded (10 requests/minute).
/api/v1/ingestion/documentsSubmit 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
| Header | Required | Value |
|---|---|---|
Authorization | Yes | Bearer <access_token> |
X-Tenant-ID | Yes | Your organization UID |
Idempotency-Key | No | Unique key to prevent duplicate submissions |
Request body (multipart/form-data)
| Field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | Document file (max 500 MB). PDF, Word, Excel, PowerPoint, CSV, TXT, PNG, JPEG, TIFF. |
filename | string | No | Override the original filename (max 255) |
industry_key | string | No | Industry identifier, e.g. "mortgage" (max 80) |
industry_uid | string | No | Industry ULID (26 chars, validated) |
cabinet_uid | string | No | Target cabinet ULID (26 chars) |
cabinet_name | string | No | Target cabinet name, resolved to UID (max 255) |
module_key | string | No | Metadata module key (max 80) |
external_source | string | No | Sending system name, e.g. "salesforce" (max 200) |
external_reference_id | string | No | Your system's unique ID for this document (max 200) |
external_entity_type | string | No | Entity type in your system (max 100) |
external_entity_id | string | No | Entity ID in your system (max 200) |
raw_document_type | string | No | Your classification label (max 100) |
metadata | JSON string | No | Custom key-value metadata |
notes | string | No | Internal notes (max 5000) |
Request example
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
{
"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
| Field | Type | Description |
|---|---|---|
uid | string | Ingestion request tracking ID (ULID) |
org_uid | string | Organization UID |
api_client_uid | string | API client that submitted the request |
correlation_uid | string | Correlation ID for distributed tracing |
status | string | Processing status: received, processing, processed, rejected, failed |
content_sha256 | string | SHA-256 hash of the uploaded file |
original_filename | string | Original filename |
external_source | string | null | External system identifier |
external_reference_id | string | null | Reference ID in external system |
external_entity_type | string | null | Entity type in external system |
external_entity_id | string | null | Entity ID in external system |
raw_document_type | string | null | Document classification label |
industry_key | string | null | Industry identifier |
industry_uid | string | null | Industry ULID |
cabinet_uid | string | null | Target cabinet ULID |
module_key | string | null | Metadata module key |
received_at | datetime | When the request was received |
processed_at | datetime | null | When processing began |
created_at | datetime | Record creation timestamp |
updated_at | datetime | Record update timestamp |
Error responses
validation_errorThe file field is required.
missing_tokenBearer token is required.
invalid_tokenToken is invalid or expired.
insufficient_scopeToken does not have the documents:ingest scope.
tenant_mismatchInvalid tenant identifier.
validation_errorCabinet not found in this organization.
Rate limit exceeded (60 requests/minute).
server_errorAn unexpected error occurred.
/api/v1/orgGet 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
| Header | Required | Value |
|---|---|---|
Authorization | Yes | Bearer <access_token> |
X-Tenant-ID | Yes | Your organization UID |
Request example
curl https://api.docuhelix.com/api/v1/org \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"Response 200
{
"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
| Field | Type | Description |
|---|---|---|
org_uid | string | Organization UID from the authenticated token |
api_client_uid | string | Authenticated API client UID |
scopes | string[] | Scopes granted to this API client |
industries | object[] | Industries attached to this organization |
industries[].uid | string | Industry ULID |
industries[].key | string | Machine-readable industry key |
industries[].name | string | Human-readable industry name |
Error responses
missing_tokenBearer token is required.
insufficient_scopeToken does not have the org:read scope.
/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
| Parameter | Type | Description |
|---|---|---|
uid | string | The ingestion request UID returned from the ingestion endpoint |
Request example
curl https://api.docuhelix.com/api/v1/ingestions/01JNQR7V3KXMSW8YBT4FH6PZEA \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"Response 200
{
"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
| Field | Type | Description |
|---|---|---|
ingestion_request_uid | string | Tracking identifier |
status | string | Processing status: received, processing, processed, rejected, failed |
original_filename | string | Original uploaded filename |
content_sha256 | string | SHA-256 file hash |
received_at | datetime | When the ingestion was received |
processed_at | datetime | null | When processing began |
classification | object | null | Classification details (available after processing) |
classification.status | string | pending, classified, needs_review, unresolved, failed |
classification.suggested_industry | object | null | AI/rule-suggested industry with uid and name |
classification.suggested_cabinet | object | null | AI/rule-suggested cabinet with uid and name |
classification.suggested_module_key | string | null | Suggested document type |
classification.confidence | object | Confidence scores (0.0–1.0) for industry, cabinet, module |
promotion | object | null | Promotion details (available after classification) |
promotion.status | string | not_promoted, promoted, failed |
promotion.document_uid | string | null | Created document UID (when promoted) |
promotion.version_uid | string | null | Created version UID (when promoted) |
last_error | string | null | Most recent error message |
Error responses
missing_tokenBearer token is required.
insufficient_scopeToken does not have the ingestions:read scope.
not_foundIngestion not found.
/api/v1/cabinetsList 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
| Parameter | Type | Description |
|---|---|---|
industry_uid | string | Filter by industry ULID |
q | string | Search cabinets by name (max 255) |
page | integer | Page number (default: 1) |
per_page | integer | Results per page (default: 25, max: 100) |
Request example
curl "https://api.docuhelix.com/api/v1/cabinets?industry_uid=01JABC..." \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"Response 200
{
"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
missing_tokenBearer token is required.
insufficient_scopeToken does not have the cabinets:read scope.
/api/v1/document-typesList 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
| Parameter | Type | Description |
|---|---|---|
q | string | Search by name or key (max 255) |
Request example
curl "https://api.docuhelix.com/api/v1/document-types?q=closing" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "X-Tenant-ID: 01J8KP4QXRN3MV5YZWT6H2ABCD"Response 200
{
"data": [
{ "uid": "01JMOD...", "key": "closing_disclosure", "name": "Closing Disclosure" },
{ "uid": "01JMOD...", "key": "closing_statement", "name": "Closing Statement" }
]
}Error responses
missing_tokenBearer token is required.
insufficient_scopeToken does not have the document-types:read scope.
/api/v1/documentsList documents
Search and list documents for the authenticated organization. Supports filtering by cabinet, document type, and text search.
Required scope:Read Documents
Query parameters
| Parameter | Type | Description |
|---|---|---|
q | string | Search by document title (max 255) |
cabinet_uid | string | Filter by cabinet ULID |
module_key | string | Filter by document type key |
page | integer | Page number (default: 1) |
per_page | integer | Results per page (default: 25, max: 100) |
Request example
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
{
"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
| Field | Type | Description |
|---|---|---|
uid | string | Document ULID |
title | string | null | Document title |
cabinet_uid | string | Cabinet the document belongs to |
cabinet_name | string | null | Human-readable cabinet name |
module_key | string | null | Document type key |
created_by_type | string | Creator type: user or api_client |
created_at | datetime | When the document was created |
Error responses
missing_tokenBearer token is required.
insufficient_scopeToken does not have the documents:read scope.
Error envelope
All error responses use the same structure:
{
"error": {
"code": "error_code",
"message": "Human-readable description",
"details": {
"field_name": ["Validation message"]
}
}
}| Field | Type | Description |
|---|---|---|
code | string | Machine-readable error code |
message | string | Human-readable description |
details | object | null | Field-level validation errors (when applicable) |
