Get Your API Key

Create a free account to generate API keys and start building automated indexing into your workflow.

ExhibitX Developer API

Build automated document indexing into your workflow. Upload a PDF or Word document, run the AI pipeline, and download a structured, page-referenced index programmatically.

Base URL
https://exhibitx-backend-production.up.railway.app/api/v1

Authentication

All API requests require an API key. Pass it via the Authorization header or the X-API-Key header.

Authorization Header
curl -X GET 'https://exhibitx-backend-production.up.railway.app/api/v1/projects' \
  -H 'Authorization: Bearer exbx_live_...' \
  -H 'Content-Type: application/json'

Create an account to generate your API key from the developer dashboard. Keys are prefixed with exbx_live_ for production and exbx_test_ for sandbox.

Quick Start

Four steps to go from a PDF or DOCX to a professional index:

1

Estimate cost

BASH
curl -X POST 'https://exhibitx-backend-production.up.railway.app/api/v1/estimate' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -F 'file=@book.pdf'
2

Create project

BASH
curl -X POST 'https://exhibitx-backend-production.up.railway.app/api/v1/projects' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -F 'file=@book.pdf' \
  -F 'name=My Book Index' \
  -F 'startPage=13' \
  -F 'endPage=342' \
  -F 'extractionInstructions=Focus on key concepts and named entities'
3

Poll status

BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/status' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
4

Download index

BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/index' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'

Pricing & Billing

Usage is metered by document tokens. Top up your wallet and pay per document.

PipelineRateExample (100K tokens)
Standard Document Index (PDF)$0.001 / token$100.00
Embedded Document Index (DOCX)$0.001 / token$100.00
Trim$0.0001 / token$10.00

Top up your wallet via the billing API or the dashboard. Enterprise customers can request custom rates by contacting support.

Document Types

ExhibitX supports two document workflows. The type is auto-detected from the uploaded file's extension, or you can set it explicitly via the projectType parameter.

TypeDescriptionRate
bookStandard Document Index. Upload a PDF; get a structured, page-referenced index.$0.001/token
docxEmbedded Document Index. Upload a .docx file; index is embedded back into the document via XE field markers.$0.001/token
POST

Estimate Cost

/api/v1/estimateUpload a PDF or DOCX (multipart/form-data, field: "file") to get a token count and price estimate without being charged. Optional: startPage/endPage (integers) for PDF page range.

Request
BASH
curl -X POST \
  'https://exhibitx-backend-production.up.railway.app/api/v1/estimate' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "tokenCount": 95420,
    "pageCount": 312,
    "endpointType": "pipeline",
    "rate": 0.001,
    "estimatedCost": 95.42,
    "currency": "USD",
    "currentBalance": 150,
    "canAfford": true
  }
}
POST

Create Project

/api/v1/projectsUpload a PDF or DOCX (multipart/form-data, field: "file") and start the AI indexing pipeline. Charges wallet based on document tokens. Required: file, name. Document type is auto-detected: `.pdf` produces a Standard Document Index, `.docx` produces an Embedded Document Index (Word XE fields). See parameter reference below for page ranges, custom extraction instructions, and more.

Request
BASH
curl -X POST \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "projectId": "proj_abc123",
    "operationId": "op_xyz789",
    "statusEndpoint": "/api/v1/projects/proj_abc123/status",
    "cost": {
      "dollars": 95.42,
      "documentTokens": 95420,
      "ratePerToken": 0.001,
      "remainingBalanceDollars": 54.58
    }
  }
}

Create Project Parameters

All parameters are sent as multipart form fields. JSON objects must be stringified.

Required

ParameterTypeDescription
fileFilePDF file to index
namestringProject name

Page Range (PDF only)

These parameters are ignored for DOCX uploads, which always process the entire document.

ParameterTypeDescription
startPageintegerFirst PDF page to index (auto-detected if omitted)
endPageintegerLast PDF page to index (last page if omitted)
hasPreamblestring"true" if book has roman-numeral preamble pages
preambleStartPageintegerFirst preamble page (absolute PDF page)
preambleEndPageintegerLast preamble page (absolute PDF page)
hasEndnotesstring"true" if book has endnotes
endnoteLocationstring"end_of_book" or "end_of_chapter"
endnotePageRangesJSONArray of start/end ranges for endnote pages
excludedPageRangesJSONPage ranges to skip (e.g., image-only pages)

Index Type & Model

ParameterTypeDescription
projectTypestring"book" (PDF) or "docx" (Word). Auto-detected from file extension when omitted.
modelTierstring"standard" (default) or "premium"

Extraction Control

ParameterTypeDescription
extractionGranularitystring"default", "detailed", or "highly_detailed"
extractionInstructionsstringCustom AI guidance (e.g., "Focus on legal terminology")
contextualSubentryMinMentionsintegerMin mentions for subentry generation (default: 5)
maxSubentryDepthintegerSubentry nesting depth: 1-3 (default: 1)

Paragraph IDs (PDF only)

DOCX uploads always use paragraph IDs and do not accept these overrides.

ParameterTypeDescription
useParagraphIdsstring"true" to use paragraph IDs instead of page numbers
paragraphIdPatternstringRegex pattern (e.g., "C\\d*P\\d+")
paragraphIdLocationstring"left", "right", or "inline"
GET

Check Status

/api/v1/projects/{projectId}/statusPoll the indexing pipeline status.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/status' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "operationId": "op_xyz789",
    "status": "in_progress",
    "currentPhase": "Phase 10: Synthesis Generation",
    "progressPercent": 67,
    "startedAt": "2025-01-15T10:30:00Z",
    "updatedAt": "2025-01-15T10:45:00Z"
  }
}
GET

Download Index

/api/v1/projects/{projectId}/indexDownload the completed index as structured JSON.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/index' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "metadata": {
      "projectId": "proj_abc123",
      "totalTerms": 847,
      "totalSubentries": 234
    },
    "terms": [
      {
        "termId": "t1",
        "name": "carbon emissions",
        "pages": [
          12,
          45,
          46,
          47,
          89
        ],
        "synthesis": "Carbon emissions refer to...",
        "crossReferences": [
          {
            "type": "see_also",
            "targetTermName": "greenhouse gases"
          }
        ]
      }
    ]
  }
}
GET

Export Files

/api/v1/projects/{projectId}/export/downloadDownload formatted export files. Formats: docx, rtf, txt, latex, csv, cdxf, markdown.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/export/download' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "message": "Binary file download"
}
GET

List Projects

/api/v1/projectsRetrieve a paginated list of your projects with term counts and status.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": [
    {
      "project_id": "proj_abc123",
      "name": "Climate Policy Analysis",
      "status": "completed",
      "term_count": 847,
      "created_at": "2025-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 23,
    "total_pages": 1,
    "has_more": false
  }
}
PATCH

Rename Project

/api/v1/projects/{projectId}Rename an existing project.

Request
BASH
curl -X PATCH \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
 \
  -d '{
      "name": "Updated Project Name"
    }'
Response
JSON
{
  "success": true,
  "data": {
    "projectId": "proj_abc123",
    "name": "Updated Project Name"
  }
}
DELETE

Delete Project

/api/v1/projects/{projectId}Permanently delete a project and all associated data.

Request
BASH
curl -X DELETE \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "message": "Project and all associated data have been deleted"
}
POST

Trim Index

/api/v1/projects/{projectId}/trimUse AI to rank terms by importance and trim the index to a target count.

Request
BASH
curl -X POST \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/trim' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
 \
  -d '{
      "targetTermCount": 500
    }'
Response
JSON
{
  "success": true,
  "data": {
    "operationId": "op_trim_123",
    "currentTermCount": 847,
    "targetTermCount": 500,
    "cost": {
      "dollars": 9.54,
      "remainingBalanceDollars": 45.04
    }
  }
}
GET

Check Balance

/api/v1/billing/balanceCheck your current wallet balance and token rates.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/billing/balance' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "balanceDollars": 150,
    "walletTokens": 100000,
    "rates": {
      "pipeline": {
        "ratePerToken": 0.001
      },
      "legal_pipeline": {
        "ratePerToken": 0.0005
      },
      "trim": {
        "ratePerToken": 0.0001
      }
    }
  }
}
POST

Top Up Wallet

/api/v1/billing/topupCreate a Stripe checkout session to add funds to your wallet.

Request
BASH
curl -X POST \
  'https://exhibitx-backend-production.up.railway.app/api/v1/billing/topup' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
 \
  -d '{
      "amount_dollars": 100
    }'
Response
JSON
{
  "success": true,
  "data": {
    "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_...",
    "amountDollars": 100,
    "walletTokens": 66667
  }
}
GET

Billing History

/api/v1/billing/historyRetrieve a paginated list of billing events.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/billing/history' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "events": [
      {
        "eventId": "evt_123",
        "endpointType": "pipeline",
        "documentTokens": 95420,
        "amountDollars": 95.42,
        "status": "completed",
        "createdAt": "2025-01-15T10:30:00Z"
      }
    ],
    "pagination": {
      "page": 1,
      "total": 5
    }
  }
}
GET

Usage Statistics

/api/v1/usageGet aggregated usage statistics for a date range.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/usage' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "statistics": {
      "total_requests": 1247,
      "successful_requests": 1230
    },
    "billing": {
      "totalSpendDollars": 523.4,
      "totalDocumentTokensProcessed": 523400
    }
  }
}

Read API

Read-only endpoints for accessing project data, terms, and syntheses.

Projects

Access and list your indexing projects

GET

Get Project

/api/v1/projects/{projectId}Get detailed information about a specific project including statistics.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "project_id": "proj_abc123",
    "name": "Climate Policy Analysis",
    "book_title": "Global Climate Governance",
    "book_author": "Dr. Jane Smith",
    "status": "completed",
    "term_count": 847,
    "mention_count": 3254,
    "synthesis_count": 312,
    "cross_reference_count": 156,
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-16T14:22:00Z"
  }
}

Terms

Retrieve terms, page references, and relationships

GET

List Terms

/api/v1/projects/{projectId}/termsGet all terms in a project with their page references and relationships.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/terms' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": [
    {
      "term_id": "term_xyz789",
      "standardized_term": "carbon emissions",
      "user_edit": null,
      "page_refs": "12, 45-47, 89",
      "mention_count": 23,
      "has_synthesis": true,
      "parent_id": null,
      "children_count": 3
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 847,
    "total_pages": 17,
    "has_more": true
  }
}
GET

Get Term Details

/api/v1/projects/{projectId}/terms/{termId}Get detailed information about a specific term including mentions and relationships.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/terms/term_xyz789' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": {
    "term_id": "term_xyz789",
    "standardized_term": "carbon emissions",
    "user_edit": null,
    "page_refs": "12, 45-47, 89",
    "mentions": [
      {
        "page": 12,
        "context": "...reducing carbon emissions through policy..."
      },
      {
        "page": 45,
        "context": "...global carbon emissions have increased..."
      }
    ],
    "synthesis": "Carbon emissions refer to the release of carbon dioxide...",
    "parent": null,
    "children": [
      {
        "term_id": "child_1",
        "name": "industrial emissions"
      },
      {
        "term_id": "child_2",
        "name": "transportation emissions"
      }
    ],
    "cross_references": [
      {
        "term_id": "xref_1",
        "name": "greenhouse gases"
      }
    ]
  }
}

Syntheses

AI-generated explanations for each term

GET

List Syntheses

/api/v1/projects/{projectId}/synthesesGet AI-generated synthesis explanations for all terms in a project.

Request
BASH
curl -X GET \
  'https://exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/syntheses' \
  -H 'X-API-Key: exbx_live_your_api_key' \
  -H 'Content-Type: application/json'
Response
JSON
{
  "success": true,
  "data": [
    {
      "synthesis_id": "syn_abc123",
      "term_id": "term_xyz789",
      "term_name": "carbon emissions",
      "synthesis_text": "Carbon emissions in this work refer to the release of CO2...",
      "model_used": "gpt-4o",
      "created_at": "2025-01-15T12:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 312,
    "total_pages": 7,
    "has_more": true
  }
}

Rate Limits

Rate limits depend on your plan. Limits are applied per API key.

PlanPer MinutePer Day
Free601,000
Pro30010,000
Enterprise1,000Unlimited

Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Error Codes

All errors follow a consistent JSON format:

Error Response Format
{
  "success": false,
  "error": "Human-readable error message",
  "code": "ERROR_CODE"
}
StatusMeaningCommon Cause
400Bad RequestMissing or invalid parameters
401UnauthorizedMissing or invalid API key
402Payment RequiredInsufficient wallet balance
403ForbiddenAPI key lacks required scope
404Not FoundProject or resource does not exist
409ConflictIndex not yet ready for download
429Rate LimitedToo many requests; retry after X-RateLimit-Reset
500Server ErrorInternal error; contact support if persistent