Developers
Moonbase API
Programmatic access to published MoonScore reports. Build internal dashboards, embed scores in your CRM, or wire alerts into Slack.
Generate keys from Settings → API keys. Each key has its own rate limit. Sandbox keys return fixture data.
REST under /v1, GraphQL at /v1/graphql. Try it in the playground.
Subscribe to report.completed, score.changed, alert.fired, and more. HMAC-SHA256 signed.
Authentication
All requests require a bearer token in the Authorization header.
curl -H "Authorization: Bearer mb_live_…" \ https://base.moonrig.io/api/public/v1/reports/your-slug
Scopes
Each key is created with one or more scopes. Calling an endpoint without its scope returns 403. Keys created before scopes were selectable have read only.
| Endpoint | Scope |
|---|---|
GET /v1/reports/:slug | read |
GET /v1/search | read |
POST /v1/graphql | read |
POST /v1/submissions | write |
POST /v1/submissions/:id/documents | write |
GET /v1/reports/:slug
Fetch a single published report by slug.
GET https://base.moonrig.io/api/public/v1/reports/acme-protocol Authorization: Bearer mb_live_…
Example response
{
"slug": "acme-protocol",
"name": "Acme Protocol",
"industry": "Web3",
"stage": "Series A",
"geography": "Singapore",
"score": {
"overall": 78.4,
"band": "Moderate",
"pillars": [ { "name": "Team", "score": 82, "weight": 0.15 }, ... ],
"strengths": [ ... ],
"risks": [ ... ],
"scored_at": "2026-05-12T08:11:00Z"
},
"verification": {
"verified_score": 76.0,
"verdict": "confirmed",
"signed_at": "2026-05-18T14:22:00Z"
},
"report_url": "https://base.moonrig.io/r/acme-protocol"
}POST /v1/graphql
Single endpoint, typed schema. Open the playground to try it live.
curl -X POST -H "Authorization: Bearer mb_live_…" -H "Content-Type: application/json" \
https://base.moonrig.io/api/public/v1/graphql -d '{"query":"{ me { sandbox } search(industry:\"Web3\",limit:3){ slug score } }"}'GET /v1/search
Search published reports with optional filters. q accepts only letters, numbers, spaces and hyphens, up to 120 characters; anything else returns 400. The GraphQL search(q:) argument follows the same rule.
GET https://base.moonrig.io/api/public/v1/search?q=defi&industry=Web3&min_score=65&limit=20 Authorization: Bearer mb_live_…
| Parameter | Type | Description |
|---|---|---|
q | string | Free-text query across name, description, industry |
industry | string | Exact match |
stage | string | Exact match |
min_score | number | Filter to scores ≥ value |
limit | int (max 50) | Default 20 |
Errors
401— Missing, invalid, or revoked key404— Slug not found or not published429— Rate limit exceeded for this key5xx— Server error; safe to retry
