NuMoon / Developers
Developer API · v1 · read-only by design

Build on NuMoon.

Programmatic read access to your growth intelligence. The same reconciled numbers, ranked findings, and proposed moves the brain shows in your cockpit — over plain REST, with one Bearer header.

v1 at a glanceREST + JSONBearer nmk_ keysRead-onlyStrict tenant isolation/api/v1 path-versioned

Authentication: one key, one header.

Native tenant API keys, scoped to exactly what a key should be able to do — and nothing it shouldn’t.

Create

Keys live in the dashboard

Open Settings → API keys in the NuMoon app and create a key. The full key — prefixed nmk_ — is shown exactly once, at creation. NuMoon persists only a SHA-256 digest and the last four characters; the plaintext is never stored and never appears in logs. Lose it, and you revoke and re-create — by design.

Read-only

v1 keys cannot write. On purpose.

Every v1 key is read-only. Anything that changes the world — pausing a campaign, sending an email, moving money — only ships through the in-app action workflow, where a human reviews and approves each move. Your API key can leak, sit in a CI log, or end up in a notebook and still never touch your accounts. That’s the same approval-gated write model the whole product is built on, extended to the API.

Revoke

Revocation is instant and loud

Revoked or expired keys get a 401with a distinct machine-readable error code — your client can tell “bad key” from “revoked key” and react accordingly. Keys resolve to exactly one workspace; cross-tenant access is structurally impossible.

Every request carries one header. Logging into the NuMoon app itself is separate — that’s a separate session-based login; API keys never grant dashboard access.

GET/api/v1/dashboard/summaryrequest
curl https://api.numoon.ai/api/v1/dashboard/summary \
  -H "Authorization: Bearer nmk_xxxxxxxxxxxxxxxxxxxxxxxx"

Quickstart: three calls, whole picture.

Real endpoints, real shapes. Set NUMOON_API_KEY and paste.

Your business, one object

The same reconciled snapshot the cockpit renders: revenue, expenses, net income, cash, and per-department health scores. Optional KPI cards (runway, CAC, LTV, ROAS) appear as data sources come online — absent ones are null, not missing.

GET/api/v1/dashboard/summaryrequest
curl https://api.numoon.ai/api/v1/dashboard/summary \
  -H "Authorization: Bearer $NUMOON_API_KEY"
GET/api/v1/dashboard/summary200 OK
{
  "total_revenue": {
    "label": "Total Revenue",
    "value": 48210.55,
    "formatted_value": "$48,210.55",
    "change_percent": 12.4,
    "change_direction": "up",
    "trend_data": [38200.1, 41080.9, 44512.3, 48210.55],
    "period": "month"
  },
  "total_expenses": { "label": "Total Expenses", "value": 21940.12, "formatted_value": "$21,940.12", "change_percent": 3.1, "change_direction": "up", "trend_data": null, "period": "month" },
  "net_income": { "label": "Net Income", "value": 26270.43, "formatted_value": "$26,270.43", "change_percent": 21.7, "change_direction": "up", "trend_data": null, "period": "month" },
  "cash_balance": { "label": "Cash Balance", "value": 112400.0, "formatted_value": "$112,400.00", "change_percent": null, "change_direction": null, "trend_data": null, "period": "month" },
  "runway_months": null,
  "revenue_growth": null,
  "customer_growth": null,
  "cac": null,
  "ltv": null,
  "roas": null,
  "health_scores": [
    { "category": "marketing", "score": 72, "status": "good", "trend": "improving", "details": null },
    { "category": "finance", "score": 81, "status": "excellent", "trend": "stable", "details": null }
  ],
  "trends": null,
  "data_freshness": "2026-06-09T18:40:00Z",
  "connected_integrations": 6,
  "status": "active",
  "message": null,
  "demo_mode": false
}

Findings, ranked

Every finding the brain has surfaced for your workspace, filterable by category, priority, status_filter, and unread_only. Paginate with limit (1–500, default 100) and offset.

GET/api/v1/insights/request
curl "https://api.numoon.ai/api/v1/insights/?priority=high&limit=1" \
  -H "Authorization: Bearer $NUMOON_API_KEY"
GET/api/v1/insights/200 OK
[
  {
    "id": "0d9f3a6e-8c41-4f2a-b7d3-2e1a9c5b8f10",
    "tenant_id": "7c2e4b9a-1f3d-4e8c-a6b5-9d0c2f4e6a81",
    "title": "Meta-reported ROAS is running 2.0x above bank-settled ROAS",
    "summary": "Meta attributes $9,820 more revenue this month than cleared your bank after refunds and disputes.",
    "detail": "Cross-referenced Meta Ads reporting against Stripe payouts over the last 30 days…",
    "category": "marketing",
    "priority": "high",
    "impact_score": 86,
    "confidence_score": 74,
    "audience": "all",
    "data_sources": ["meta_ads", "stripe"],
    "status": "active",
    "is_read": false,
    "is_starred": false,
    "created_at": "2026-06-09T18:42:11Z",
    "updated_at": "2026-06-09T18:42:11Z"
  }
]

Proposed moves — read them, don’t fire them

The queue of proposed, approved, and completed moves. Filter by status (pending, pending_approval, approved, rejected, in_progress, completed, failed), category, or action_type. Grounded actions also carry evidence, confidence, and predicted_outcome payloads. Approving or executing is not possible with an API key — that happens in the app, by a human.

GET/api/v1/actions/request
curl "https://api.numoon.ai/api/v1/actions/?status=pending&limit=1" \
  -H "Authorization: Bearer $NUMOON_API_KEY"
GET/api/v1/actions/200 OK
[
  {
    "id": "f4b8c2d1-3a6e-4c9f-8b2d-5e7a1f9c0d34",
    "tenant_id": "7c2e4b9a-1f3d-4e8c-a6b5-9d0c2f4e6a81",
    "insight_id": "0d9f3a6e-8c41-4f2a-b7d3-2e1a9c5b8f10",
    "title": "Pause Meta campaign #4 — spend with no settled revenue",
    "description": "Campaign #4 spent $1,840 over 14 days with zero bank-settled conversions…",
    "action_type": "recommendation",
    "category": "marketing",
    "estimated_impact": "Stops ~$920/week in unrecoverable spend",
    "estimated_value": 1840,
    "effort_level": "low",
    "status": "pending",
    "approved_by": null,
    "approved_at": null,
    "executed_at": null,
    "completed_at": null,
    "execution_config": null,
    "execution_result": null,
    "error_message": null,
    "actual_impact": null,
    "actual_value": null,
    "created_at": "2026-06-09T18:45:02Z",
    "updated_at": "2026-06-09T18:45:02Z",
    "has_drafts": false,
    "latest_trajectory_status": null,
    "execution_mode": "manual",
    "predicted_outcome": null,
    "evidence": null,
    "confidence": null,
    "how_to": null,
    "execution_hook": null
  }
]

Integrations: connected in-app, read over the API.

You never integrate with Stripe, Meta, or Shopify directly — and you never handle a provider client ID or secret.

In the app — one-click Connect

41 providers · Stripe, Shopify, Meta, Klaviyo, QuickBooks…
OAuth handled end-to-end by our connection layer — no provider client IDs to register
No provider client IDs or secrets to register, ever
Tokens stay with the connection layer, not in your code

In your code — one REST API

RReconciled revenue, expenses, cash, health scores
RFindings ranked by predicted dollar impact
RProposed moves with status, evidence, confidence
One Bearer key · one base URL · no provider SDKs

The brain does the cross-referencing before your request ever lands: platform-reported numbers are reconciled against settled reality, then served as one consistent JSON surface. Your code reads conclusions, not raw connector payloads.

Rate limits & versioning.

The honest v1 posture — what’s guaranteed, what isn’t published yet.

Fair use

Reasonable use, no hard quotas yet

v1 ships without published per-key quotas. Your data refreshes on sync cycles measured in minutes, so poll every few minutes — not every second. If we introduce enforced limits, they’ll be published here first, with notice.

Stable

/api/v1 doesn’t break under you

The API is path-versioned. Additive changes — new optional fields, new endpoints — can land inside v1 at any time, so build clients that tolerate unknown fields. Breaking changes only ever ship under a new version path.

Contact

Changelog & support

Questions, a missing endpoint, or a response that doesn’t match this page — email support@numoon.ai with the request path and timestamp. Never include your API key. API changes are announced on the blog.

Read-only keys · shown once · revoke any time

Read your whole business over one API.

Create a key in Settings, paste one curl command, and your reconciled numbers come back as JSON. Writes stay where they belong — behind a human tap.