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 book indexing into your workflow. Upload PDFs, run the AI pipeline, and download professional indexes 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 ixia_live_...' \
-H 'Content-Type: application/json'Create an account to generate your API key from the developer dashboard. Keys are prefixed with ixia_live_ for production and ixia_test_ for sandbox.
Quick Start
Four steps to go from a PDF to a professional index:
Estimate cost
curl -X POST 'https://exhibitx-backend-production.up.railway.app/api/v1/estimate' \
-H 'X-API-Key: ixia_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: ixia_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: ixia_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: ixia_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) |
|---|---|---|
| Main Pipeline | $0.001 / token | $100.00 |
| Legal Citation | $0.0005 / token | $50.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.
Index Types
The projectType parameter determines which indexing pipeline runs.
| Type | Description | Rate |
|---|---|---|
| book | Standard back-of-book index from PDF (default) | $0.001/token |
| bulk | Embedded/large document index. Requires extractionInstructions. Skips subentries. | $0.001/token |
| legal_locorum | Legal citation index (Bluebook/OSCOLA). Configure via citationConfig. | $0.0005/token |
| scripture | Bible reference index. Configure via scriptureConfig. | $0.001/token |
| classics_locorum | Classical text citations (OCD/LSJ). Configure via citationConfig. | $0.001/token |
| author_works | Author/works index for music, literature, art, film. Configure via authorWorksConfig. | $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 page range; endpointType ("pipeline" | "legal_pipeline" | "trim") for pricing tier; projectType to auto-determine rate.
curl -X POST \
'exhibitx-backend-production.up.railway.app/api/v1/estimate' \
-H 'X-API-Key: ixia_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 (multipart/form-data, field: "file") and start the AI indexing pipeline. Charges wallet based on document tokens. Required: file, name. Supports all index types via projectType. See parameter reference below for page ranges, custom instructions, legal/scripture/author-works configs, and more.
curl -X POST \
'exhibitx-backend-production.up.railway.app/api/v1/projects' \
-H 'X-API-Key: ixia_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
| 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" (default), "bulk", "legal_locorum", "scripture", "classics_locorum", "author_works" |
| 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
| 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" |
Special Index Configurations (JSON strings)
| Parameter | Fields | Used With |
|---|---|---|
| scriptureConfig | bibleVersion, namingConvention, canons[] | scripture |
| citationConfig | citationSystem, jurisdictions[], includeCategories[], customCitationRules | legal_locorum, classics_locorum |
| authorWorksConfig | subjectDomain, includeMetadata | author_works |
Check Status
/api/v1/projects/{projectId}/status — Poll the indexing pipeline status.
curl -X GET \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/status' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/index' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/export/download' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/trim' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/billing/balance' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/billing/topup' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/billing/history' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/usage' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/terms' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/terms/term_xyz789' \
-H 'X-API-Key: ixia_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 \
'exhibitx-backend-production.up.railway.app/api/v1/projects/proj_abc123/syntheses' \
-H 'X-API-Key: ixia_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 |