Libre Biotech

API Reference

Programmatic access to platform data via the public REST API.

Base URLs

The platform provides two API entry points:

APIBase URLDescription
Public APIhttps://librebiotech.org/api/v1/Read-only access to public content (protocols, projects, courses, discussions)
REST APIhttps://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

MethodEndpointDescription
GET/api/v1/protocolsList public protocols (paginated). Query params: page, per_page, category
GET/api/v1/protocol/{id}Get a single protocol with all versions and steps

Projects

MethodEndpointDescription
GET/api/v1/projectsList public projects (paginated)
GET/api/v1/project/{id}Get a single project with metadata

Courses

MethodEndpointDescription
GET/api/v1/coursesList courses (paginated)
GET/api/v1/course/{id}Get a single course with modules and lessons

Platform

MethodEndpointDescription
GET/api/v1/statsPlatform statistics (investigations, protocols, courses, members, groups)
GET/api/v1/contributorsFeatured contributors with profile information

Cards & Skill Files

MethodEndpointDescription
GET/api.php/v1/platform-cardPlatform skill file as JSON — live statistics, data model, all endpoints, code examples. No auth required. Cached 1 hour
GET/CLAUDE.mdPlatform 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

MethodEndpointDescription
GET/api.php/v1/investigationsList 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}/exportExport as ISA-Tab (default) or ISA-JSON. Query param: format=isajson
GET/api.php/v1/investigations/{id}/validateValidate investigation for ISA compliance. Returns isValid, completeness (0-100%), errors, warnings, and badge
GET/api.php/v1/investigations/{id}/provenanceGet investigation provenance graph (all processes, samples, and their relationships)
GET/api.php/v1/investigations/{id}/prov-oExport investigation provenance as W3C PROV-O (JSON-LD). Includes prov:Activity, prov:Entity, and prov:Agent nodes
GET/api.php/v1/investigations/{id}/ml-exportML-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}/cardInvestigation data card. Query param: format=json for JSON (default: Markdown with YAML frontmatter). Public investigations require no auth
POST/api.php/v1/investigationsCreate 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

MethodEndpointDescription
GET/api.php/v1/processesList processes (paginated)
GET/api.php/v1/processes/{id}Get process details (title, category, date, procedure, parameters)
GET/api.php/v1/processes/{id}/samplesGet all samples produced by this process
GET/api.php/v1/processes/{id}/detailsGet full process details including inputs, outputs, files, and linked people
POST/api.php/v1/processesCreate process
PUT/api.php/v1/processes/{id}Update process
DELETE/api.php/v1/processes/{id}Delete process

Samples

MethodEndpointDescription
GET/api.php/v1/samplesList samples (paginated)
GET/api.php/v1/samples/{id}Get sample details (label, organism, material type, description, annotations)
GET/api.php/v1/samples/{id}/lineageGet full sample lineage graph (ancestors and descendants with process categories)
GET/api.php/v1/samples/{id}/ancestorsGet sample ancestor chain (source materials only, walking up the lineage)
GET/api.php/v1/samples/{id}/descendantsGet all samples derived from this sample (walking down the lineage)
GET/api.php/v1/samples/{id}/prov-oExport sample provenance as W3C PROV-O (JSON-LD)
POST/api.php/v1/samplesCreate sample
PUT/api.php/v1/samples/{id}Update sample
DELETE/api.php/v1/samples/{id}Delete sample

Files

MethodEndpointDescription
GET/api.php/v1/filesList files (paginated)
GET/api.php/v1/files/{id}Get file metadata (name, size, MIME type, checksum)
POST/api.php/v1/filesUpload 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

StatusMeaning
200Success
201Created (returned after POST)
400Bad request (missing or invalid parameters). Response includes errors.missing_fields array when applicable
401Unauthorised (missing or invalid API key)
403Forbidden (valid key but insufficient permissions for this resource)
404Resource not found
429Rate limited (too many requests). Response includes Retry-After: 60 header
500Server 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)