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.
https://exhibitx-backend-production.up.railway.app/api/v1Authentication
All API requests require an API key. Pass it via the Authorization header or the X-API-Key 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:
Estimate cost
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'Create project
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'Poll status
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'
Download index
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.
| Pipeline | Rate | Example (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.
| Type | Description | Rate |
|---|---|---|
| book | Standard Document Index. Upload a PDF; get a structured, page-referenced index. | $0.001/token |
| docx | Embedded Document Index. Upload a .docx file; index is embedded back into the document via XE field markers. | $0.001/token |
Estimate Cost
/api/v1/estimate — Upload 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.
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'
{
"success": true,
"data": {
"tokenCount": 95420,
"pageCount": 312,
"endpointType": "pipeline",
"rate": 0.001,
"estimatedCost": 95.42,
"currency": "USD",
"currentBalance": 150,
"canAfford": true
}
}Create Project
/api/v1/projects — Upload 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.
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'
{
"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
| Parameter | Type | Description |
|---|---|---|
| file | File | PDF file to index |
| name | string | Project name |
Page Range (PDF only)
These parameters are ignored for DOCX uploads, which always process the entire document.
| Parameter | Type | Description |
|---|---|---|
| startPage | integer | First PDF page to index (auto-detected if omitted) |
| endPage | integer | Last PDF page to index (last page if omitted) |
| hasPreamble | string | "true" if book has roman-numeral preamble pages |
| preambleStartPage | integer | First preamble page (absolute PDF page) |
| preambleEndPage | integer | Last preamble page (absolute PDF page) |
| hasEndnotes | string | "true" if book has endnotes |
| endnoteLocation | string | "end_of_book" or "end_of_chapter" |
| endnotePageRanges | JSON | Array of start/end ranges for endnote pages |
| excludedPageRanges | JSON | Page ranges to skip (e.g., image-only pages) |
Index Type & Model
| Parameter | Type | Description |
|---|---|---|
| projectType | string | "book" (PDF) or "docx" (Word). Auto-detected from file extension when omitted. |
| modelTier | string | "standard" (default) or "premium" |
Extraction Control
| Parameter | Type | Description |
|---|---|---|
| extractionGranularity | string | "default", "detailed", or "highly_detailed" |
| extractionInstructions | string | Custom AI guidance (e.g., "Focus on legal terminology") |
| contextualSubentryMinMentions | integer | Min mentions for subentry generation (default: 5) |
| maxSubentryDepth | integer | Subentry nesting depth: 1-3 (default: 1) |
Paragraph IDs (PDF only)
DOCX uploads always use paragraph IDs and do not accept these overrides.
| Parameter | Type | Description |
|---|---|---|
| useParagraphIds | string | "true" to use paragraph IDs instead of page numbers |
| paragraphIdPattern | string | Regex pattern (e.g., "C\\d*P\\d+") |
| paragraphIdLocation | string | "left", "right", or "inline" |
Check Status
/api/v1/projects/{projectId}/status — Poll the indexing pipeline status.
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'
{
"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"
}
}Download Index
/api/v1/projects/{projectId}/index — Download the completed index as structured JSON.
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'
{
"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"
}
]
}
]
}
}Export Files
/api/v1/projects/{projectId}/export/download — Download formatted export files. Formats: docx, rtf, txt, latex, csv, cdxf, markdown.
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'
{
"success": true,
"message": "Binary file download"
}List Projects
/api/v1/projects — Retrieve a paginated list of your projects with term counts and status.
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'
{
"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
}
}Rename Project
/api/v1/projects/{projectId} — Rename an existing project.
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"
}'{
"success": true,
"data": {
"projectId": "proj_abc123",
"name": "Updated Project Name"
}
}Delete Project
/api/v1/projects/{projectId} — Permanently delete a project and all associated data.
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'
{
"success": true,
"message": "Project and all associated data have been deleted"
}Trim Index
/api/v1/projects/{projectId}/trim — Use AI to rank terms by importance and trim the index to a target count.
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
}'{
"success": true,
"data": {
"operationId": "op_trim_123",
"currentTermCount": 847,
"targetTermCount": 500,
"cost": {
"dollars": 9.54,
"remainingBalanceDollars": 45.04
}
}
}Check Balance
/api/v1/billing/balance — Check your current wallet balance and token rates.
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'
{
"success": true,
"data": {
"balanceDollars": 150,
"walletTokens": 100000,
"rates": {
"pipeline": {
"ratePerToken": 0.001
},
"legal_pipeline": {
"ratePerToken": 0.0005
},
"trim": {
"ratePerToken": 0.0001
}
}
}
}Top Up Wallet
/api/v1/billing/topup — Create a Stripe checkout session to add funds to your wallet.
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
}'{
"success": true,
"data": {
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_...",
"amountDollars": 100,
"walletTokens": 66667
}
}Billing History
/api/v1/billing/history — Retrieve a paginated list of billing events.
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'
{
"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
}
}
}Usage Statistics
/api/v1/usage — Get aggregated usage statistics for a date range.
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'
{
"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 Project
/api/v1/projects/{projectId} — Get detailed information about a specific project including statistics.
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'
{
"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
List Terms
/api/v1/projects/{projectId}/terms — Get all terms in a project with their page references and relationships.
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'
{
"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 Term Details
/api/v1/projects/{projectId}/terms/{termId} — Get detailed information about a specific term including mentions and relationships.
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'
{
"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
List Syntheses
/api/v1/projects/{projectId}/syntheses — Get AI-generated synthesis explanations for all terms in a project.
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'
{
"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.
| Plan | Per Minute | Per Day |
|---|---|---|
| Free | 60 | 1,000 |
| Pro | 300 | 10,000 |
| Enterprise | 1,000 | Unlimited |
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:
{
"success": false,
"error": "Human-readable error message",
"code": "ERROR_CODE"
}| Status | Meaning | Common Cause |
|---|---|---|
| 400 | Bad Request | Missing or invalid parameters |
| 401 | Unauthorized | Missing or invalid API key |
| 402 | Payment Required | Insufficient wallet balance |
| 403 | Forbidden | API key lacks required scope |
| 404 | Not Found | Project or resource does not exist |
| 409 | Conflict | Index not yet ready for download |
| 429 | Rate Limited | Too many requests; retry after X-RateLimit-Reset |
| 500 | Server Error | Internal error; contact support if persistent |