Partner API Reference | MOSS
API REFERENCE · v2.0

Partner API

The MOSS Partner API lets you create and manage customers, promote them from sandbox to production, stream events, and read analytics and billing, all programmatically. Every response field below matches the live API exactly.

Base URLhttps://api.mosscomputing.com
AuthBearer token, prt_ prefix
FormatJSON request and response bodies
SDKsPython · TypeScript

Authentication

Every Partner API request carries your partner key as a bearer token. The key is issued once at registration and cannot be retrieved again. Store it like a production secret.

http
Authorization: Bearer prt_your_partner_key
PrefixScope
prt_Partner API: manage customers, webhooks, analytics, billing
cust_Customer API: register agents, sign actions, query audit
cap_Capability token: scoped, time-limited agent runtime signing

Register a partner

Registration is public (no auth). The response returns your prt_ token exactly once.

POST /v1/partner/register
{
  "external_id": "emery_ai",
  "name": "Emery AI",
  "settings": {},
  "promo_code": "MOSS_EARLY_2026"
}
201 Created
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "emery_ai",
  "name": "Emery AI",
  "status": "active",
  "early_access": true,
  "token": "prt_live_abc123..."
}
Store the token now. The token field is returned exactly once and cannot be retrieved again.

Partner management

GET/v1/partner/me

Return your partner profile and rolled-up governance counts.

200 OK
{
  "id": "550e8400-...",
  "external_id": "emery_ai",
  "name": "Emery AI",
  "status": "active",
  "governance": { "organizations": 12, "agents": 45, "envelopes": 15200 }
}
PATCH/v1/partner/settings

Update partner defaults applied to new customers, such as default jurisdictions and frameworks.

Request
{
  "settings": {
    "default_jurisdictions": ["EU", "US"],
    "default_frameworks": ["eu_ai_act", "nist_ai_rmf"]
  }
}
POST/v1/partner/revoke

Revoke your partner key. Revocation propagates to every delegated customer credential.

200 OK
{
  "affected": { "direct": 1, "delegated": 45, "total": 46 },
  "propagation": { "channels_notified": 3, "status": "completed" }
}

Customer lifecycle

POST/v1/partner/customers

Create a customer. It starts pending and auto-activates to sandbox_active on the first authenticated cust_ call. Supports the Idempotency-Key header.

Request
{
  "external_id": "acme_123",
  "name": "Acme Corp",
  "tier": "platform",
  "settings": { "jurisdictions": ["US"], "frameworks": ["nist_ai_rmf"] }
}
201 Created
{
  "customer_id": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "acme_123",
  "name": "Acme Corp",
  "status": "pending",
  "partner_id": "partner-uuid-here",
  "credentials": {
    "customer_token": { "token": "cust_live_abc123...", "prefix": "cust_" }
  }
}
The credentials.customer_token.token is returned exactly once.
GET/v1/partner/customers

List your customers, newest first.

QueryTypeDescription
statusstringpending, sandbox_active, production_active, suspended, deactivated
limitintMax results (default 100)
offsetintPagination offset (default 0)
GET/v1/partner/customers/{customer_id}

Fetch a single customer with governance status and limits. A suspension_reason is included when the status is suspended.

200 OK
{
  "customer_id": "uuid-here",
  "name": "Acme Corp",
  "tier": "platform",
  "status": "sandbox_active",
  "governance": {
    "frameworks_active": ["nist_ai_rmf", "eu_ai_act"],
    "policies_inherited": 5,
    "compliance_score": 85
  },
  "limits": { "agents": 10, "envelopes_per_month": 10000 }
}
PATCH/v1/partner/customers/{customer_id}

Update a customer's limits or settings. Returns the full customer object.

Request
{
  "limits": { "agents": 50 },
  "settings": { "jurisdictions": ["EU", "US"] }
}
POST/v1/partner/customers/{customer_id}/promote

Promote a sandbox customer to production. Requires a signed attestation and billing details; the attestation record is cryptographically signed and immutable. Supports Idempotency-Key.

Request
{
  "attestation": {
    "kyc_completed": true,
    "kyc_provider": "Onfido",
    "terms_accepted": true,
    "terms_version": "2026-01",
    "compliance_reviewed": true
  },
  "billing": {
    "tier": "platform",
    "billing_email": "billing@acme.com",
    "billing_cycle": "monthly"
  }
}
200 OK
{
  "customer_id": "uuid-here",
  "status": "production_active",
  "transition": { "from": "sandbox_active", "to": "production_active", "by": "partner" },
  "attestation_record": { "hash": "sha256:...", "signature": "ml_dsa_44_sig_hex...", "immutable": true },
  "credentials": {
    "production_token": { "token": "cust_live_prod_abc123...", "environment": "production" }
  },
  "billing": { "subscription_id": "sub_abc123", "monthly_price": 8333.33, "annual_price": 100000 }
}
The production token is returned exactly once.
GET/v1/partner/customers/{customer_id}/promotion-readiness

Check whether a customer can be promoted. Returns per-check results and a list of blockers.

200 OK
{
  "ready": false,
  "customer_status": "sandbox_active",
  "checks": [
    { "label": "KYC completed", "passed": true, "detail": "Verified via Onfido" },
    { "label": "First signature", "passed": false, "detail": "No signatures yet" }
  ],
  "blockers": ["No signatures yet"]
}
POST/v1/partner/customers/{customer_id}/suspend

Suspend a customer, optionally halting agents immediately with a grace period. Supports Idempotency-Key.

Request
{
  "reason": "payment_failed",
  "suspend_agents_immediately": true,
  "grace_period_days": 90,
  "notification_email": "admin@acme.com"
}
POST/v1/partner/customers/{customer_id}/reactivate

Reactivate a suspended customer to its prior state. Requires a resolution block. Supports Idempotency-Key.

Request
{
  "resolution": { "issue_resolved": true, "details": "Payment received and processed" }
}
DELETE/v1/partner/customers/{customer_id}

Deactivate a customer. Returns the customer with status: "deactivated". This is a terminal state.

POST/v1/partner/customers/{customer_id}/invite

Invite a customer user to the MOSS Customer Portal.

201 Created
{
  "invitation_id": "inv-uuid",
  "email": "admin@acme.com",
  "status": "sent",
  "expires_at": "2026-08-27T12:00:00Z",
  "accept_url": "https://app.mosscomputing.com/invite/inv-uuid"
}

Sessions

POST/v1/partner/customers/{customer_id}/session

Mint a 15-minute full-access session token, ideal for embedding the MOSS dashboard in your own platform. No request body. Supports Idempotency-Key.

201 Created
{
  "session_id": "sess-uuid",
  "customer_id": "cust-uuid",
  "token": "cust_session_abc123...",
  "expires_at": "2026-08-20T12:15:00Z"
}
DELETE/v1/partner/customers/{customer_id}/session

Revoke one session by session_id, or omit it to revoke all active partner-session tokens for the customer. Returns 204 No Content.

Compliance reports

GET/v1/partner/customers/{customer_id}/compliance-report

Generate a signed PDF compliance report (application/pdf) with the governance summary, compliance score, policy statistics, and an ML-DSA-44 signature trailer.

Response headerDescription
X-MOSS-Report-IdUnique report ID
X-MOSS-Key-IdSigning key ID
Content-Dispositionattachment; filename="moss-compliance-{id}-{date}.pdf"

Webhooks

POST/v1/partner/webhooks

Register a webhook. It starts pending_verification; MOSS sends a challenge to the URL, and status flips to active once your sink echoes it in a 2xx response. The secret is stored hashed and never returned.

Request
{
  "url": "https://yourapp.com/webhooks/moss",
  "events": ["customer.*", "agent.anomaly_detected"],
  "security": { "secret": "your-secure-secret-at-least-8-chars" },
  "filters": { "severity_minimum": "medium", "environments": ["production"] }
}
GET/v1/partner/webhooks

List webhooks. Individual webhooks are available at GET /v1/partner/webhooks/{webhook_id}, re-verified with POST /v1/partner/webhooks/{webhook_id}/verify, and soft-deleted with DELETE /v1/partner/webhooks/{webhook_id}.

GET/v1/partner/webhooks/{webhook_id}/deliveries

Cursor-paginated delivery log with per-attempt status and response codes.

200 OK
{
  "deliveries": [
    {
      "delivery_id": "del-uuid",
      "event_type": "customer.status_changed",
      "status": "delivered",
      "attempts": 1,
      "response_code": 200
    }
  ],
  "pagination": { "has_more": false, "next_cursor": null }
}
GuideSignature verification

MOSS signs "{timestamp}.{body}" with HMAC-SHA256 using your shared secret, and sends the signature in the X-MOSS-Signature header as sha256=<hex>. Both SDKs ship a verifier.

python
from moss_partner_sdk import verify_webhook_signature

is_valid = verify_webhook_signature(
    payload=request.body,                       # raw bytes
    signature=request.headers["X-MOSS-Signature"],
    secret="your-shared-secret",
    timestamp=request.headers["X-MOSS-Timestamp"],
)
HeaderFormat
X-MOSS-Signaturesha256=<hex>
X-MOSS-TimestampUnix seconds (string)
X-MOSS-Delivery-IdUUID
X-MOSS-Event-TypeEvent type string

Analytics

GET/v1/partner/analytics

Portfolio analytics across customers, agents, governance, compliance, security, billing, and performance. Query with period (YYYY-MM) and granularity (daily or monthly).

200 OK (excerpt)
{
  "customers": { "total": 12, "by_status": { "sandbox_active": 7, "production_active": 3 } },
  "governance": { "total_signatures": 15200, "policy_violations": 120, "violation_rate": 0.0027 },
  "compliance": { "average_score": 87.5 },
  "billing": { "current_mrr": 750000, "customers_billable": 10 }
}

Usage

GET/v1/partner/usage

Usage summary for a period (current_month, last_month, last_30_days, last_90_days, or custom with start_date/end_date). Per-customer breakdowns are at GET /v1/partner/usage/customers with sort and order.

Billing & earnings

GET/v1/partner/billing/earnings

MOSS revenue, per-tier breakdown, usage, and your estimated margin. Your partner price and margin are set by your rate card and returned live in the response — the endpoint reflects your account’s terms, not a fixed schedule.

200 OK (excerpt)
{
  "period": "2026-08",
  "moss_revenue": { "monthly_recurring": 750000, "annual_recurring": 9000000, "currency": "USD" },
  "by_tier": [
    { "tier": "platform", "count": 5, "annual_total": 375000, "list_price_annual": 100000 }
  ],
  "partner_margin_estimate": { "monthly": "<per your rate card>", "annual": "<per your rate card>" }
}

Tiers

GET/v1/partner/tiers

List sellable tiers with list price, agent limits, retention, and features. Your partner price for each tier is returned live per your rate card — it is not a published schedule. The startup tier is direct-only (available_through_partners: false).

TierList / yrPartner / yrAgents
platform$100,000Per rate card5
scale$175,000Per rate card20
govern$275,000Per rate card50
enterpriseCustomPer rate cardUnlimited

Default policies

POST/v1/partner/defaults/policies

Create a default policy bundle applied to all new customers. List, update, and delete at GET, PATCH /{policy_id}, and DELETE /{policy_id}.

Request
{
  "name": "Block PII in outputs",
  "action": "block",
  "match": { "action_type": "*", "output_contains_pii": true },
  "priority": 100,
  "customer_can_override": false
}

Error handling

All errors return JSON with a machine-readable error code, a human message, and a request_id for support.

Error shape
{
  "error": "customer_not_found",
  "message": "Customer not found",
  "request_id": "req-uuid"
}
StatusCodeMeaning
401not_authenticatedMissing or invalid API key
403invalid_credential_typeWrong key prefix (need prt_)
404customer_not_foundCustomer not found or not owned by partner
409invalid_transitionInvalid status transition
409idempotency_key_conflictSame key, different body
422incomplete_attestationMissing required attestation fields for promotion

Idempotency

Send an Idempotency-Key header on create, promote, suspend, reactivate, and session endpoints for replay-safe writes. Same key + same body replays the original response; same key + different body returns 409 idempotency_key_conflict. Keys are partner-scoped.