RequestRocketRequestRocketDocs
PartnersBilling

MSP billing API

Rates, billing owner, plans, renew, and top-up for a managed client.

MSP configuration is the floor. Managed-client configuration and plan routes are nested under the client. Promo code responses omit the redemption secret.

On this page

Endpoints

MethodPathWhat it does
GET/api/msps/:mspId/configurationsRead the MSP rates floor
PUT/api/msps/:mspId/configurationsUpdate the MSP rates floor
GET/api/msps/:mspId/clients/:clientId/configurationsRead a managed client's configuration
PUT/api/msps/:mspId/clients/:clientId/configurationsUpdate billingTo, rates, and feature overrides
GET/api/msps/:mspId/clients/:clientId/planRead a managed client's plan
PUT/api/msps/:mspId/clients/:clientId/planRequest a plan change
POST/api/msps/:mspId/clients/:clientId/plan/renewRenew a lapsed plan
POST/api/msps/:mspId/clients/:clientId/plan/topupRequest a manual top-up
POST/api/msps/:mspId/clients/:clientId/promocodesRedeem a code for a managed client

Update who pays

PUT /api/msps/:mspId/clients/:clientId/configurations sets billingTo to client or msp. Rates below the MSP floor are raised, not rejected.

Request

curl -X PUT "https://api.requestrocket.com/api/msps/:mspId/clients/:clientId/configurations" \
  -H "Authorization: u-your-token" \
  -H "Content-Type: application/json" \
  -d '{
  "billingTo": "client"
}'
import axios from "axios";

const response = await axios.request({
  method: "PUT",
  url: "https://api.requestrocket.com/api/msps/:mspId/clients/:clientId/configurations",
  headers: {
    "Authorization": "u-your-token",
    "Content-Type": "application/json",
  },
  data: {
  "billingTo": "client"
}
});

console.log(response.status, response.data);
import requests

response = requests.request(
    "PUT",
    "https://api.requestrocket.com/api/msps/:mspId/clients/:clientId/configurations",
    headers={
        "Authorization": "u-your-token",
        "Content-Type": "application/json",
    },
    data="{\n  \"billingTo\": \"client\"\n}"
)
print(response.status_code, response.json())
package main

import (
    "fmt"
    "io"
    "net/http"
    "strings"
)

func main() {
    payload := strings.NewReader(`{
  "billingTo": "client"
}`)
    req, _ := http.NewRequest("PUT", "https://api.requestrocket.com/api/msps/:mspId/clients/:clientId/configurations", payload)
    req.Header.Set("Authorization", "u-your-token")
    req.Header.Set("Content-Type", "application/json")
    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)
    fmt.Println(resp.StatusCode, string(body))
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.requestrocket.com/api/msps/:mspId/clients/:clientId/configurations"))
            .method("PUT", HttpRequest.BodyPublishers.ofString("{\n  \"billingTo\": \"client\"\n}"))
            .header("Authorization", "u-your-token")
            .header("Content-Type", "application/json")
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode());
        System.out.println(response.body());
    }
}

Responses

{
  "configuration": {
    "billingTo": "client",
    "billingType": "stripe",
    "billingStatus": "active"
  },
  "message": "Configuration updated successfully"
}
{
  "message": "Input failed data validation",
  "errors": [
    "/billingTo: must be equal to one of the allowed values"
  ]
}
{
  "message": "Unauthorized"
}
{
  "Message": "User is not authorized to access this resource with an explicit deny in an identity-based policy"
}
{
  "message": "method / endpoint not supported"
}

All fields are optional. Omit a field to leave it unchanged. Rates below the MSP floor are raised, not rejected.

Request body

ParameterTypeRequiredDescription
billingTostringWho is charged: client or msp. Switching to msp requires a payment method on the MSP.
billingTypestringstripe, marketplace, or invoice. A partner caller can set stripe. marketplace and invoice are applied for a system admin.
topUpMethodstringautomatic or manual.
regionAccessstring[]Region codes this organisation may use. Send an array to replace the list.
limitsobjectRequest caps. Sending limits requires both fields below. A value above the platform default is capped: 300 per minute and 20000 per day.
limits.requestsPerMinutenumberPer-minute cap. Required when limits is sent.
limits.requestsPerDaynumberPer-day cap. Required when limits is sent.
budgetobjectTop-up thresholds. Applied when billing is charged to the MSP and billingType is stripe. Sending budget requires both thresholds. budget.current is the balance and is not writable.
budget.minimumTopUpThresholdnumberLow-balance threshold. Required when budget is sent. Values below 5 are raised to 5.
budget.maximumTopUpThresholdnumberTop-up ceiling. Required when budget is sent. Values below 20 are raised to 20, and the ceiling stays at least 10 above the minimum.
ratesobjectPrice multipliers. Sending rates requires all four metrics. Each value is clamped to the range 0.7 to 1, then raised to the MSP floor.
rates.apiSecondsnumberAPI-seconds multiplier. Required when rates is sent.
rates.storageGBnumberStorage multiplier. Required when rates is sent.
rates.aiTokensnumberAI-token multiplier. Required when rates is sent.
rates.plannumberPlan-fee multiplier. Required when rates is sent.
featureOverridesstring[]Features the MSP assigns. Omit the field to leave overrides unchanged. An empty array clears MSP-assignable overrides and keeps features only RequestRocket can grant. Values: proxy_auth_key, proxy_auth_basic, proxy_auth_bearer, proxy_auth_jwt, proxy_auth_jwt_verify, proxy_auth_oauth2, proxy_auth_idp_verify, mcp_entrypoint, mcp_user_pool, target_auth_key, target_auth_basic, target_auth_bearer, target_auth_jwt, target_auth_oauth2, target_auth_none, target_auth_passthrough, target_auth_custom_token, target_auth_custom, target_auth_jwt_signed, async_api, overrides, mocking, request_transformation, response_transformation, human_auth, metering, authorization_rules, data_filtering, data_redaction, custom_domains, payload_logging, logging_webhooks, security_alerts, governance_alerts.

Plan fields, promoOverrides, promotionalCodes, billingStatus, and sharing are not changed by this call. Redeem a code on the promocodes route. Change the plan on the plan route.

Returns the saved configuration. The balance in budget.current is left as stored.

Response

AttributeTypeDescription
configuration.billingTostringclient or msp.
configuration.billingTypestringstripe, marketplace, or invoice.
configuration.billingStatusstringactive or suspended. Not changed by this call.
configuration.topUpMethodstringautomatic or manual.
configuration.ratesobjectapiSeconds, storageGB, aiTokens, and plan after clamping.
configuration.limitsobjectrequestsPerMinute and requestsPerDay after capping.
configuration.budget.currentnumberBalance. Not overwritten by this call.
configuration.budget.minimumTopUpThresholdnumberLow-balance threshold after validation.
configuration.budget.maximumTopUpThresholdnumberTop-up ceiling after validation.
configuration.featureOverridesstring[]Overrides after this call.
messagestringConfiguration updated successfully.

Read the MSP rates floor

GET /api/msps/:mspId/configurations returns the MSP billing type and the rates floor.

Query parameters

None.

Response

AttributeTypeDescription
configuration.billingTypestringstripe, marketplace, or invoice.
configuration.billingStatusstringactive or suspended, when set.
configuration.promotionalCodesarray or nullApplied grants. Each item has name, createdAt, and expiresAt. The redemption secret is not included.
configuration.rates.apiSecondsnumberFloor multiplier for API seconds.
configuration.rates.storageGBnumberFloor multiplier for storage.
configuration.rates.aiTokensnumberFloor multiplier for AI tokens.
configuration.rates.plannumberFloor multiplier for the plan fee.
messagestringSuccess.

Update the MSP rates floor

PUT /api/msps/:mspId/configurations updates the MSP's own configuration. All fields are optional. Omit a field to leave it unchanged. Rates and billing type are applied for a system admin. Raising the floor re-clamps managed organisations whose stored rates sit below the new floor. Client balances are not overwritten.

Request body

ParameterTypeRequiredDescription
billingTypestringstripe, marketplace, or invoice. Applied for a system admin.
billingStatusstringactive or suspended. Accepted by validation and left unchanged.
ratesobjectFloor multipliers. Applied for a system admin. Sending rates requires apiSeconds, storageGB, aiTokens, and plan. Each value is clamped to the range 0.7 to 1.
rates.apiSecondsnumberAPI-seconds floor. Required when rates is sent.
rates.storageGBnumberStorage floor. Required when rates is sent.
rates.aiTokensnumberAI-token floor. Required when rates is sent.
rates.plannumberPlan-fee floor. Required when rates is sent.

promotionalCodes is not writable here. Redeem a code on the managed-client promocodes route, or on POST /api/msps/:mspId/promocodes for the MSP itself.

Returns the saved configuration. When the new floor raises one or more managed organisations, the response also includes clientsReclamped.

Response

AttributeTypeDescription
configurationobjectSaved MSP configuration. Same shape as the GET response.
clientsReclampednumberHow many managed organisations were raised to the new floor. Present only when that count is greater than zero.
messagestringConfiguration updated successfully.

Read a managed client's configuration

GET /api/msps/:mspId/clients/:clientId/configurations returns the organisation configuration, including who pays, rates, and the plan fields stored on the configuration.

Query parameters

None.

Response

AttributeTypeDescription
configuration.billingTostringclient or msp.
configuration.billingTypestringstripe, marketplace, or invoice.
configuration.billingStatusstringactive or suspended.
configuration.topUpMethodstringautomatic or manual.
configuration.ratesobjectapiSeconds, storageGB, aiTokens, and plan.
configuration.limitsobjectrequestsPerMinute and requestsPerDay.
configuration.budgetobjectcurrent, minimumTopUpThreshold, and maximumTopUpThreshold.
configuration.planTierstringbasic, team, enterprise_basic, enterprise_security, enterprise_governance, or enterprise_custom.
configuration.planStatusstringactive, upgrade_requested, downgrade_scheduled, payment_failed, or expired.
configuration.featureOverridesstring[]Features granted outside the plan.
configuration.promoOverridesstring[]Features granted by promotional codes.
messagestringSuccess.

Read a managed client's plan

GET /api/msps/:mspId/clients/:clientId/plan returns the current plan, the features it includes, and the prices after the MSP plan multiplier.

Query parameters

None.

Response

AttributeTypeDescription
plan.planTierstringStored tier.
plan.planStatusstringactive, upgrade_requested, downgrade_scheduled, payment_failed, or expired.
plan.planPendingTierstring or nullTier waiting on payment or a scheduled downgrade.
plan.planPendingInvoiceIdstring or nullInvoice that must be paid before an upgrade or renewal applies.
plan.planPendingEffectiveAtstring or nullWhen a scheduled downgrade takes effect.
plan.planExpiresAtstring or nullEnd of the current paid period.
plan.effectivePlanTierstringTier used for feature checks.
plan.featuresstring[]Features included for effectivePlanTier.
plan.displayNamestringLabel for the effective tier.
plan.pricesobjectMonthly fee for each tier after the MSP plan multiplier.
messagestringSuccess.

Request a plan change

PUT /api/msps/:mspId/clients/:clientId/plan requests an upgrade, schedules a downgrade, or cancels a pending change by sending the current tier. The MSP can change the plan when billingTo is msp.

Request body

ParameterTypeRequiredDescription
planTierstring✓basic, team, enterprise_basic, enterprise_security, enterprise_governance, or enterprise_custom. enterprise_custom is assigned by a system admin.

Returns the plan after the request. An upgrade on Stripe billing also returns invoiceId and leaves the tier unchanged until the invoice is paid. A downgrade stays on the current tier until planPendingEffectiveAt. Sending the current tier with nothing pending returns the plan unchanged.

Response

AttributeTypeDescription
planobjectPlan view. Same attributes as the GET plan response.
invoiceIdstringStripe invoice id. Present when an upgrade invoice was created.
messagestringUpgrade invoice created — pending payment, Downgrade scheduled for period end, Pending plan change cancelled, Plan unchanged, or Plan updated.

Renew a lapsed plan

POST /api/msps/:mspId/clients/:clientId/plan/renew renews a plan that is expired or payment-failed. This call has no request body. The MSP can renew when billingTo is msp.

Returns the plan. Stripe billing also returns invoiceId and waits for payment. Invoice and marketplace billing renew immediately.

Response

AttributeTypeDescription
planobjectPlan view after the renewal request.
invoiceIdstringStripe invoice id, when a renewal invoice was created.
messagestringRenewal invoice created — pending payment, or Plan renewed.

Request a manual top-up

POST /api/msps/:mspId/clients/:clientId/plan/topup submits a top-up for an organisation whose topUpMethod is manual. This call has no request body. The MSP can submit it when billingTo is msp.

Returns a confirmation. The call does not include a new balance.

Response

AttributeTypeDescription
messagestringTop-up request submitted to billing.

Redeem a code for a managed client

POST /api/msps/:mspId/clients/:clientId/promocodes redeems a promotional code for the organisation. The response returns the grant name, not the redemption secret.

Request body

ParameterTypeRequiredDescription
codestring✓Redemption secret. It is not returned.

Returns the grant that matched, whether it was already applied, and the full grant list.

Response

AttributeTypeDescription
applied.namestringPublic name of the grant.
applied.createdAtstringISO-8601 time the grant was applied.
applied.expiresAtstringISO-8601 expiry.
alreadyAppliedbooleantrue when this grant name was already stored.
promotionalCodesarrayGrants after this call. Each item has name, createdAt, and expiresAt.
messagestringPromotional code applied, or Promotional code already applied.

Shared status codes, the 5.5 MB cap, and plan rate limits are on Platform limits.

Next

On this page