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
- Who pays
- MSP rates floor
- Managed-client configuration
- Managed-client plan
- Plan changes
- Renewal and top-up
- Promotional grants
Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /api/msps/:mspId/configurations | Read the MSP rates floor |
| PUT | /api/msps/:mspId/configurations | Update the MSP rates floor |
| GET | /api/msps/:mspId/clients/:clientId/configurations | Read a managed client's configuration |
| PUT | /api/msps/:mspId/clients/:clientId/configurations | Update billingTo, rates, and feature overrides |
| GET | /api/msps/:mspId/clients/:clientId/plan | Read a managed client's plan |
| PUT | /api/msps/:mspId/clients/:clientId/plan | Request a plan change |
| POST | /api/msps/:mspId/clients/:clientId/plan/renew | Renew a lapsed plan |
| POST | /api/msps/:mspId/clients/:clientId/plan/topup | Request a manual top-up |
| POST | /api/msps/:mspId/clients/:clientId/promocodes | Redeem 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": "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
| Parameter | Type | Required | Description |
|---|---|---|---|
billingTo | string | Who is charged: client or msp. Switching to msp requires a payment method on the MSP. | |
billingType | string | stripe, marketplace, or invoice. A partner caller can set stripe. marketplace and invoice are applied for a system admin. | |
topUpMethod | string | automatic or manual. | |
regionAccess | string[] | Region codes this organisation may use. Send an array to replace the list. | |
limits | object | Request caps. Sending limits requires both fields below. A value above the platform default is capped: 300 per minute and 20000 per day. | |
limits.requestsPerMinute | number | Per-minute cap. Required when limits is sent. | |
limits.requestsPerDay | number | Per-day cap. Required when limits is sent. | |
budget | object | Top-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.minimumTopUpThreshold | number | Low-balance threshold. Required when budget is sent. Values below 5 are raised to 5. | |
budget.maximumTopUpThreshold | number | Top-up ceiling. Required when budget is sent. Values below 20 are raised to 20, and the ceiling stays at least 10 above the minimum. | |
rates | object | Price 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.apiSeconds | number | API-seconds multiplier. Required when rates is sent. | |
rates.storageGB | number | Storage multiplier. Required when rates is sent. | |
rates.aiTokens | number | AI-token multiplier. Required when rates is sent. | |
rates.plan | number | Plan-fee multiplier. Required when rates is sent. | |
featureOverrides | string[] | 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
| Attribute | Type | Description |
|---|---|---|
configuration.billingTo | string | client or msp. |
configuration.billingType | string | stripe, marketplace, or invoice. |
configuration.billingStatus | string | active or suspended. Not changed by this call. |
configuration.topUpMethod | string | automatic or manual. |
configuration.rates | object | apiSeconds, storageGB, aiTokens, and plan after clamping. |
configuration.limits | object | requestsPerMinute and requestsPerDay after capping. |
configuration.budget.current | number | Balance. Not overwritten by this call. |
configuration.budget.minimumTopUpThreshold | number | Low-balance threshold after validation. |
configuration.budget.maximumTopUpThreshold | number | Top-up ceiling after validation. |
configuration.featureOverrides | string[] | Overrides after this call. |
message | string | Configuration 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
| Attribute | Type | Description |
|---|---|---|
configuration.billingType | string | stripe, marketplace, or invoice. |
configuration.billingStatus | string | active or suspended, when set. |
configuration.promotionalCodes | array or null | Applied grants. Each item has name, createdAt, and expiresAt. The redemption secret is not included. |
configuration.rates.apiSeconds | number | Floor multiplier for API seconds. |
configuration.rates.storageGB | number | Floor multiplier for storage. |
configuration.rates.aiTokens | number | Floor multiplier for AI tokens. |
configuration.rates.plan | number | Floor multiplier for the plan fee. |
message | string | Success. |
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
| Parameter | Type | Required | Description |
|---|---|---|---|
billingType | string | stripe, marketplace, or invoice. Applied for a system admin. | |
billingStatus | string | active or suspended. Accepted by validation and left unchanged. | |
rates | object | Floor 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.apiSeconds | number | API-seconds floor. Required when rates is sent. | |
rates.storageGB | number | Storage floor. Required when rates is sent. | |
rates.aiTokens | number | AI-token floor. Required when rates is sent. | |
rates.plan | number | Plan-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
| Attribute | Type | Description |
|---|---|---|
configuration | object | Saved MSP configuration. Same shape as the GET response. |
clientsReclamped | number | How many managed organisations were raised to the new floor. Present only when that count is greater than zero. |
message | string | Configuration 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
| Attribute | Type | Description |
|---|---|---|
configuration.billingTo | string | client or msp. |
configuration.billingType | string | stripe, marketplace, or invoice. |
configuration.billingStatus | string | active or suspended. |
configuration.topUpMethod | string | automatic or manual. |
configuration.rates | object | apiSeconds, storageGB, aiTokens, and plan. |
configuration.limits | object | requestsPerMinute and requestsPerDay. |
configuration.budget | object | current, minimumTopUpThreshold, and maximumTopUpThreshold. |
configuration.planTier | string | basic, team, enterprise_basic, enterprise_security, enterprise_governance, or enterprise_custom. |
configuration.planStatus | string | active, upgrade_requested, downgrade_scheduled, payment_failed, or expired. |
configuration.featureOverrides | string[] | Features granted outside the plan. |
configuration.promoOverrides | string[] | Features granted by promotional codes. |
message | string | Success. |
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
| Attribute | Type | Description |
|---|---|---|
plan.planTier | string | Stored tier. |
plan.planStatus | string | active, upgrade_requested, downgrade_scheduled, payment_failed, or expired. |
plan.planPendingTier | string or null | Tier waiting on payment or a scheduled downgrade. |
plan.planPendingInvoiceId | string or null | Invoice that must be paid before an upgrade or renewal applies. |
plan.planPendingEffectiveAt | string or null | When a scheduled downgrade takes effect. |
plan.planExpiresAt | string or null | End of the current paid period. |
plan.effectivePlanTier | string | Tier used for feature checks. |
plan.features | string[] | Features included for effectivePlanTier. |
plan.displayName | string | Label for the effective tier. |
plan.prices | object | Monthly fee for each tier after the MSP plan multiplier. |
message | string | Success. |
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
| Parameter | Type | Required | Description |
|---|---|---|---|
planTier | string | ✓ | 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
| Attribute | Type | Description |
|---|---|---|
plan | object | Plan view. Same attributes as the GET plan response. |
invoiceId | string | Stripe invoice id. Present when an upgrade invoice was created. |
message | string | Upgrade 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
| Attribute | Type | Description |
|---|---|---|
plan | object | Plan view after the renewal request. |
invoiceId | string | Stripe invoice id, when a renewal invoice was created. |
message | string | Renewal 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
| Attribute | Type | Description |
|---|---|---|
message | string | Top-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
| Parameter | Type | Required | Description |
|---|---|---|---|
code | string | ✓ | Redemption secret. It is not returned. |
Returns the grant that matched, whether it was already applied, and the full grant list.
Response
| Attribute | Type | Description |
|---|---|---|
applied.name | string | Public name of the grant. |
applied.createdAt | string | ISO-8601 time the grant was applied. |
applied.expiresAt | string | ISO-8601 expiry. |
alreadyApplied | boolean | true when this grant name was already stored. |
promotionalCodes | array | Grants after this call. Each item has name, createdAt, and expiresAt. |
message | string | Promotional code applied, or Promotional code already applied. |
Shared status codes, the 5.5 MB cap, and plan rate limits are on Platform limits.