Developer API

The MirrorHub API is a plain HTTPS/JSON interface. There is no SDK to install and no client to keep updated — every endpoint is reachable with curl, and any CI runner can call it directly.

Base URL: https://api.mirrorhub.space/v1

Authentication

Requests are authenticated with a bearer token issued per namespace. Tokens are created in the control panel or with the API itself. Read-scoped tokens are enough for CI; write-scoped tokens are required for purge and upload operations.

# Store the token as a CI secret, never in the repository
export MH_TOKEN="mhk_live_9f4c2a7be1d85c30"

# Authenticated request
curl -sS -H "Authorization: Bearer $MH_TOKEN" \
  https://api.mirrorhub.space/v1/namespaces

Tokens may be restricted by source IP range and by expiry. Rotate them from the control panel; revocation takes effect within 30 seconds across all nodes.

Pulling from a private namespace

Private mirrors use the same protocol paths as the public ones. Supply the token as the password, or as an HTTP header if your client supports it.

# APT (Debian / Ubuntu) — /etc/apt/auth.conf.d/mirrorhub.conf
machine mirrorhub.space
login mh-ci
password mhk_live_9f4c2a7be1d85c30

# Docker / OCI
echo "$MH_TOKEN" | docker login de.mirrorhub.space -u mh-ci --password-stdin
docker pull de.mirrorhub.space/acme/base-image:2026.10

# npm
npm config set //de.mirrorhub.space/npm/:_authToken "$MH_TOKEN"

# pip
pip install --index-url https://mh-ci:$MH_TOKEN@de.mirrorhub.space/pypi/simple \
  acme-internal-sdk

Endpoints

MethodPathDescription
GET/v1/namespacesList namespaces the token can access, with storage and egress counters.
GET/v1/namespaces/{ns}/usageCurrent billing-cycle egress, storage and request count.
POST/v1/namespaces/{ns}/purgeInvalidate one object, a path prefix or the whole namespace.
POST/v1/namespaces/{ns}/artifactsUpload an artifact (raw body or multipart) into a namespace.
GET/v1/namespaces/{ns}/artifactsList artifacts with sizes, checksums and last-modified timestamps.
GET/v1/tokensList tokens, their scopes and last-used time.
POST/v1/tokensCreate a scoped, optionally expiring token.
DELETE/v1/tokens/{id}Revoke a token immediately.
GET/v1/nodesPublic node status: location, uptime, throughput, sync age.

Examples

# 1. Check the current billing-cycle usage
curl -sS -H "Authorization: Bearer $MH_TOKEN" \
  https://api.mirrorhub.space/v1/namespaces/acme/usage

# 200 OK
# {
#   "namespace": "acme",
#   "period": "2026-10",
#   "egress_bytes": 4219387904,
#   "egress_limit_bytes": 21990232555520,
#   "storage_bytes": 731208654848,
#   "requests": 18422910
# }
# 2. Publish a build artifact
curl -sS -X POST \
  -H "Authorization: Bearer $MH_TOKEN" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @dist/app-2026.10.18.tar.gz \
  "https://api.mirrorhub.space/v1/namespaces/acme/artifacts?path=releases/app-2026.10.18.tar.gz"

# 201 Created
# { "path": "releases/app-2026.10.18.tar.gz",
#   "size": 48211304,
#   "sha256": "3f1c…a907",
#   "url": "https://de.mirrorhub.space/acme/releases/app-2026.10.18.tar.gz" }
# 3. Purge a stale prefix after a rebuild
curl -sS -X POST \
  -H "Authorization: Bearer $MH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"prefix":"releases/latest/"}' \
  https://api.mirrorhub.space/v1/namespaces/acme/purge

# 202 Accepted
# { "purged": 412, "nodes": ["de-fra-1","nl-ams-1","pl-waw-1","se-sto-1"] }
# 4. Create a short-lived token for a release pipeline
curl -sS -X POST \
  -H "Authorization: Bearer $MH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"release-2026.10","scopes":["read"],"expires_in":86400}' \
  https://api.mirrorhub.space/v1/tokens

Rate limits

Limits are applied per token and per namespace, and are returned in the response headers X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Bulk object downloads from the serving layer are not subject to API limits.

PlanAPI requestsConcurrent uploadsPurge requests
Free300 / min25 / hour
Team5,000 / min16unlimited
Businessfrom 50,000 / minby agreementunlimited

Errors

Errors use standard HTTP status codes and a JSON body with a machine-readable code:

# 403 Forbidden
# { "error": "token_scope_denied",
#   "message": "Token has scope 'read' but this endpoint requires 'write'." }

# 429 Too Many Requests
# { "error": "rate_limit_exceeded",
#   "message": "Namespace limit reached. Retry after 2026-10-18T14:43:00Z.",
#   "retry_after": 41 }

Webhooks

Teams on the Team and Business plans can register an HTTPS webhook to receive mirror.sync.stale, namespace.limit.warning and incident.opened events. Webhook payloads are signed with an HMAC-SHA256 header, X-MirrorHub-Signature, computed over the raw request body.

Questions about integration? The engineering team answers API questions at support@mirrorhub.space. Incidents affecting mirror freshness are announced to noc@mirrorhub.space subscribers.