Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/bio-xyz/BioAgents/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Paper Retrieval API provides access to previously generated research papers. Use this to retrieve papers, get fresh download URLs, and list all papers for a conversation.
This API is for retrieving existing papers. To generate new papers, see Paper Generation API.

Authentication

All endpoints require authentication via:
  • JWT token in Authorization header
  • API key in X-API-Key header
  • x402/b402 payment proof

URL Expiration

Presigned URLs expire after 1 hour. Always request fresh URLs when downloading papers:
  • ✅ Request URL → Download immediately
  • ✅ Request URL → Download within 1 hour
  • ❌ Cache URL → Download later (will fail after 1 hour)

Endpoints

Get Paper

GET /api/deep-research/paper/:paperId
endpoint
Get fresh presigned URLs for a paper
Path Parameters
paperId
string
required
Paper ID (UUID returned from generation)
Response
{
  "success": true,
  "paperId": "550e8400-e29b-41d4-a716-446655440000",
  "conversationId": "660e8400-e29b-41d4-a716-446655440000",
  "pdfPath": "user/USER_ID/conversation/CONV_ID/papers/PAPER_ID/paper.pdf",
  "pdfUrl": "https://s3.amazonaws.com/bucket/path?X-Amz-Signature=...",
  "rawLatexUrl": "https://s3.amazonaws.com/bucket/path/main.tex?X-Amz-Signature=...",
  "createdAt": "2024-01-01T12:00:00Z"
}
paperId
string
Unique paper identifier
conversationId
string
Source conversation ID
pdfPath
string
S3 storage path (for reference)
pdfUrl
string
Presigned URL for PDF download (expires in 1 hour)
rawLatexUrl
string
Presigned URL for LaTeX source (may be null for older papers)
createdAt
string
Paper creation timestamp (ISO 8601)
cURL Example
curl -X GET https://api.bioagents.ai/api/deep-research/paper/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
Download Example
# Get paper URLs
RESPONSE=$(curl -s -X GET \
  https://api.bioagents.ai/api/deep-research/paper/$PAPER_ID \
  -H "Authorization: Bearer $JWT_TOKEN")

# Extract URLs
PDF_URL=$(echo $RESPONSE | jq -r '.pdfUrl')
LATEX_URL=$(echo $RESPONSE | jq -r '.rawLatexUrl')

# Download files
curl -o paper.pdf "$PDF_URL"
curl -o main.tex "$LATEX_URL"

List Papers

GET /api/deep-research/conversations/:conversationId/papers
endpoint
List all papers for a conversation
Path Parameters
conversationId
string
required
Conversation ID to list papers for
Response
{
  "success": true,
  "conversationId": "660e8400-e29b-41d4-a716-446655440000",
  "papers": [
    {
      "paperId": "550e8400-e29b-41d4-a716-446655440000",
      "pdfPath": "user/.../papers/.../paper.pdf",
      "status": "completed",
      "createdAt": "2024-01-01T12:00:00Z"
    },
    {
      "paperId": "660e8400-e29b-41d4-a716-446655440001",
      "pdfPath": "user/.../papers/.../paper.pdf",
      "status": "completed",
      "createdAt": "2024-01-01T11:00:00Z"
    }
  ]
}
papers
array
Array of paper metadata objects, sorted by creation date (newest first)
papers[].paperId
string
Paper unique identifier
papers[].pdfPath
string
S3 storage path
papers[].status
string
Paper status: pending, processing, completed, or failed
papers[].createdAt
string
Creation timestamp (ISO 8601)
cURL Example
curl -X GET https://api.bioagents.ai/api/deep-research/conversations/CONVERSATION_ID/papers \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
Download All Papers Example
# Get paper list
RESPONSE=$(curl -s -X GET \
  https://api.bioagents.ai/api/deep-research/conversations/$CONVERSATION_ID/papers \
  -H "Authorization: Bearer $JWT_TOKEN")

# Extract paper IDs
echo $RESPONSE | jq -r '.papers[].paperId' | while read PAPER_ID; do
  # Get fresh URLs for each paper
  PAPER=$(curl -s https://api.bioagents.ai/api/deep-research/paper/$PAPER_ID \
    -H "Authorization: Bearer $JWT_TOKEN")
  
  # Download PDF
  PDF_URL=$(echo $PAPER | jq -r '.pdfUrl')
  curl -o "paper_${PAPER_ID}.pdf" "$PDF_URL"
  
  echo "Downloaded: paper_${PAPER_ID}.pdf"
done

Check Paper Status

GET /api/deep-research/paper/:paperId/status
endpoint
Check paper generation status (for async jobs)
See Paper Generation API for details.

Error Responses

401 Unauthorized

{
  "error": "Authentication required",
  "message": "Valid authentication is required to access papers"
}

403 Forbidden

{
  "error": "Access denied",
  "message": "You do not have permission to access this paper"
}
This occurs when attempting to access another user’s paper.

404 Not Found (Paper)

{
  "error": "Paper not found",
  "message": "Paper with id 550e8400-e29b-41d4-a716-446655440000 not found"
}

404 Not Found (Conversation)

{
  "error": "Conversation not found",
  "message": "Conversation with id 660e8400-e29b-41d4-a716-446655440000 not found"
}

500 Internal Server Error

{
  "error": "Failed to get paper",
  "message": "Storage provider unavailable"
}

503 Service Unavailable

{
  "error": "Storage unavailable",
  "message": "Storage provider is not configured"
}

Paper Metadata

Each paper includes:

File Structure

user/{userId}/conversation/{conversationId}/papers/{paperId}/
  ├── paper.pdf         # Compiled PDF
  ├── main.tex          # LaTeX source
  └── figures/          # Embedded figures (if any)
      ├── figure1.png
      └── figure2.png

Paper Contents

  • Title: Derived from research objective
  • Abstract: Summary of findings
  • Sections: Introduction, Methods, Results, Discussion, Conclusion
  • References: All cited papers with DOIs
  • Figures: Analysis artifacts with captions

Integration Examples

JavaScript/TypeScript

interface Paper {
  paperId: string;
  conversationId: string;
  pdfUrl: string;
  rawLatexUrl?: string;
  createdAt: string;
}

async function getPaper(paperId: string, token: string): Promise<Paper> {
  const response = await fetch(
    `https://api.bioagents.ai/api/deep-research/paper/${paperId}`,
    { headers: { Authorization: `Bearer ${token}` } }
  );
  
  if (!response.ok) {
    throw new Error(`Failed to get paper: ${response.statusText}`);
  }
  
  return response.json();
}

async function downloadPaper(paperId: string, token: string): Promise<Blob> {
  const paper = await getPaper(paperId, token);
  const response = await fetch(paper.pdfUrl);
  return response.blob();
}

// Usage
const paper = await getPaper('550e8400-e29b-41d4-a716-446655440000', token);
const blob = await downloadPaper(paper.paperId, token);

// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'research-paper.pdf';
a.click();
URL.revokeObjectURL(url);

Python

import requests
import json
from typing import Dict, List

class PaperClient:
    def __init__(self, base_url: str, token: str):
        self.base_url = base_url
        self.headers = {"Authorization": f"Bearer {token}"}
    
    def get_paper(self, paper_id: str) -> Dict:
        """Get paper metadata with fresh URLs"""
        response = requests.get(
            f"{self.base_url}/api/deep-research/paper/{paper_id}",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()
    
    def list_papers(self, conversation_id: str) -> List[Dict]:
        """List all papers for a conversation"""
        response = requests.get(
            f"{self.base_url}/api/deep-research/conversations/{conversation_id}/papers",
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()["papers"]
    
    def download_paper(self, paper_id: str, output_path: str):
        """Download paper PDF"""
        paper = self.get_paper(paper_id)
        
        # Download from presigned URL
        response = requests.get(paper["pdfUrl"])
        response.raise_for_status()
        
        with open(output_path, "wb") as f:
            f.write(response.content)
        
        print(f"Downloaded: {output_path}")

# Usage
client = PaperClient("https://api.bioagents.ai", token)
papers = client.list_papers(conversation_id)

for paper in papers:
    if paper["status"] == "completed":
        client.download_paper(paper["paperId"], f"paper_{paper['paperId']}.pdf")

Best Practices

1. Always Request Fresh URLs

Don’t cache presigned URLs for more than a few minutes:
// ❌ Bad: Cache URL for long-term use
const paper = await getPaper(paperId);
localStorage.setItem('pdfUrl', paper.pdfUrl); // Will expire!

// ✅ Good: Request fresh URL when needed
async function downloadWhenNeeded(paperId) {
  const paper = await getPaper(paperId);
  return fetch(paper.pdfUrl);
}

2. Handle Missing LaTeX Sources

Older papers may not have LaTeX sources:
const paper = await getPaper(paperId);

if (paper.rawLatexUrl) {
  // Download LaTeX source
  const latex = await fetch(paper.rawLatexUrl);
} else {
  console.log('LaTeX source not available for this paper');
}

3. Verify Paper Status Before Download

const papers = await listPapers(conversationId);

for (const paper of papers) {
  if (paper.status === 'completed') {
    await downloadPaper(paper.paperId);
  } else if (paper.status === 'failed') {
    console.error(`Paper ${paper.paperId} generation failed`);
  } else {
    console.log(`Paper ${paper.paperId} is ${paper.status}`);
  }
}