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
/api/v1/projects/createCreate 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_urlArXiv 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_fileBase64-encoded PDF file content. Either arxiv_url or pdf_file is required.
pdf_filenameFilename for the PDF (required when pdf_file is provided).
instructionCustom instructions for the AI to guide the visualization generation (max 10,000 characters).
imagesArray of image attachments (max 8). Each image: { data: "base64...", mimeType: "image/png", filename?: "chart.png" }
modelModel ID to use for generation. Defaults to gemini-3-pro-preview. See /api/models for available models.
model_configModel configuration: { temperature?: 0-2, topP?: 0-1, topK?: number, maxTokens?: number }
templateTemplate 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
{
"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
/api/v1/projects/createGet Project Status
/api/v1/projects/:project_id/statusGet 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_idThe 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
{
"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
/api/v1/projects/:project_id/statusContinue Project
/api/v1/projects/:project_id/continueContinue 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_idThe unique identifier of the project to continue (path parameter)
instructionNew instructions for the AI to modify or enhance the visualization (max 10,000 characters).
imagesArray of image attachments (max 8). Each image: { data: "base64...", mimeType: "image/png", filename?: "chart.png" }
modelModel ID to use for generation. Uses same model as project creation if not specified.
model_configModel 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
{
"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
/api/v1/projects/:project_id/continueList Projects
/api/projectsList 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
{
"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
/api/projectsGet Project
/api/projects/:project_idGet a specific project
Retrieves detailed information about a specific project, including the generated code, fragment data, and conversation history.
Parameters
project_idThe unique identifier of the project
Request
curl -X GET "https://explorableresearch.com/api/projects/abc123" \
-H "x-api-key: YOUR_API_KEY"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
/api/projects/:project_idDelete Project
/api/projects/:project_idDelete a project
Permanently deletes a project and its associated sandbox. This action cannot be undone.
Parameters
project_idThe 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
// Returns 204 No Content on successTry it out
/api/projects/:project_idCode 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}`);