v1.0

API Reference

Integrate baref00t.io into your stack. Manage customers, trigger assessments, and automate security workflows through the Partner and Distributor APIs.

Overview

baref00t.io exposes two REST APIs that let you automate security assessment workflows. The Partner API is for MSPs who manage their own customers and run assessments against those tenants. The Distributor API is for organisations that provision and manage multiple partner accounts underneath a single billing relationship.

Both APIs accept and return JSON. All requests must be made over HTTPS. HTTP requests are rejected.

Authentication

Every request must include an API key in a custom header. Partner keys and Distributor keys use separate headers and separate prefixes so the server can route your request to the correct API surface.

Partner API Key

Pass your key in the X-Partner-Key header. Partner keys always start with pk_live_.

curl https://api.baref00t.io/api/v1/partner/me \
  -H "X-Partner-Key: pk_live_abc123def456"

Distributor API Key

Pass your key in the X-Distributor-Key header. Distributor keys always start with dk_live_.

curl https://api.baref00t.io/api/v1/distributor/me \
  -H "X-Distributor-Key: dk_live_xyz789ghi012"

Key Management

Each partner account can hold a maximum of two active API keys at any time. Use the Generate API Key and Revoke API Key endpoints to rotate keys with zero downtime: generate a new key in slot 2 while slot 1 is still active, migrate your systems, then revoke slot 1.

Never expose your API key in client-side code, public repositories, or browser requests. Keys carry the same privileges as your partner or distributor account.

Base URLs

APIBase URL
Partnerhttps://api.baref00t.io/api/v1/partner/
Distributorhttps://api.baref00t.io/api/v1/distributor/

All endpoint paths in this reference are shown relative to the base URL. For example, GET /v1/partner/me means you send the request to https://api.baref00t.io/api/v1/partner/me.

Rate Limits

APILimitWindow
Partner60 requestsper minute, per key
Distributor120 requestsper minute, per key

When you exceed the limit, the API returns a 429 status with the error code RATE_LIMITED. The response includes a Retry-After header indicating how many seconds to wait before retrying.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Retry after 12 seconds."
  }
}

Error Handling

All error responses follow a consistent envelope. The HTTP status code indicates the error category, and the response body contains a machine-readable code and a human-readable message.

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable description of what went wrong."
  }
}

Error Codes

CodeStatusDescription
MISSING_KEY401No API key header was provided in the request.
INVALID_KEY401The API key is malformed, expired, or revoked.
RATE_LIMITED429You have exceeded the rate limit for your API tier.
PARTNER_INACTIVE403The partner account is suspended or pending activation.
DISTRIBUTOR_INACTIVE403The distributor account is suspended or pending activation.
INVALID_JSON400The request body is not valid JSON.
MISSING_FIELD400A required field is missing from the request body.
INVALID_PRODUCT400The product identifier is not recognised.
PRODUCT_NOT_ALLOWED403Your plan does not include the requested product.
RUN_LIMIT_REACHED403You have reached the monthly assessment run limit for your plan.
NOT_FOUND404The requested resource does not exist or you do not have access.
MAX_KEYS409You already have the maximum number of API keys (2).
TOO_MANY400The bulk request exceeds the maximum batch size.

Webhooks

Configure a webhook URL in your partner or distributor portal to receive real-time event notifications. Webhooks are delivered as POST requests with a JSON body to the URL you specify.

Events

  • assessment.started An assessment run has been queued and is beginning execution.
  • assessment.completed An assessment run has finished and results are available.
  • assessment.failed An assessment run encountered an error and could not complete.
  • customer.created A new customer record was created.
  • customer.updated A customer record was modified.
  • customer.deleted A customer record was removed.
  • partner.activated A sub-partner account has been activated (Distributor only).
  • partner.suspended A sub-partner account has been suspended (Distributor only).
  • key.created A new API key was generated for the account.
  • key.revoked An API key was revoked.

Payload Format

{
  "id": "evt_a1b2c3d4e5f6",
  "type": "assessment.completed",
  "timestamp": "2026-04-03T08:15:22Z",
  "data": {
    "assessmentId": "run_x9y8z7w6",
    "customerId": "cust_abc123",
    "product": "essential-eight",
    "status": "completed",
    "score": 72
  }
}

Signature Verification

Every webhook request includes a X-Baref00t-Signature header containing an HMAC-SHA256 signature of the raw request body. Verify this signature using the webhook secret displayed in your portal to ensure the request originated from baref00t.io.

// Pseudocode: verify webhook signature
expected = HMAC-SHA256(webhook_secret, raw_request_body)
received = request.headers["X-Baref00t-Signature"]

// Use a constant-time comparison to prevent timing attacks
valid = constant_time_equal(expected, received)

Delivery

Webhooks are delivered with a timeout of 10 seconds. If your endpoint returns a non-2xx status code or times out, the delivery is retried up to 5 times with exponential backoff (1 min, 5 min, 30 min, 2 hr, 12 hr). After all retries are exhausted, the event is marked as failed in your portal's webhook log.

Your webhook endpoint should return a 200 status code as quickly as possible. Process the event payload asynchronously to avoid timeouts.

Partner API

The Partner API lets MSPs manage customers and run security assessments through a single API key. All endpoints require the X-Partner-Key header.

GET /v1/partner/me X-Partner-Key
Returns your partner account profile including plan details, usage counters, and limits.

Response 200

{
  "id": "prt_abc123",
  "company": "Acme MSP",
  "email": "admin@acmemsp.com",
  "plan": "professional",
  "status": "active",
  "usage": {
    "month": "2026-04",
    "runsUsed": 42,
    "runsLimit": 200,
    "customersCount": 18
  },
  "createdAt": "2026-01-15T09:30:00Z"
}
POST /v1/partner/plan X-Partner-Key
Upgrade or downgrade your MSP subscription plan. Changes take effect immediately on your Stripe subscription with proration — upgrades are charged on the next invoice, downgrades credit the unused portion of the current cycle. The new plan's run limit and allowed products apply to assessments triggered after the response returns.

Request body

{
  "plan": "professional",     // required: 'starter' | 'professional' | 'enterprise'
  "billing": "monthly",        // optional: 'monthly' | 'rolling' (annual). Defaults to current.
  "currency": "usd"             // optional: 'usd' | 'aud' | 'gbp' | 'eur' | 'sgd'. Auto-detected from your current subscription if omitted.
}

Response 200

{
  "partnerId": "prt_abc123",
  "plan": "professional",
  "billing": "monthly",
  "currency": "usd",
  "runLimit": 100,
  "subscriptionStatus": "active",
  "currentPeriodEnd": "2026-05-09T00:00:00Z"
}

Errors

400 INVALID_JSON           — request body could not be parsed
400 PLAN_CHANGE_FAILED     — invalid plan/billing, no active subscription, already on target plan,
                          or subscription is in a state that cannot be modified (canceled, etc)
401 Missing or invalid X-Partner-Key
500 Price lookup or Stripe API error

Notes

Rate-limited to 10 plan changes per hour per partner. Upgrades/downgrades are audited. Dashboard UI is available on the Billing tab of the partner portal.
GET /v1/partner/products X-Partner-Key
Returns the list of products available on your current plan.

Response 200

{
  "products": [
    {
      "id": "essential-eight",
      "name": "Essential Eight Assessment",
      "category": "compliance",
      "estimatedDuration": 180
    },
    {
      "id": "nist-csf",
      "name": "NIST CSF Assessment",
      "category": "compliance",
      "estimatedDuration": 240
    }
  ]
}
GET /v1/partner/customers X-Partner-Key
Returns all customers belonging to your partner account.

Response 200

{
  "customers": [
    {
      "id": "cust_abc123",
      "name": "Contoso Ltd",
      "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
      "email": "it@contoso.com",
      "createdAt": "2026-02-10T14:00:00Z"
    }
  ]
}
POST /v1/partner/customers X-Partner-Key
Creates a new customer record linked to your partner account.

Request Body

FieldTypeDescription
namestringrequiredDisplay name for the customer organisation.
tenantIdstring (GUID)requiredMicrosoft 365 tenant ID for the customer.
emailstringoptionalPrimary contact email address.
receiversstring[]optionalEmail addresses that receive assessment report notifications.
questionnaireRecipientsstring[]optionalEmail addresses that receive questionnaire invitations.
{
  "name": "Contoso Ltd",
  "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
  "email": "it@contoso.com",
  "receivers": ["ciso@contoso.com", "it@contoso.com"],
  "questionnaireRecipients": ["ciso@contoso.com"]
}

Response 201

{
  "id": "cust_abc123",
  "name": "Contoso Ltd",
  "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
  "email": "it@contoso.com",
  "receivers": ["ciso@contoso.com", "it@contoso.com"],
  "questionnaireRecipients": ["ciso@contoso.com"],
  "createdAt": "2026-04-03T10:00:00Z"
}

curl Example

curl -X POST https://api.baref00t.io/api/v1/partner/customers \
  -H "X-Partner-Key: pk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Contoso Ltd",
    "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
    "email": "it@contoso.com",
    "receivers": ["ciso@contoso.com"],
    "questionnaireRecipients": ["ciso@contoso.com"]
  }'
GET /v1/partner/customers/{id} X-Partner-Key
Returns full details for a single customer including receiver lists and recent assessment history.

Path Parameters

ParameterTypeDescription
idstringrequiredCustomer ID (e.g. cust_abc123).

Response 200

{
  "id": "cust_abc123",
  "name": "Contoso Ltd",
  "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
  "email": "it@contoso.com",
  "receivers": ["ciso@contoso.com", "it@contoso.com"],
  "questionnaireRecipients": ["ciso@contoso.com"],
  "recentRuns": [
    {
      "id": "run_x9y8z7w6",
      "product": "essential-eight",
      "status": "completed",
      "completedAt": "2026-03-28T14:22:00Z"
    }
  ],
  "createdAt": "2026-02-10T14:00:00Z"
}
PUT /v1/partner/customers/{id} X-Partner-Key
Updates an existing customer. Send only the fields you want to change. Omitted fields remain unchanged.

Path Parameters

ParameterTypeDescription
idstringrequiredCustomer ID.

Request Body

{
  "name": "Contoso Corporation",
  "receivers": ["ciso@contoso.com", "security@contoso.com"]
}

Response 200

{
  "id": "cust_abc123",
  "name": "Contoso Corporation",
  "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
  "email": "it@contoso.com",
  "receivers": ["ciso@contoso.com", "security@contoso.com"],
  "questionnaireRecipients": ["ciso@contoso.com"],
  "updatedAt": "2026-04-03T10:05:00Z"
}
DELETE /v1/partner/customers/{id} X-Partner-Key
Permanently removes a customer and all associated assessment data. This action cannot be undone.

Path Parameters

ParameterTypeDescription
idstringrequiredCustomer ID.

Response 204

No content. The customer has been deleted.

POST /v1/partner/assessments X-Partner-Key
Triggers a new assessment run for a customer. The run executes asynchronously; poll the status endpoint or use webhooks to track progress.

Request Body

FieldTypeDescription
customerIdstringrequiredThe customer to run the assessment against.
productstringrequiredProduct identifier (e.g. essential-eight, nist-csf).
maturityTargetnumberoptionalTarget maturity level (1-5). Defaults to the product default.
{
  "customerId": "cust_abc123",
  "product": "essential-eight",
  "maturityTarget": 3
}

Response 202

{
  "id": "run_x9y8z7w6",
  "customerId": "cust_abc123",
  "product": "essential-eight",
  "maturityTarget": 3,
  "status": "queued",
  "createdAt": "2026-04-03T10:10:00Z"
}

curl Example

curl -X POST https://api.baref00t.io/api/v1/partner/assessments \
  -H "X-Partner-Key: pk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "cust_abc123",
    "product": "essential-eight",
    "maturityTarget": 3
  }'
GET /v1/partner/assessments X-Partner-Key
Returns a list of assessment runs. Use query parameters to filter results.

Query Parameters

ParameterTypeDescription
monthstringoptionalFilter by month in YYYY-MM format.
productstringoptionalFilter by product identifier.
customerIdstringoptionalFilter by customer ID.

Response 200

{
  "runs": [
    {
      "id": "run_x9y8z7w6",
      "customerId": "cust_abc123",
      "product": "essential-eight",
      "status": "completed",
      "score": 72,
      "createdAt": "2026-04-03T10:10:00Z",
      "completedAt": "2026-04-03T10:13:22Z"
    }
  ]
}

curl Example

curl "https://api.baref00t.io/api/v1/partner/assessments?month=2026-04&product=essential-eight" \
  -H "X-Partner-Key: pk_live_abc123def456"
GET /v1/partner/assessments/{id} X-Partner-Key
Returns the current status and results of a single assessment run.

Path Parameters

ParameterTypeDescription
idstringrequiredAssessment run ID (e.g. run_x9y8z7w6).

Response 200

{
  "id": "run_x9y8z7w6",
  "customerId": "cust_abc123",
  "customerName": "Contoso Ltd",
  "product": "essential-eight",
  "maturityTarget": 3,
  "status": "completed",
  "score": 72,
  "findings": 14,
  "critical": 2,
  "high": 5,
  "medium": 4,
  "low": 3,
  "reportUrl": "https://app.baref00t.io/reports/run_x9y8z7w6",
  "createdAt": "2026-04-03T10:10:00Z",
  "completedAt": "2026-04-03T10:13:22Z"
}
POST /v1/partner/customers/bulk X-Partner-Key
Creates multiple customers in a single request. Maximum 100 customers per request.

Request Body

{
  "customers": [
    {
      "name": "Contoso Ltd",
      "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
      "email": "it@contoso.com"
    },
    {
      "name": "Fabrikam Inc",
      "tenantId": "a1b2c3d4-5678-9abc-def0-123456789abc",
      "email": "admin@fabrikam.com"
    }
  ]
}

Response 201

{
  "created": 2,
  "failed": 0,
  "customers": [
    { "id": "cust_abc123", "name": "Contoso Ltd", "status": "created" },
    { "id": "cust_def456", "name": "Fabrikam Inc", "status": "created" }
  ]
}
Maximum batch size is 100 customers. Requests exceeding this limit return a TOO_MANY error.
POST /v1/partner/assessments/bulk X-Partner-Key
Triggers the same assessment product against multiple customers. Maximum 50 customers per request.

Request Body

FieldTypeDescription
productstringrequiredProduct identifier to run.
customerIdsstring[]requiredArray of customer IDs. Max 50.
maturityTargetnumberoptionalTarget maturity level applied to all runs.
{
  "product": "essential-eight",
  "customerIds": ["cust_abc123", "cust_def456", "cust_ghi789"],
  "maturityTarget": 3
}

Response 202

{
  "queued": 3,
  "failed": 0,
  "runs": [
    { "id": "run_001", "customerId": "cust_abc123", "status": "queued" },
    { "id": "run_002", "customerId": "cust_def456", "status": "queued" },
    { "id": "run_003", "customerId": "cust_ghi789", "status": "queued" }
  ]
}
Maximum batch size is 50 customer IDs. Requests exceeding this limit return a TOO_MANY error.
POST /v1/partner/keys X-Partner-Key
Generates a new API key for your partner account. Each account can hold a maximum of 2 active keys.

Request Body

No request body required.

Response 201

{
  "slot": 2,
  "key": "pk_live_newkey789xyz",
  "createdAt": "2026-04-03T10:20:00Z"
}
The full key is only returned once at creation time. Store it securely. You cannot retrieve it again.
DELETE /v1/partner/keys/{slot} X-Partner-Key
Revokes the API key in the specified slot. The key becomes immediately invalid.

Path Parameters

ParameterTypeDescription
slotnumberrequiredKey slot to revoke: 1 or 2.

Response 204

No content. The key has been revoked.

You cannot revoke a key if it is the only active key on the account. Generate a new key first, then revoke the old one.

Distributor API

The Distributor API lets you provision and manage multiple partner accounts under a single billing relationship. All endpoints require the X-Distributor-Key header.

GET /v1/distributor/me X-Distributor-Key
Returns your distributor account profile including plan details and aggregate usage.

Response 200

{
  "id": "dist_xyz789",
  "company": "Global Security Distribution",
  "email": "ops@globalsecdist.com",
  "status": "active",
  "partnersCount": 12,
  "usage": {
    "month": "2026-04",
    "totalRuns": 384,
    "totalCustomers": 156
  },
  "createdAt": "2025-11-01T08:00:00Z"
}
GET /v1/distributor/partners X-Distributor-Key
Returns all sub-partner accounts under your distributor account.

Query Parameters

ParameterTypeDescription
statusstringoptionalFilter by status: active, suspended, pending.

Response 200

{
  "partners": [
    {
      "id": "prt_abc123",
      "company": "Acme MSP",
      "email": "admin@acmemsp.com",
      "plan": "professional",
      "status": "active",
      "customersCount": 18,
      "createdAt": "2026-01-15T09:30:00Z"
    }
  ]
}
POST /v1/distributor/partners X-Distributor-Key
Provisions a new partner account under your distributor. The partner receives an activation email.

Request Body

FieldTypeDescription
emailstringrequiredAdmin email for the new partner account.
companystringrequiredCompany name for the partner.
namestringrequiredContact name for the partner admin.
planstringrequiredPlan to assign: starter, professional, enterprise.
billingobjectrequiredBilling configuration for the partner.
billing.currencystringrequiredISO 4217 currency code: AUD, USD, GBP, EUR, NZD.
billing.intervalstringoptionalBilling interval: quarterly (default) or annual.
{
  "email": "admin@newmsp.com",
  "company": "New MSP Pty Ltd",
  "name": "Jane Smith",
  "plan": "professional",
  "billing": {
    "currency": "AUD",
    "interval": "quarterly"
  }
}

Response 201

{
  "id": "prt_new456",
  "company": "New MSP Pty Ltd",
  "email": "admin@newmsp.com",
  "plan": "professional",
  "status": "pending",
  "billing": {
    "currency": "AUD",
    "interval": "quarterly"
  },
  "createdAt": "2026-04-03T11:00:00Z"
}
GET /v1/distributor/partners/{id} X-Distributor-Key
Returns full details for a sub-partner including current plan, billing, and usage for the current month.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID (e.g. prt_abc123).

Response 200

{
  "id": "prt_abc123",
  "company": "Acme MSP",
  "email": "admin@acmemsp.com",
  "name": "John Doe",
  "plan": "professional",
  "status": "active",
  "billing": {
    "currency": "AUD",
    "interval": "quarterly"
  },
  "usage": {
    "month": "2026-04",
    "runsUsed": 42,
    "runsLimit": 200,
    "customersCount": 18
  },
  "createdAt": "2026-01-15T09:30:00Z"
}
PUT /v1/distributor/partners/{id} X-Distributor-Key
Updates a sub-partner's plan or billing configuration. Send only the fields you want to change.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID.

Request Body

{
  "plan": "enterprise",
  "billing": {
    "interval": "annual"
  }
}

Response 200

{
  "id": "prt_abc123",
  "plan": "enterprise",
  "billing": {
    "currency": "AUD",
    "interval": "annual"
  },
  "updatedAt": "2026-04-03T11:15:00Z"
}
POST /v1/distributor/partners/{id}/activate X-Distributor-Key
Activates a pending or suspended partner account. The partner immediately gains access to the API and portal.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID.

Request Body

No request body required.

Response 200

{
  "id": "prt_abc123",
  "status": "active",
  "activatedAt": "2026-04-03T11:20:00Z"
}
POST /v1/distributor/partners/{id}/suspend X-Distributor-Key
Suspends an active partner account. The partner's API keys are immediately invalidated and portal access is revoked.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID.

Request Body

No request body required.

Response 200

{
  "id": "prt_abc123",
  "status": "suspended",
  "suspendedAt": "2026-04-03T11:25:00Z"
}
Suspending a partner immediately invalidates all of their API keys. The partner will need to generate new keys after reactivation.
POST /v1/distributor/partners/{id}/plan X-Distributor-Key
Upgrade or downgrade a sub-partner's MSP subscription plan on their behalf. The partner's Stripe subscription is updated with prorated billing, and the new plan's run limits apply immediately.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID (must belong to this distributor).

Request body

{
  "plan": "enterprise",      // required: 'starter' | 'professional' | 'enterprise'
  "billing": "rolling",        // optional: 'monthly' | 'rolling' (annual). Defaults to partner's current.
  "currency": "aud"             // optional: 'usd' | 'aud' | 'gbp' | 'eur' | 'sgd'. Auto-detected from partner's current subscription if omitted.
}

Response 200

{
  "partnerId": "prt_abc123",
  "plan": "enterprise",
  "billing": "rolling",
  "currency": "aud",
  "runLimit": -1,                // -1 = unlimited
  "subscriptionStatus": "active",
  "currentPeriodEnd": "2027-04-09T00:00:00Z"
}

Errors

404 NOT_FOUND              — partner does not exist or is not owned by this distributor
400 PLAN_CHANGE_FAILED     — invalid plan/billing, no active subscription, already on target plan,
                          or subscription is in a state that cannot be modified
401 Missing or invalid X-Distributor-Key
500 Price lookup or Stripe API error

Notes

Plan changes against sub-partners are audited under the distributor's ID. If the distributor has StripeBillingEnabled=false, the partner's own Stripe subscription is still updated — revenue-share settlement is tracked separately.
GET /v1/distributor/partners/{id}/customers X-Distributor-Key
Returns all customers belonging to a specific sub-partner.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID.

Response 200

{
  "customers": [
    {
      "id": "cust_abc123",
      "name": "Contoso Ltd",
      "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
      "email": "it@contoso.com",
      "createdAt": "2026-02-10T14:00:00Z"
    }
  ]
}
POST /v1/distributor/partners/{id}/customers X-Distributor-Key
Creates a customer record under a specific sub-partner. The request body is identical to the Partner API's create customer endpoint.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID to create the customer under.

Request Body

{
  "name": "Contoso Ltd",
  "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
  "email": "it@contoso.com",
  "receivers": ["ciso@contoso.com"],
  "questionnaireRecipients": ["ciso@contoso.com"]
}

Response 201

{
  "id": "cust_new789",
  "name": "Contoso Ltd",
  "tenantId": "d4f5a678-1234-5678-9abc-def012345678",
  "email": "it@contoso.com",
  "receivers": ["ciso@contoso.com"],
  "questionnaireRecipients": ["ciso@contoso.com"],
  "partnerId": "prt_abc123",
  "createdAt": "2026-04-03T11:30:00Z"
}
POST /v1/distributor/partners/{id}/assessments X-Distributor-Key
Triggers an assessment run on behalf of a sub-partner. The request body is identical to the Partner API's trigger assessment endpoint.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID.

Request Body

{
  "customerId": "cust_abc123",
  "product": "essential-eight",
  "maturityTarget": 3
}

Response 202

{
  "id": "run_dist001",
  "customerId": "cust_abc123",
  "partnerId": "prt_abc123",
  "product": "essential-eight",
  "status": "queued",
  "createdAt": "2026-04-03T11:35:00Z"
}
GET /v1/distributor/partners/{id}/assessments X-Distributor-Key
Returns all assessment runs belonging to a specific sub-partner.

Path Parameters

ParameterTypeDescription
idstringrequiredPartner ID.

Response 200

{
  "runs": [
    {
      "id": "run_dist001",
      "customerId": "cust_abc123",
      "product": "essential-eight",
      "status": "completed",
      "score": 72,
      "createdAt": "2026-04-03T11:35:00Z",
      "completedAt": "2026-04-03T11:38:44Z"
    }
  ]
}
GET /v1/distributor/usage X-Distributor-Key
Returns aggregate usage across all sub-partners for the specified month.

Query Parameters

ParameterTypeDescription
monthstringoptionalMonth in YYYY-MM format. Defaults to current month.

Response 200

{
  "month": "2026-04",
  "totalPartners": 12,
  "activePartners": 10,
  "totalCustomers": 156,
  "totalRuns": 384,
  "byPartner": [
    {
      "partnerId": "prt_abc123",
      "company": "Acme MSP",
      "runs": 42,
      "customers": 18
    },
    {
      "partnerId": "prt_def456",
      "company": "SecureIT Partners",
      "runs": 67,
      "customers": 24
    }
  ]
}
POST /v1/distributor/partners/bulk X-Distributor-Key
Provisions multiple partner accounts in a single request. Maximum 50 partners per request.

Request Body

{
  "partners": [
    {
      "email": "admin@mspalpha.com",
      "company": "MSP Alpha",
      "name": "Alice Wong",
      "plan": "professional",
      "billing": { "currency": "AUD", "interval": "quarterly" }
    },
    {
      "email": "admin@mspbeta.com",
      "company": "MSP Beta",
      "name": "Bob Chen",
      "plan": "starter",
      "billing": { "currency": "USD", "interval": "quarterly" }
    }
  ]
}

Response 201

{
  "created": 2,
  "failed": 0,
  "partners": [
    { "id": "prt_alpha01", "company": "MSP Alpha", "status": "pending" },
    { "id": "prt_beta02", "company": "MSP Beta", "status": "pending" }
  ]
}
Maximum batch size is 50 partners. Requests exceeding this limit return a TOO_MANY error.