Projects API

Create, list, and manage your explorable projects programmatically.

Synchronous Processing

The Create and Continue endpoints are synchronous - they wait for AI generation to complete before returning. Responses include the full project data with preview URL and generated code. Typical response time is 30-120 seconds depending on the complexity of the paper.

Create Project

POST
/api/v1/projects/create

Create a new project from a research paper

Creates a new interactive explorable from an ArXiv paper or uploaded PDF. This endpoint waits for AI generation to complete (up to 5 minutes) and returns the full project data including preview URL and generated code.

Parameters

arxiv_url
string

ArXiv paper URL (e.g., https://arxiv.org/abs/2301.00001 or https://arxiv.org/html/2301.00001). HTML URLs extract paper figures for richer AI context. Either arxiv_url or pdf_file is required.

pdf_file
string

Base64-encoded PDF file content. Either arxiv_url or pdf_file is required.

pdf_filename
string

Filename for the PDF (required when pdf_file is provided).

instruction
string

Custom instructions for the AI to guide the visualization generation (max 10,000 characters).

images
array

Array of image attachments (max 8). Each image: { data: "base64...", mimeType: "image/png", filename?: "chart.png" }

model
string

Model ID to use for generation. Defaults to gemini-3-pro-preview. See /api/models for available models.

model_config
object

Model configuration: { temperature?: 0-2, topP?: 0-1, topK?: number, maxTokens?: number }

template
string

Template to use: "explorable-research-developer" (default, React+Vite) or "html-developer" (static HTML)

Request

curl -X POST "https://explorableresearch.com/api/v1/projects/create" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "arxiv_url": "https://arxiv.org/abs/2301.00001",
    "instruction": "Focus on visualizing the key algorithm"
  }'

Response

Response (200 OK)
{
  "success": true,
  "project": {
    "id": "abc123",
    "status": "ready",
    "title": "Gradient Descent Visualization",
    "description": "Interactive visualization of gradient descent...",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:31:30Z",
    "preview_url": "https://sandbox.e2b.dev/...",
    "sandbox_id": "sbx-abc123",
    "template": "explorable-research-developer",
    "code": "import React from 'react';..."
  }
}

Try it out

Sign in to use the interactive API playground
POST
/api/v1/projects/create

Get Project Status

GET
/api/v1/projects/:project_id/status

Get current project status and data

Returns the current status and data of a project. Useful for checking project details without fetching the full conversation history.

Parameters

project_id
Required
string

The unique identifier of the project

Request

curl -X GET "https://explorableresearch.com/api/v1/projects/abc123/status" \
  -H "x-api-key: YOUR_API_KEY"

Response

Response
{
  "success": true,
  "project": {
    "id": "abc123",
    "status": "ready",
    "title": "Gradient Descent Visualization",
    "description": "Interactive visualization...",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:31:00Z",
    "preview_url": "https://sandbox.e2b.dev/...",
    "sandbox_id": "sbx-abc123",
    "template": "explorable-research-developer",
    "code": "import React from 'react';..."
  }
}

Try it out

Sign in to use the interactive API playground
GET
/api/v1/projects/:project_id/status

Continue Project

POST
/api/v1/projects/:project_id/continue

Continue an existing project with new instructions

Adds new instructions to an existing project and regenerates the visualization. This endpoint waits for AI generation to complete and returns the updated project data. The project must be in 'ready' status to continue.

Parameters

project_id
Required
string

The unique identifier of the project to continue (path parameter)

instruction
Required
string

New instructions for the AI to modify or enhance the visualization (max 10,000 characters).

images
array

Array of image attachments (max 8). Each image: { data: "base64...", mimeType: "image/png", filename?: "chart.png" }

model
string

Model ID to use for generation. Uses same model as project creation if not specified.

model_config
object

Model configuration: { temperature?: 0-2, topP?: 0-1, topK?: number, maxTokens?: number }

Request

curl -X POST "https://explorableresearch.com/api/v1/projects/abc123/continue" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "Add a slider to control the learning rate"
  }'

Response

Response (200 OK)
{
  "success": true,
  "project": {
    "id": "abc123",
    "status": "ready",
    "title": "Gradient Descent Visualization",
    "description": "Interactive visualization with controls...",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T11:46:30Z",
    "preview_url": "https://sandbox.e2b.dev/...",
    "sandbox_id": "sbx-abc123",
    "template": "explorable-research-developer",
    "code": "import React from 'react';..."
  }
}

Try it out

Sign in to use the interactive API playground
POST
/api/v1/projects/:project_id/continue

List Projects

GET
/api/projects

List all projects

Returns a list of all projects owned by the authenticated user, sorted by creation date (newest first).

Request

curl -X GET "https://explorableresearch.com/api/projects" \
  -H "x-api-key: YOUR_API_KEY"

Response

Response
{
  "projects": [
    {
      "id": "abc123",
      "title": "Gradient Descent Visualization",
      "description": "Interactive visualization of gradient descent...",
      "status": "ready",
      "created_at": "2024-01-15T10:30:00Z",
      "result": {
        "url": "https://sandbox.e2b.dev/...",
        "sbxId": "sandbox-id"
      }
    },
    {
      "id": "def456",
      "title": "Neural Network Explorer",
      "description": "Interactive neural network architecture...",
      "status": "ready",
      "created_at": "2024-01-14T15:45:00Z",
      "result": {
        "url": "https://sandbox.e2b.dev/...",
        "sbxId": "sandbox-id"
      }
    }
  ]
}

Try it out

Sign in to use the interactive API playground
GET
/api/projects

Get Project

GET
/api/projects/:project_id

Get a specific project

Retrieves detailed information about a specific project, including the generated code, fragment data, and conversation history.

Parameters

project_id
Required
string

The unique identifier of the project

Request

curl -X GET "https://explorableresearch.com/api/projects/abc123" \
  -H "x-api-key: YOUR_API_KEY"

Response

Response
{
  "project": {
    "id": "abc123",
    "title": "Gradient Descent Visualization",
    "description": "Interactive visualization of gradient descent...",
    "status": "ready",
    "created_at": "2024-01-15T10:30:00Z",
    "fragment": {
      "title": "Gradient Descent Visualization",
      "description": "...",
      "code": "import React from 'react';...",
      "file_path": "src/App.tsx",
      "template": "explorable-research-developer"
    },
    "result": {
      "url": "https://sandbox.e2b.dev/...",
      "sbxId": "sandbox-id"
    },
    "messages": [
      {
        "role": "user",
        "content": [{"type": "text", "text": "Create a gradient descent visualization..."}]
      },
      {
        "role": "assistant",
        "content": [{"type": "text", "text": "I'll create an interactive..."}]
      }
    ]
  }
}

Try it out

Sign in to use the interactive API playground
GET
/api/projects/:project_id

Delete Project

DELETE
/api/projects/:project_id

Delete a project

Permanently deletes a project and its associated sandbox. This action cannot be undone.

Parameters

project_id
Required
string

The unique identifier of the project to delete

Request

curl -X DELETE "https://explorableresearch.com/api/projects/abc123" \
  -H "x-api-key: YOUR_API_KEY"

Response

Success Response
// Returns 204 No Content on success

Try it out

Sign in to use the interactive API playground
DELETE
/api/projects/:project_id

Code Examples

Python

import requests
import base64

API_KEY = "your_api_key_here"
BASE_URL = "https://explorableresearch.com"

headers = {
    "x-api-key": API_KEY,
    "Content-Type": "application/json"
}

# Create a project from an ArXiv paper (synchronous - waits for completion)
response = requests.post(
    f"{BASE_URL}/api/v1/projects/create",
    headers=headers,
    json={
        "arxiv_url": "https://arxiv.org/abs/2301.00001",
        "instruction": "Focus on visualizing the key algorithm"
    },
    timeout=300  # 5 minute timeout for AI generation
)
project = response.json()["project"]
print(f"Created project: {project['id']}")
print(f"Preview URL: {project['preview_url']}")

# Get full project details including code
response = requests.get(
    f"{BASE_URL}/api/projects/{project['id']}",
    headers=headers
)
full_project = response.json()["project"]
print(f"Code: {full_project['fragment']['code'][:100]}...")

# Continue the project with new instructions (synchronous)
response = requests.post(
    f"{BASE_URL}/api/v1/projects/{project['id']}/continue",
    headers=headers,
    json={"instruction": "Add a slider to control parameters"},
    timeout=300
)
updated_project = response.json()["project"]
print(f"Updated preview: {updated_project['preview_url']}")

# Create from local PDF
with open("paper.pdf", "rb") as f:
    pdf_base64 = base64.b64encode(f.read()).decode()

response = requests.post(
    f"{BASE_URL}/api/v1/projects/create",
    headers=headers,
    json={
        "pdf_file": pdf_base64,
        "pdf_filename": "paper.pdf",
        "template": "html-developer",  # Use static HTML template
        "instruction": "Create an interactive explanation"
    },
    timeout=300
)
html_project = response.json()["project"]
print(f"HTML project: {html_project['preview_url']}")

JavaScript / TypeScript

const API_KEY = "your_api_key_here";
const BASE_URL = "https://explorableresearch.com";

const headers = {
  "x-api-key": API_KEY,
  "Content-Type": "application/json",
};

// Create a project from an ArXiv paper (synchronous)
async function createFromArxiv(arxivUrl: string, instruction?: string) {
  const response = await fetch(`${BASE_URL}/api/v1/projects/create`, {
    method: "POST",
    headers,
    body: JSON.stringify({ arxiv_url: arxivUrl, instruction }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error?.message || "Failed to create project");
  }

  const { project } = await response.json();
  console.log(`Created project: ${project.id}`);
  console.log(`Preview: ${project.preview_url}`);
  return project;
}

// Get full project details
async function getProject(projectId: string) {
  const response = await fetch(`${BASE_URL}/api/projects/${projectId}`, {
    headers: { "x-api-key": API_KEY },
  });
  return response.json();
}

// Continue an existing project (synchronous)
async function continueProject(projectId: string, instruction: string) {
  const response = await fetch(
    `${BASE_URL}/api/v1/projects/${projectId}/continue`,
    {
      method: "POST",
      headers,
      body: JSON.stringify({ instruction }),
    }
  );

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error?.message || "Failed to continue project");
  }

  return response.json();
}

// List all projects
async function listProjects() {
  const response = await fetch(`${BASE_URL}/api/projects`, {
    headers: { "x-api-key": API_KEY },
  });
  return response.json();
}

// Example usage
const project = await createFromArxiv(
  "https://arxiv.org/abs/1706.03762",
  "Visualize the Transformer attention mechanism"
);

const updated = await continueProject(
  project.id,
  "Add an interactive slider to control the number of attention heads"
);
console.log(`Updated: ${updated.project.preview_url}`);