API Reference
Programmatic access to platform data via the public REST API.
Base URLs
The platform provides two API entry points:
| API | Base URL | Description |
|---|---|---|
| Public API | https://librebiotech.org/api/v1/ | Read-only access to public content (protocols, projects, courses, discussions) |
| REST API | https://librebiotech.org/api.php/v1/ | Full CRUD access to investigations, processes, samples, files (requires API key) |
Authentication
Public API endpoints require no authentication. The REST API accepts API keys via the X-API-Key header:
X-API-Key: YOUR_API_KEY
Create and manage API keys from the user menu → API Keys. Each key can be named for tracking purposes and revoked individually.
Public endpoints
These endpoints are accessible without authentication and support CORS for browser-based access.
Protocols
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/protocols | List public protocols (paginated). Query params: page, per_page, category |
GET | /api/v1/protocol/{id} | Get a single protocol with all versions and steps |
Projects
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/projects | List public projects (paginated) |
GET | /api/v1/project/{id} | Get a single project with metadata |
Courses
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/courses | List courses (paginated) |
GET | /api/v1/course/{id} | Get a single course with modules and lessons |
Platform
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/stats | Platform statistics (investigations, protocols, courses, members, groups) |
GET | /api/v1/contributors | Featured contributors with profile information |
Cards & Skill Files
| Method | Endpoint | Description |
|---|---|---|
GET | /api.php/v1/platform-card | Platform skill file as JSON — live statistics, data model, all endpoints, code examples. No auth required. Cached 1 hour |
GET | /CLAUDE.md | Platform skill file as Markdown — same content as /api.php/v1/platform-card but in Markdown format. Designed for AI coding assistants |
REST API endpoints (authenticated)
These endpoints require an API key and support full CRUD operations. Base URL: /api.php/v1/
Investigations
| Method | Endpoint | Description |
|---|---|---|
GET | /api.php/v1/investigations | List investigations accessible to the authenticated user (paginated) |
GET | /api.php/v1/investigations/{id} | Get investigation details (title, description, status, visibility, dates, license) |
GET | /api.php/v1/investigations/{id}/export | Export as ISA-Tab (default) or ISA-JSON. Query param: format=isajson |
GET | /api.php/v1/investigations/{id}/validate | Validate investigation for ISA compliance. Returns isValid, completeness (0-100%), errors, warnings, and badge |
GET | /api.php/v1/investigations/{id}/provenance | Get investigation provenance graph (all processes, samples, and their relationships) |
GET | /api.php/v1/investigations/{id}/prov-o | Export investigation provenance as W3C PROV-O (JSON-LD). Includes prov:Activity, prov:Entity, and prov:Agent nodes |
GET | /api.php/v1/investigations/{id}/ml-export | ML-Ready export as flat samples × features matrix. Query params: format=csv for CSV, format=zip for ZIP bundle with README (default: JSON) |
GET | /api.php/v1/investigations/{id}/card | Investigation data card. Query param: format=json for JSON (default: Markdown with YAML frontmatter). Public investigations require no auth |
POST | /api.php/v1/investigations | Create investigation. Body: {"group_id", "title", "description"} |
PUT | /api.php/v1/investigations/{id} | Update investigation. Body: {"title", "description", "status"} |
DELETE | /api.php/v1/investigations/{id} | Delete investigation |
Processes
| Method | Endpoint | Description |
|---|---|---|
GET | /api.php/v1/processes | List processes (paginated) |
GET | /api.php/v1/processes/{id} | Get process details (title, category, date, procedure, parameters) |
GET | /api.php/v1/processes/{id}/samples | Get all samples produced by this process |
GET | /api.php/v1/processes/{id}/details | Get full process details including inputs, outputs, files, and linked people |
POST | /api.php/v1/processes | Create process |
PUT | /api.php/v1/processes/{id} | Update process |
DELETE | /api.php/v1/processes/{id} | Delete process |
Samples
| Method | Endpoint | Description |
|---|---|---|
GET | /api.php/v1/samples | List samples (paginated) |
GET | /api.php/v1/samples/{id} | Get sample details (label, organism, material type, description, annotations) |
GET | /api.php/v1/samples/{id}/lineage | Get full sample lineage graph (ancestors and descendants with process categories) |
GET | /api.php/v1/samples/{id}/ancestors | Get sample ancestor chain (source materials only, walking up the lineage) |
GET | /api.php/v1/samples/{id}/descendants | Get all samples derived from this sample (walking down the lineage) |
GET | /api.php/v1/samples/{id}/prov-o | Export sample provenance as W3C PROV-O (JSON-LD) |
POST | /api.php/v1/samples | Create sample |
PUT | /api.php/v1/samples/{id} | Update sample |
DELETE | /api.php/v1/samples/{id} | Delete sample |
Files
| Method | Endpoint | Description |
|---|---|---|
GET | /api.php/v1/files | List files (paginated) |
GET | /api.php/v1/files/{id} | Get file metadata (name, size, MIME type, checksum) |
POST | /api.php/v1/files | Upload file (multipart/form-data) |
DELETE | /api.php/v1/files/{id} | Delete file |
Response format
All REST API endpoints return JSON with a consistent envelope:
// Success
{
"success": true,
"message": "Success",
"data": { ... }
}
// Error
{
"success": false,
"error": "Error message"
}
// Paginated
{
"success": true,
"message": "Success",
"data": {
"investigations": [ ... ],
"pagination": {
"total": 45,
"page": 1,
"per_page": 25,
"total_pages": 2,
"offset": 0,
"has_more": true
}
}
}
ML-Ready export response
The /ml-export endpoint returns a different structure optimised for ML consumption. See the Data Export page or the For AI Researchers page for the full schema and code examples.
Error handling
| Status | Meaning |
|---|---|
200 | Success |
201 | Created (returned after POST) |
400 | Bad request (missing or invalid parameters). Response includes errors.missing_fields array when applicable |
401 | Unauthorised (missing or invalid API key) |
403 | Forbidden (valid key but insufficient permissions for this resource) |
404 | Resource not found |
429 | Rate limited (too many requests). Response includes Retry-After: 60 header |
500 | Server error |
CORS
Public API endpoints include CORS headers allowing browser-based access from any origin. This enables JavaScript applications to integrate with the Libre Biotech API directly.
Rate limiting
API requests are subject to rate limiting. Current limits:
- Unauthenticated: 60 requests per minute per IP
- Authenticated: 300 requests per minute per API key
When rate limited, the API returns a 429 status with a Retry-After: 60 header.
Examples
Fetch public protocols
curl https://librebiotech.org/api/v1/protocols?category=sequencing&per_page=5
# Python
import requests
response = requests.get(
"https://librebiotech.org/api/v1/protocols",
params={"category": "sequencing", "per_page": 5}
)
protocols = response.json()["data"]
for p in protocols:
print(f"{p['title']} (v{p['version']})")
Fetch investigation details (authenticated)
curl -H "X-API-Key: YOUR_KEY" \
https://librebiotech.org/api.php/v1/investigations/3
Export investigation as ISA-JSON
curl -H "X-API-Key: YOUR_KEY" -o investigation_3.json \
"https://librebiotech.org/api.php/v1/investigations/3/export?format=isajson"
Get ML-ready data
# JSON
curl -H "X-API-Key: YOUR_KEY" \
https://librebiotech.org/api.php/v1/investigations/3/ml-export
# CSV
curl -H "X-API-Key: YOUR_KEY" -o data.csv \
"https://librebiotech.org/api.php/v1/investigations/3/ml-export?format=csv"
# ZIP bundle (data + README)
curl -H "X-API-Key: YOUR_KEY" -o ml_export.zip \
"https://librebiotech.org/api.php/v1/investigations/3/ml-export?format=zip"
Get investigation data card
# Markdown (default)
curl https://librebiotech.org/api.php/v1/investigations/3/card
# JSON
curl "https://librebiotech.org/api.php/v1/investigations/3/card?format=json"
# Platform skill file
curl https://librebiotech.org/CLAUDE.md
Get sample lineage
curl -H "X-API-Key: YOUR_KEY" \
https://librebiotech.org/api.php/v1/samples/42/lineage
Export provenance as PROV-O
# Investigation-level
curl -H "X-API-Key: YOUR_KEY" \
https://librebiotech.org/api.php/v1/investigations/3/prov-o
# Sample-level
curl -H "X-API-Key: YOUR_KEY" \
https://librebiotech.org/api.php/v1/samples/42/prov-o
Python: fetch samples with annotations
import requests
API = "https://librebiotech.org/api.php/v1"
headers = {"X-API-Key": "YOUR_KEY"}
# List samples
resp = requests.get(f"{API}/samples", headers=headers, params={"per_page": 50})
samples = resp.json()["data"]["samples"]
# Get details + annotations for each
for s in samples[:5]:
detail = requests.get(f"{API}/samples/{s['id']}", headers=headers).json()["data"]
print(f"{detail['label']}: {detail.get('organism', 'N/A')}")
R: load ML-ready data into a tibble
library(httr)
library(jsonlite)
library(tibble)
api <- "https://librebiotech.org/api.php/v1"
key <- "YOUR_KEY"
resp <- GET(paste0(api, "/investigations/3/ml-export"),
add_headers("X-API-Key" = key))
data <- fromJSON(content(resp, "text", encoding = "UTF-8"))
df <- as_tibble(data$rows)
colnames(df) <- sapply(data$columns, function(c) c$name)
print(df)