Data Hub

API reference

The Data Hub REST API: authentication, scopes, every v1 endpoint grouped by resource, the MCP server, and the standard error shape.

ForDevelopers and integrators

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

MethodPathDescription
GET/instrumentsList all instruments.
POST/instrumentsCreate a new instrument.
GET/instruments/:instrumentIdGet instrument details (includes run and watcher counts).
PATCH/instruments/:instrumentIdUpdate an instrument (e.g. confirm/deactivate). Admin-only for session callers; instruments:write for bearer tokens.

Runs

MethodPathDescription
GET/instruments/:instrumentId/runsList runs for an instrument.
POST/instruments/:instrumentId/runsCreate a new run.
GET/instruments/:instrumentId/runs/:runIdGet run details.
PATCH/instruments/:instrumentId/runs/:runIdUpdate a run.
DELETE/instruments/:instrumentId/runs/:runIdSoft-delete a run.
POST/instruments/:instrumentId/runs/:runId/restoreRestore a soft-deleted run.
GET/instrument-runsList runs across all instruments.

Comments

MethodPathDescription
GET/instruments/:instrumentId/runs/:runId/commentsList active comments on a run (oldest first).
POST/instruments/:instrumentId/runs/:runId/commentsCreate a markdown comment (max 10,000 characters).
PATCH/instruments/:instrumentId/runs/:runId/comments/:commentIdEdit a comment (author only; sets edited_at).
DELETE/instruments/:instrumentId/runs/:runId/comments/:commentIdSoft-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

MethodPathDescription
POST/instruments/:instrumentId/runs/:runId/filesCreate a file record.
GET/files/:fileIdGet file details.
PATCH/files/:fileIdUpdate file metadata.
GET/files/:fileId/downloadGet a pre-signed S3 download URL.
POST/instruments/:instrumentId/runs/:runId/request-uploadRequest file upload (manual mode).
POST/instruments/:instrumentId/runs/:runId/request-upload-urlGet a pre-signed S3 upload URL.

Watchers

MethodPathDescription
GET/watchersList all watchers.
POST/watchers/registerRegister a watcher. Returns 409 CONFLICT (with error.details.existing_watcher_id) if the instrument already has an active watcher.
GET/watchers/:watcherIdGet watcher details.
DELETE/watchers/:watcherIdDeregister (soft-delete) a watcher.
POST/watchers/:watcherId/heartbeatSend a heartbeat.
GET/watchers/:watcherId/heartbeatsGet heartbeat history.
POST/watchers/:watcherId/eventsSubmit watcher events.
GET/watchers/:watcherId/configGet the synced config YAML.
PUT/watchers/:watcherId/configPush config YAML and checksum.
GET/watchers/:watcherId/config-checksumGet the config checksum.
GET/watchers/:watcherId/upload-queueGet the pending upload queue.
GET/watchers/:watcherId/update-checkServer-advertised release info (latest version, channel, mandatory flag).

Archive jobs

MethodPathDescription
GET/instruments/:instrumentId/runs/:runId/download-archiveDownload 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/:idLambda callback marking a build ready or failed.

Tokens

MethodPathDescription
GET/tokensList personal access tokens (includes each token's scopes).
POST/tokensCreate a token. Admin-only, session-only; requires a non-empty scopes array; * is rejected.
DELETE/tokens/:idRevoke a token. Admin-only; admins can revoke any user's token.

Users

MethodPathDescription
GET/usersList workspace users with their admin flag. Admin-only, session-only.
PATCH/users/:userIdToggle a user's is_admin flag. Admin-only, session-only; admins can't demote themselves.

MCP (Model Context Protocol)

MethodPathDescription
GET, POST/mcpMCP 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).

On this page