Skip to main content
This page provides a comprehensive overview of the Graphor public REST APIs. It covers the full lifecycle:
  1. Data Ingestion (Sources API): Bring data in, process it, and retrieve structured elements.
  2. Document Chat (Chat API): Ask questions about your ingested documents using natural language.
  3. Data Extraction (Extract API): Extract specific structured data from documents using custom schemas.

Data Ingestion (Sources API)

The Sources API covers the full ingestion lifecycle:

Document Chat (Chat API)

Once your data is ingested, use the Chat API to ask questions:

Data Extraction (Extract API)

Extract specific structured data from your documents using schemas:

What “Data Ingestion” includes

  • Upload: create a new source (file / URL / GitHub / YouTube)
  • Process: choose OCR/parsing method; reprocess when needed
  • List: monitor status and metadata
  • Elements: retrieve structured elements/partitions after processing
  • Delete: remove a source permanently

Authentication

All API endpoints require authentication using API tokens. Include your token in the Authorization header:
Authorization: Bearer YOUR_API_TOKEN
Learn how to generate and manage API tokens in the API Tokens guide.

Token Security

  • Never expose tokens in client-side code or public repositories
  • Use environment variables to store tokens securely
  • Rotate tokens regularly for enhanced security
  • Use different tokens for different environments (dev/staging/prod)

URL Structure

Graphor API endpoints follow consistent URL patterns based on their scope and purpose:

Sources (Data Ingestion)

https://sources.graphorlm.com      # Source management

Chat

https://sources.graphorlm.com/ask-sources    # Document Chat

Extraction

https://sources.graphorlm.com/run-extraction # Data Extraction

Response Formats

All API responses follow consistent JSON structures with appropriate HTTP status codes:

Success Response Pattern

{
  "status": "success",
  "message": "Operation completed successfully",
  "data": {
    // Resource-specific data
  }
}

Error Response Pattern

{
  "detail": "Descriptive error message explaining what went wrong"
}

Common Status Codes

CodeMeaningUsage
200OKSuccessful GET, POST, PATCH operations
400Bad RequestInvalid parameters or malformed requests
401UnauthorizedInvalid or missing API token
404Not FoundResource doesn’t exist
413Payload Too LargeFile size exceeds limits
500Internal Server ErrorServer-side processing errors

Complete Workflow Example

Here’s the full “happy path”: upload → process → list → elements → chat/extract.

1. Upload a source

// Upload a document
const uploadResponse = await fetch('https://sources.graphorlm.com/upload', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN'
  },
  body: formData // File data
});
const { file_name } = await uploadResponse.json();
console.log('Uploaded:', file_name);

2. Process (OCR/parsing)

const processResponse = await fetch('https://sources.graphorlm.com/process', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    file_name,
    partition_method: 'hi_res'
  })
});

3. Monitor status (List Sources)

const listResponse = await fetch('https://sources.graphorlm.com', {
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN'
  }
});
const sources = await listResponse.json();
const source = sources.find(s => s.file_name === file_name);
console.log('Status:', source?.status);

4. Retrieve structured elements (after processing)

const elementsResponse = await fetch('https://sources.graphorlm.com/elements', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    file_name
  })
});
const elements = await elementsResponse.json();
console.log('Elements:', elements.length);

5. Ask Questions (Chat)

const chatResponse = await fetch('https://sources.graphorlm.com/ask-sources', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    question: "What are the main topics in this document?",
    file_names: [file_name] // Optional: Scope to this specific file
  })
});
const answer = await chatResponse.json();
console.log('Answer:', answer.answer);

6. Extract Data (Extraction)

const extractResponse = await fetch('https://sources.graphorlm.com/run-extraction', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    file_name: file_name,
    user_instruction: "Extract the invoice number and total amount.",
    output_schema_fields: [
      { key: "invoice_number", type: "string", description: "Invoice ID" },
      { key: "total_amount", type: "number", description: "Total due" }
    ]
  })
});
const extractedData = await extractResponse.json();
console.log('Extracted:', extractedData.extracted_items[0].output);

Integration Patterns

Minimal Sources (Ingestion) Client

class GraphorClient {
  constructor(apiToken) {
    this.apiToken = apiToken;
    this.headers = {
      'Authorization': `Bearer ${apiToken}`,
      'Content-Type': 'application/json'
    };
  }

  async uploadSource(file, filename) {
    const formData = new FormData();
    formData.append('file', file, filename);
    
    const response = await fetch('https://sources.graphorlm.com/upload', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${this.apiToken}` },
      body: formData
    });
    return await response.json();
  }

  async listSources() {
    const response = await fetch('https://sources.graphorlm.com', {
      headers: this.headers
    });
    return await response.json();
  }

  async processSource(fileName, partitionMethod = 'BASIC') {
    const response = await fetch('https://sources.graphorlm.com/process', {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({
        file_name: fileName,
        partition_method: partitionMethod
      })
    });
    return await response.json();
  }

  async listElements(fileName) {
    const response = await fetch('https://sources.graphorlm.com/elements', {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({ file_name: fileName })
    });
    return await response.json();
  }

  async deleteSource(fileName) {
    const response = await fetch('https://sources.graphorlm.com/delete', {
      method: 'DELETE',
      headers: this.headers,
      body: JSON.stringify({ file_name: fileName })
    });
    return await response.json();
  }

  async ask(question, fileNames = []) {
    const response = await fetch('https://sources.graphorlm.com/ask-sources', {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({ 
        question, 
        file_names: fileNames 
      })
    });
    return await response.json();
  }

  async extract(fileName, instruction, schema) {
    const response = await fetch('https://sources.graphorlm.com/run-extraction', {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({
        file_name: fileName,
        user_instruction: instruction,
        output_schema_fields: schema
      })
    });
    return await response.json();
  }
}

// Usage example
const client = new GraphorClient('YOUR_API_TOKEN');

// Ingestion + Chat + Extraction workflow
async function ingestAndAnalyze() {
  try {
    // 1. Upload and process
    const file = document.getElementById('fileInput').files[0];
    await client.uploadSource(file, file.name);
    await client.processSource(file.name, 'hi_res');
    
    // 2. Chat with the document
    const chatResult = await client.ask("Summarize this document", [file.name]);
    console.log('Chat Answer:', chatResult.answer);

    // 3. Extract structured data
    const extractResult = await client.extract(
      file.name,
      "Extract key values",
      [{ key: "summary", type: "string", description: "Document summary" }]
    );
    console.log('Extraction:', extractResult.extracted_items);

  } catch (error) {
    console.error('Error:', error);
  }
}

Python Integration

import requests
from typing import Dict, List, Any, Optional
import os

class GraphorLMAPI:
    def __init__(self, api_token: str):
        self.api_token = api_token
        self.headers = {
            "Authorization": f"Bearer {api_token}",
            "Content-Type": "application/json"
        }
    
    # Sources API
    def upload_source(self, file_path: str) -> Dict[str, Any]:
        """Upload a source file"""
        url = "https://sources.graphorlm.com/upload"
        
        with open(file_path, 'rb') as f:
            files = {'file': (os.path.basename(file_path), f)}
            headers = {"Authorization": f"Bearer {self.api_token}"}
            response = requests.post(url, headers=headers, files=files)
            
        response.raise_for_status()
        return response.json()
    
    def list_sources(self) -> List[Dict[str, Any]]:
        """List all sources"""
        response = requests.get("https://sources.graphorlm.com", headers=self.headers)
        response.raise_for_status()
        return response.json()
    
    def process_source(self, file_name: str, partition_method: str = "BASIC") -> Dict[str, Any]:
        """Process a source with specified method"""
        url = "https://sources.graphorlm.com/process"
        payload = {
            "file_name": file_name,
            "partition_method": partition_method
        }
        response = requests.post(url, headers=self.headers, json=payload)
        response.raise_for_status()
        return response.json()
    
    def list_elements(self, file_name: str) -> List[Dict[str, Any]]:
        """List structured elements/partitions for a processed source"""
        url = "https://sources.graphorlm.com/elements"
        payload = {"file_name": file_name}
        response = requests.post(url, headers=self.headers, json=payload)
        response.raise_for_status()
        return response.json()
    
    def delete_source(self, file_name: str) -> Dict[str, Any]:
        """Delete a source"""
        url = "https://sources.graphorlm.com/delete"
        payload = {"file_name": file_name}
        response = requests.delete(url, headers=self.headers, json=payload)
        response.raise_for_status()
        return response.json()
    
    # Chat API
    def ask(self, question: str, file_names: Optional[List[str]] = None) -> Dict[str, Any]:
        """Ask a question about documents"""
        url = "https://sources.graphorlm.com/ask-sources"
        payload = {"question": question}
        if file_names:
            payload["file_names"] = file_names
            
        response = requests.post(url, headers=self.headers, json=payload)
        response.raise_for_status()
        return response.json()

    # Extraction API
    def extract(self, file_name: str, instruction: str, schema: List[Dict[str, Any]]) -> Dict[str, Any]:
        """Extract structured data from a document"""
        url = "https://sources.graphorlm.com/run-extraction"
        payload = {
            "file_name": file_name,
            "user_instruction": instruction,
            "output_schema_fields": schema
        }
        response = requests.post(url, headers=self.headers, json=payload)
        response.raise_for_status()
        return response.json()

# Usage
api = GraphorLMAPI(os.getenv("GRAPHORLM_API_TOKEN"))

# Ingestion, Chat, and Extraction workflow
def analyze_documents(documents: List[str]):
    try:
        # 1. Ingest
        for doc_path in documents:
            api.upload_source(doc_path)
            file_name = os.path.basename(doc_path)
            api.process_source(file_name, 'hi_res')
            
            # 2. Chat
            chat_answer = api.ask("What is this document about?", [file_name])
            print(f"Chat Answer for {file_name}: {chat_answer['answer']}")

            # 3. Extract
            schema = [{"key": "summary", "type": "string", "description": "Short summary"}]
            extract_result = api.extract(file_name, "Summarize the document", schema)
            print(f"Extraction for {file_name}: {extract_result['extracted_items']}")
        
        return True
        
    except Exception as e:
        print(f"Failed: {e}")
        return False

Rate Limits and Best Practices

Performance Guidelines

  • Batch Operations: Group multiple related requests when possible
  • Asynchronous Processing: Use async/await for multiple concurrent requests
  • Retry Logic: Implement exponential backoff for transient failures
  • Caching: Cache frequently accessed data like flow configurations

Error Handling Best Practices

async function robustAPICall(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(`HTTP ${response.status}: ${errorData.detail}`);
      }
      
      return await response.json();
    } catch (error) {
      console.warn(`Attempt ${attempt} failed:`, error.message);
      
      if (attempt === maxRetries) {
        throw error;
      }
      
      // Exponential backoff
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
    }
  }
}

Testing and Development

API Testing Tools

You can test Graphor API endpoints using:
  • cURL: Command-line testing and scripting
  • Postman: Interactive API testing and documentation
  • Bruno/Insomnia: Alternative API clients
  • Custom Scripts: Automated testing suites

Example cURL Commands

# List all sources
curl -X GET "https://sources.graphorlm.com" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Upload a file
curl -X POST "https://sources.graphorlm.com/upload" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "[email protected]"

# Process a source (OCR/parsing)
curl -X POST "https://sources.graphorlm.com/process" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"file_name":"document.pdf","partition_method":"hi_res"}'

# List source elements/partitions
curl -X POST "https://sources.graphorlm.com/elements" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"file_name":"document.pdf"}'

# Delete a source
curl -X DELETE "https://sources.graphorlm.com/delete" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"file_name":"document.pdf"}'

Common Use Cases

Content Management System Integration

Ingest documents as they’re created/updated in your CMS:
class ContentSearchAPI {
  constructor(apiToken, flowName) {
    this.client = new GraphorClient(apiToken);
  }

  async ingestDocument(file, partitionMethod = 'hi_res') {
    const uploadResult = await this.client.uploadSource(file, file.name);
    await this.client.processSource(file.name, partitionMethod);
    return { success: true, fileName: uploadResult.file_name };
  }
}

Automated Ingestion Pipeline

Batch ingest research documents (upload + process):
class ResearchPipeline:
    def __init__(self, api_token: str):
        self.api = GraphorLMAPI(api_token)
    
    def ingest_papers(self, paper_paths: List[str]) -> Dict[str, Any]:
        """Ingest multiple research papers"""
        for paper_path in paper_paths:
            self.api.upload_source(paper_path)
            filename = os.path.basename(paper_path)
            self.api.process_source(filename, "hi_res")
        return {"status": "success", "count": len(paper_paths)}

Migration and Versioning

API Versioning

The Graphor API follows semantic versioning principles:
  • Current Version: v1 (stable)
  • Endpoint Paths: Include version in URL structure where applicable
  • Backward Compatibility: Breaking changes will increment major version

Migration Best Practices

  • Monitor API Updates: Subscribe to API changelog notifications
  • Version Pinning: Specify API versions in your integrations
  • Gradual Migration: Test new versions in staging before production deployment
  • Fallback Strategies: Implement graceful degradation for API changes

Support and Resources

Getting Help

Community and Updates

  • Documentation Updates: This documentation is continuously updated with new features
  • API Changelog: Monitor changes and new endpoint releases
  • Best Practices: Learn from community implementations and use cases

Next Steps

Ready to start building with Graphor APIs? Choose your path:

For Beginners

For Advanced Users

The Graphor REST API provides the foundation for building intelligent, document-driven applications. With comprehensive support for advanced RAG implementations, multiple node types (chunking, retrieval, reranking, Smart RAG, Graph RAG, RAPTOR RAG, and LLM), and flexible pipeline management, these APIs give you the power and flexibility to build sophisticated AI workflows that scale from simple document search to complex research analysis systems.