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 URL | https://api.mosscomputing.com |
| Auth | Bearer token, prt_ prefix |
| Format | JSON request and response bodies |
| SDKs | Python · 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.
Authorization: Bearer prt_your_partner_key
| Prefix | Scope |
|---|---|
| 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.
{
"external_id": "emery_ai",
"name": "Emery AI",
"settings": {},
"promo_code": "MOSS_EARLY_2026"
}{
"id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "emery_ai",
"name": "Emery AI",
"status": "active",
"early_access": true,
"token": "prt_live_abc123..."
}token field is returned exactly once and cannot be retrieved again.Partner management
Return your partner profile and rolled-up governance counts.
{
"id": "550e8400-...",
"external_id": "emery_ai",
"name": "Emery AI",
"status": "active",
"governance": { "organizations": 12, "agents": 45, "envelopes": 15200 }
}Update partner defaults applied to new customers, such as default jurisdictions and frameworks.
{
"settings": {
"default_jurisdictions": ["EU", "US"],
"default_frameworks": ["eu_ai_act", "nist_ai_rmf"]
}
}Revoke your partner key. Revocation propagates to every delegated customer credential.
{
"affected": { "direct": 1, "delegated": 45, "total": 46 },
"propagation": { "channels_notified": 3, "status": "completed" }
}Customer lifecycle
Create a customer. It starts pending and auto-activates to sandbox_active on the first authenticated cust_ call. Supports the Idempotency-Key header.
{
"external_id": "acme_123",
"name": "Acme Corp",
"tier": "platform",
"settings": { "jurisdictions": ["US"], "frameworks": ["nist_ai_rmf"] }
}{
"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_" }
}
}credentials.customer_token.token is returned exactly once.List your customers, newest first.
| Query | Type | Description |
|---|---|---|
| status | string | pending, sandbox_active, production_active, suspended, deactivated |
| limit | int | Max results (default 100) |
| offset | int | Pagination offset (default 0) |
Fetch a single customer with governance status and limits. A suspension_reason is included when the status is suspended.
{
"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 }
}Update a customer's limits or settings. Returns the full customer object.
{
"limits": { "agents": 50 },
"settings": { "jurisdictions": ["EU", "US"] }
}Promote a sandbox customer to production. Requires a signed attestation and billing details; the attestation record is cryptographically signed and immutable. Supports Idempotency-Key.
{
"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"
}
}{
"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 }
}Check whether a customer can be promoted. Returns per-check results and a list of blockers.
{
"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"]
}Suspend a customer, optionally halting agents immediately with a grace period. Supports Idempotency-Key.
{
"reason": "payment_failed",
"suspend_agents_immediately": true,
"grace_period_days": 90,
"notification_email": "admin@acme.com"
}Reactivate a suspended customer to its prior state. Requires a resolution block. Supports Idempotency-Key.
{
"resolution": { "issue_resolved": true, "details": "Payment received and processed" }
}Deactivate a customer. Returns the customer with status: "deactivated". This is a terminal state.
Invite a customer user to the MOSS Customer Portal.
{
"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
Mint a 15-minute full-access session token, ideal for embedding the MOSS dashboard in your own platform. No request body. Supports Idempotency-Key.
{
"session_id": "sess-uuid",
"customer_id": "cust-uuid",
"token": "cust_session_abc123...",
"expires_at": "2026-08-20T12:15:00Z"
}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
Generate a signed PDF compliance report (application/pdf) with the governance summary, compliance score, policy statistics, and an ML-DSA-44 signature trailer.
| Response header | Description |
|---|---|
| X-MOSS-Report-Id | Unique report ID |
| X-MOSS-Key-Id | Signing key ID |
| Content-Disposition | attachment; filename="moss-compliance-{id}-{date}.pdf" |
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.
{
"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"] }
}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}.
Cursor-paginated delivery log with per-attempt status and response codes.
{
"deliveries": [
{
"delivery_id": "del-uuid",
"event_type": "customer.status_changed",
"status": "delivered",
"attempts": 1,
"response_code": 200
}
],
"pagination": { "has_more": false, "next_cursor": null }
}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.
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"],
)| Header | Format |
|---|---|
| X-MOSS-Signature | sha256=<hex> |
| X-MOSS-Timestamp | Unix seconds (string) |
| X-MOSS-Delivery-Id | UUID |
| X-MOSS-Event-Type | Event type string |
Analytics
Portfolio analytics across customers, agents, governance, compliance, security, billing, and performance. Query with period (YYYY-MM) and granularity (daily or monthly).
{
"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
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
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.
{
"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
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).
| Tier | List / yr | Partner / yr | Agents |
|---|---|---|---|
| platform | $100,000 | Per rate card | 5 |
| scale | $175,000 | Per rate card | 20 |
| govern | $275,000 | Per rate card | 50 |
| enterprise | Custom | Per rate card | Unlimited |
Default policies
Create a default policy bundle applied to all new customers. List, update, and delete at GET, PATCH /{policy_id}, and DELETE /{policy_id}.
{
"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": "customer_not_found",
"message": "Customer not found",
"request_id": "req-uuid"
}| Status | Code | Meaning |
|---|---|---|
| 401 | not_authenticated | Missing or invalid API key |
| 403 | invalid_credential_type | Wrong key prefix (need prt_) |
| 404 | customer_not_found | Customer not found or not owned by partner |
| 409 | invalid_transition | Invalid status transition |
| 409 | idempotency_key_conflict | Same key, different body |
| 422 | incomplete_attestation | Missing 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.