API reference
The Data Hub REST API: authentication, scopes, every v1 endpoint grouped by resource, the MCP server, and the standard error shape.
The Data Hub API is served by the web application at /api/v1/. It's used by the
watcher, the Lambda, Model Context Protocol (MCP) clients, and the web dashboard.
Data Hub is self-hosted, so the base URL is your own deployment's host followed by
/api/v1. The examples below use https://datahub.example.com; substitute your host.
Authentication
Two methods (see Security & permissions for the full model):
- Session cookies: the web dashboard (Google OAuth). Session callers implicitly hold every scope.
- Bearer tokens:
Authorization: Bearer dhub_…, used by the watcher, Lambda, and MCP clients.
curl https://datahub.example.com/api/v1/instruments \
-H "Authorization: Bearer dhub_your_token_here"Token-authenticated requests are gated on scopes: a
request missing the route's required scope is rejected with 403 FORBIDDEN. Some
mutations additionally require the admin role; see
Admin-gated operations.
Endpoints
Instruments
| Method | Path | Description |
|---|---|---|
GET | /instruments | List all instruments. |
POST | /instruments | Create a new instrument. |
GET | /instruments/:instrumentId | Get instrument details (includes run and watcher counts). |
PATCH | /instruments/:instrumentId | Update an instrument (e.g. confirm/deactivate). Admin-only for session callers; instruments:write for bearer tokens. |
Runs
| Method | Path | Description |
|---|---|---|
GET | /instruments/:instrumentId/runs | List runs for an instrument. |
POST | /instruments/:instrumentId/runs | Create a new run. |
GET | /instruments/:instrumentId/runs/:runId | Get run details. |
PATCH | /instruments/:instrumentId/runs/:runId | Update a run. |
DELETE | /instruments/:instrumentId/runs/:runId | Soft-delete a run. |
POST | /instruments/:instrumentId/runs/:runId/restore | Restore a soft-deleted run. |
GET | /instrument-runs | List runs across all instruments. |
Comments
| Method | Path | Description |
|---|---|---|
GET | /instruments/:instrumentId/runs/:runId/comments | List active comments on a run (oldest first). |
POST | /instruments/:instrumentId/runs/:runId/comments | Create a markdown comment (max 10,000 characters). |
PATCH | /instruments/:instrumentId/runs/:runId/comments/:commentId | Edit a comment (author only; sets edited_at). |
DELETE | /instruments/:instrumentId/runs/:runId/comments/:commentId | Soft-delete a comment (author only). |
Cross-user edit/delete returns 403 FORBIDDEN; mutating a comment whose parent run
is soft-deleted returns 409 CONFLICT.
Files
| Method | Path | Description |
|---|---|---|
POST | /instruments/:instrumentId/runs/:runId/files | Create a file record. |
GET | /files/:fileId | Get file details. |
PATCH | /files/:fileId | Update file metadata. |
GET | /files/:fileId/download | Get a pre-signed S3 download URL. |
POST | /instruments/:instrumentId/runs/:runId/request-upload | Request file upload (manual mode). |
POST | /instruments/:instrumentId/runs/:runId/request-upload-url | Get a pre-signed S3 upload URL. |
Watchers
| Method | Path | Description |
|---|---|---|
GET | /watchers | List all watchers. |
POST | /watchers/register | Register a watcher. Returns 409 CONFLICT (with error.details.existing_watcher_id) if the instrument already has an active watcher. |
GET | /watchers/:watcherId | Get watcher details. |
DELETE | /watchers/:watcherId | Deregister (soft-delete) a watcher. |
POST | /watchers/:watcherId/heartbeat | Send a heartbeat. |
GET | /watchers/:watcherId/heartbeats | Get heartbeat history. |
POST | /watchers/:watcherId/events | Submit watcher events. |
GET | /watchers/:watcherId/config | Get the synced config YAML. |
PUT | /watchers/:watcherId/config | Push config YAML and checksum. |
GET | /watchers/:watcherId/config-checksum | Get the config checksum. |
GET | /watchers/:watcherId/upload-queue | Get the pending upload queue. |
GET | /watchers/:watcherId/update-check | Server-advertised release info (latest version, channel, mandatory flag). |
Archive jobs
| Method | Path | Description |
|---|---|---|
GET | /instruments/:instrumentId/runs/:runId/download-archive | Download the run archive. Cache hit → 302 to a presigned S3 URL (or 200 {status:"ready", download_url, size_bytes} with Accept: application/json). Cache miss → 202 {status:"building", job_id} and an async build; re-issue the same URL to poll. ?file_ids=1,2,3 narrows to a subset. |
PATCH | /archive-jobs/:id | Lambda callback marking a build ready or failed. |
Tokens
| Method | Path | Description |
|---|---|---|
GET | /tokens | List personal access tokens (includes each token's scopes). |
POST | /tokens | Create a token. Admin-only, session-only; requires a non-empty scopes array; * is rejected. |
DELETE | /tokens/:id | Revoke a token. Admin-only; admins can revoke any user's token. |
Users
| Method | Path | Description |
|---|---|---|
GET | /users | List workspace users with their admin flag. Admin-only, session-only. |
PATCH | /users/:userId | Toggle a user's is_admin flag. Admin-only, session-only; admins can't demote themselves. |
MCP (Model Context Protocol)
| Method | Path | Description |
|---|---|---|
GET, POST | /mcp | MCP server endpoint (Streamable HTTP transport). |
The MCP server exposes Data Hub to AI clients (Claude Desktop, Cursor, and any
compliant client) using Bearer tokens only; session cookies aren't supported.
Tools enforce the same scopes as their REST counterparts. Key tools include
list_instruments, search_runs, get_run, list_run_files, get_run_archive,
get_file_download_url, reprocess_file, claim_run/unclaim_run,
get_system_status, and list_watchers. There are also resources
(datahub://instruments, filter options) and prompts (daily_summary,
troubleshoot_instrument, compare_runs).
For configuration and the full tool/resource/prompt catalog, see the MCP server reference, and Managing tokens → With an MCP client for client setup.
Error responses
Errors follow a consistent shape:
{
"code": "NOT_FOUND",
"message": "Instrument not found.",
"details": null
}Scope failures use code: "FORBIDDEN" with a message naming the missing scope.
Common codes: VALIDATION_ERROR (400), UNAUTHORIZED (401), FORBIDDEN (403),
NOT_FOUND (404), CONFLICT (409).
Watcher configuration
Every config.yaml field, the ~/.data-hub file layout, environment variables, run-detection presets, upload modes, and the initial-scan behavior.
MCP server
Query instruments, runs, files, and watcher data from AI clients like Claude Desktop and Cursor through the Data Hub Model Context Protocol server.