What Is NLDocSearch?

NLDocSearch (NLDS) is a platform that ingests mortgage documents, indexes them using AI-powered OCR and extraction, and enables natural language queries against those documents — for example: "latest signed Closing Disclosure for Mike Johnson".

Before You Read the API Reference

Read the Getting Started guide first. It explains all constructs (company, product, case, external IDs, upload flow, query semantics, webhook) with annotated examples before you start calling APIs.

Authentication

All endpoints require an OAuth2 Bearer token obtained via the AuthX machine client credentials flow.

Token endpoint:

POST /authx/oauth2/token
grant_type=client_credentials
client_id=<your-client-id>
client_secret=<your-client-secret>
scope=nldocsearch.api

Tokens expire after 30 minutes. Re-request before expiry. Cache locally — do not store in source code or version control.

API Journey

  1. Products — discover available product codes for your company
  2. Cases — create a case (loan application) under a product
  3. Document Upload — register documents, upload to blob storage, signal completion
  4. Query — submit a natural language query against a case; poll or receive via webhook
  5. Results — retrieve matched documents and open them

Products

Discover the product catalog for your company. Products are admin-managed and define the document context for cases. Integration clients read products; they do not create or modify them.

List active products for company

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": [
    ]
}

Get product by code

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

productCode
required
string

Product identifier code

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Cases

Create and inspect loan application cases. Each case is scoped to a product and aggregates all uploaded documents. Use externalCaseId to make case creation idempotent with your upstream system.

Create a case

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Request Body schema: application/json
required

Case creation request

productCode
required
string

Product identifier

externalCaseId
string or null <= 256 characters

Your system's case identifier (optional; enables idempotency)

displayName
string or null <= 256 characters

Human-readable case label

metadata
object or null

Arbitrary non-sensitive business metadata

Responses

Request samples

Content type
application/json
{
  • "productCode": "MORTGAGE",
  • "externalCaseId": "LOS-998877",
  • "displayName": "Johnson Residential Mortgage - 2024",
  • "metadata": {
    }
}

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Get case with document status summary

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

casePublicId
required
string <uuid>

Case public identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Document Upload

Register documents, receive SAS upload URLs, and signal completion. Documents are uploaded directly to Azure Blob Storage — the API never proxies file bytes. Validation runs automatically after upload completion.

Batch register documents and receive SAS upload URLs

Register 1–100 documents for a case and receive one short-lived SAS URL per document for direct-to-blob upload. Documents are uploaded directly to Azure Blob Storage using the SAS URL — the API never proxies file bytes.

If a document with the same externalDocumentId is already registered under the same (companyId, productId), the existing record is returned with its current status. A new SAS URL is issued only for documents in registered status or earlier.

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

casePublicId
required
string <uuid>

Case public identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Request Body schema: application/json
required

Document registration request

required
Array of objects (DocumentRegistrationItem) [ 1 .. 100 ] items

Responses

Request samples

Content type
application/json
{
  • "documents": [
    ]
}

Response samples

Content type
application/json
{}

Signal upload completion and trigger validation

Call this endpoint after the blob PUT to sasUploadUrl succeeds. NLDS will verify the blob exists in landing storage and begin validation asynchronously. Response returns immediately with uploadStatus: upload_pending. Poll the document status endpoint to track validation progress.

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

casePublicId
required
string <uuid>

Case public identifier

documentPublicId
required
string <uuid>

Document public identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Request Body schema: application/json

Upload completion request (optional)

confirmedContentLength
integer or null <int64>

Confirmed file size in bytes

confirmedContentType
string or null

Confirmed MIME type

Responses

Request samples

Content type
application/json
{
  • "confirmedContentLength": 1024576,
  • "confirmedContentType": "application/pdf"
}

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Get document upload and validation status

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

casePublicId
required
string <uuid>

Case public identifier

documentPublicId
required
string <uuid>

Document public identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

External Reference Lookup

Check whether documents are already registered before uploading. Use externalDocumentId (your system's document reference) to look up existing registration status and avoid duplicate uploads.

Check external document references before upload

Check whether documents identified by your system's externalDocumentId values are already registered in NLDS. Use this before batch registration to identify which documents to skip, retry, or re-upload.

Uniqueness is (companyId, productCode, externalDocumentId). Documents registered under different products are not returned.

Unknown externalDocumentId values are not included in the response — absence means not yet registered.

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Request Body schema: application/json
required

Document lookup request

productCode
required
string

Product identifier

externalDocumentIds
required
Array of strings [ 1 .. 100 ] items

List of document IDs to look up

Responses

Request samples

Content type
application/json
{
  • "productCode": "MORTGAGE",
  • "externalDocumentIds": [
    ]
}

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Query

Submit structured document checklist queries against a case's indexed documents. Queries run asynchronously. Poll the status endpoint or configure a webhook to receive results when the query pipeline completes.

Submit a document checklist query

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Request Body schema: application/json
required
casePublicId
required
string <uuid>

The case to query

required
Array of objects (DocTypeQueryItem) [ 1 .. 20 ] items

List of document types to find, each with optional attribute filters

previousJobId
string or null <uuid>

Prior job ID for conversational context carry-over

Responses

Request samples

Content type
application/json
{
  • "casePublicId": "87654321-4321-4321-4321-210987654321",
  • "checklist": [
    ],
  • "previousJobId": null
}

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Poll query job status

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

jobId
required
string <uuid>

Query job identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Retrieve query results

Call only after status endpoint returns complete or partial. Returns the full result set. isPartial: true when status is partial. Jobs expire 24 hours after creation — after expiry, results are no longer available.

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

jobId
required
string <uuid>

Query job identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
Example
{
  • "meta": {
    },
  • "data": {
    }
}

Document Access

Retrieve short-lived access URLs for document viewing/download. Search results contain identifiers only — never direct storage URLs. Call this endpoint when a user selects a result to open the document.

Get short-lived document access URL

Retrieve a short-lived access URL for a result document. Search results contain identifiers only — no direct storage URLs. Call this endpoint when presenting a result to a user who wants to open the document.

The access URL is generated at request time after re-checking tenant and document authorization. It expires in minutes (see expiresAt). Do not cache accessUrl beyond expiry — request a new one for each access.

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

docId
required
string <uuid>

Document identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{
  • "meta": {
    },
  • "data": {
    }
}

Webhooks

Configure a webhook endpoint to receive query results via push delivery instead of polling. NLDS posts NldsQueryResultEvent to your configured URL when a query job reaches a terminal state.

Configure query result webhook

Configure or update the webhook endpoint that NLDS calls when a query reaches a terminal state (complete, partial, or failed). There is one webhook configuration per company. Calling PUT again updates the existing configuration.

NLDS will send HTTP POST to your url with an NldsQueryResultEvent payload and an X-Webhook-Signature header (HMAC-SHA256 of the request body using your secret). Verify this signature before processing the event.

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Request Body schema: application/json
required
url
required
string <uri>

HTTPS endpoint URL where NLDS will POST webhook events

secret
required
string >= 16 characters

Shared secret for HMAC-SHA256 signature verification

active
boolean
Default: true

Enable or pause webhook delivery

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{}

Get current webhook configuration

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{}

Remove webhook configuration

Authorizations:
bearerAuth
path Parameters
companyId
required
integer <int64>

Company tenant identifier

header Parameters
X-Request-ID
string <uuid>

Optional client-provided request correlation ID

Responses

Response samples

Content type
application/json
{
  • "meta": {
    }
}

Webhook callback endpoint (client-implemented)

This endpoint is IMPLEMENTED BY THE CLIENT. NLDS will POST to the URL you configured via PUT /webhooks/query-result. This schema documents the expected payload structure and client responsibilities.

Your implementation must:

  1. Verify the signature in X-Webhook-Signature header by computing HMAC-SHA256 of the raw request body using your configured secret.
  2. Return HTTP 200 within 10 seconds.
  3. Handle retries — the same eventId may be delivered multiple times; use it for deduplication on your side.
  4. If not ready to handle the event, return a non-200 status or timeout; NLDS will retry.

NLDS retry policy:

  • On non-200 response or timeout (>10 seconds): retry with exponential backoff
  • Retry schedule: 1 minute, 5 minutes, 30 minutes
  • Max 3 retries
  • After exhausting retries, the event is dropped and an alert is raised on the NLDS side

Example verification code (Node.js):

const crypto = require('crypto');
const signature = req.headers['x-webhook-signature'];
const computed = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
if (signature !== computed) {
  return res.status(401).send('Signature invalid');
}
Authorizations:
bearerAuth
header Parameters
X-Webhook-Signature
required
string

HMAC-SHA256 of request body signed with your webhook secret (hex-encoded)

Request Body schema: application/json
required
eventId
required
string

Unique event delivery identifier (use for idempotency)

eventType
required
string
Enum: "NLDOCSEARCH_QUERY_COMPLETED" "NLDOCSEARCH_QUERY_PARTIAL" "NLDOCSEARCH_QUERY_FAILED"

Event classification

companyId
required
integer <int64>

Company identifier

casePublicId
required
string <uuid>

Case identifier

jobId
required
string <uuid>

Query job identifier

status
required
string (QueryStatus)
Enum: "processing" "complete" "partial" "failed"

Query job status

occurredAt
required
string <date-time>

Event timestamp

object (NldsResultSummary)
Array of objects or null (QueryResultItem)

Full result set for COMPLETED and PARTIAL; null for FAILED

errorCode
string or null

Error code for FAILED events

errorMessage
string or null

Error message for FAILED events

Responses

Request samples

Content type
application/json
{
  • "eventId": "string",
  • "eventType": "NLDOCSEARCH_QUERY_COMPLETED",
  • "companyId": 0,
  • "casePublicId": "6e32fc0a-3656-4840-a65e-87b981967f16",
  • "jobId": "9d222c6d-893e-4e79-8201-3c9ca16a0f39",
  • "status": "processing",
  • "occurredAt": "2019-08-24T14:15:22Z",
  • "resultSummary": {
    },
  • "results": [
    ],
  • "errorCode": "string",
  • "errorMessage": "string"
}