Configurations
Configure billing mode, retail rate multipliers, and access settings for your MSP and managed clients
Configurations
The configurations API lets you view your MSP's own settings and manage billing, rate multipliers, and access for each managed client organisation.
Endpoints
| Method | Endpoint | Description | Min Role |
|---|---|---|---|
| GET | /api/msps/{mspId}/configurations | Get your MSP's own configuration | msp_user |
| PUT | /api/msps/{mspId}/configurations | Update your MSP's own configuration | msp_admin |
| GET | /api/msps/{mspId}/clients/{clientId}/configurations | Get a managed client's configuration | msp_user |
| PUT | /api/msps/{mspId}/clients/{clientId}/configurations | Update a managed client's configuration | msp_admin |
Your MSP's own rates are managed by RequestRocket support and cannot be changed via the API. Each value is the fraction of the retail price your MSP pays. A managed client's rate for the same metric cannot be set below that fraction.
MSP Configuration
Get MSP Configuration
Retrieve your MSP organisation's own configuration, including billing type, promotional codes, and the fraction of retail price your MSP pays for each metric.
Request
GET /api/msps/{mspId}/configurations HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}Response
{
"configuration": {
"billingType": "stripe",
"billingStatus": "active",
"promotionalCodes": null,
"rates": {
"apiSeconds": 0.8,
"storageGB": 0.8,
"aiTokens": 0.8,
"plan": 0.8
}
},
"message": "Success"
}Response Fields
| Field | Type | Description |
|---|---|---|
billingType | string | How your MSP is billed: stripe, marketplace, or invoice |
billingStatus | string | Account status: active or suspended |
promotionalCodes | object[] | null | Promotional codes on the MSP. Each entry has name, createdAt, and expiresAt. |
rates | object | Fraction of the retail price your MSP pays for each metric. Managed client rates cannot be set below these values. |
rates.apiSeconds | number | Fraction of the retail API-seconds price. 1 is 100% of retail. |
rates.storageGB | number | Fraction of the retail storage price. 1 is 100% of retail. |
rates.aiTokens | number | Fraction of the retail AI-token price. 1 is 100% of retail. |
rates.plan | number | Fraction of the retail plan price. 1 is 100% of retail. |
Example
curl -X GET "https://api.requestrocket.com/api/msps/${MSP_ID}/configurations?configurationType=msp" \
-H "Authorization: ${USER_TOKEN}"const response = await fetch(
`https://api.requestrocket.com/api/msps/${mspId}/configurations?configurationType=msp`,
{
headers: { 'Authorization': process.env.USER_TOKEN }
}
);
const data = await response.json();
console.log('MSP config:', data.configuration);import requests, os
response = requests.get(
f'https://api.requestrocket.com/api/msps/{msp_id}/configurations',
params={'configurationType': 'msp'},
headers={'Authorization': os.getenv('USER_TOKEN')}
)
print(response.json()['configuration'])req, _ := http.NewRequest("GET",
fmt.Sprintf("https://api.requestrocket.com/api/msps/%s/configurations?configurationType=msp", mspId), nil)
req.Header.Set("Authorization", os.Getenv("USER_TOKEN"))
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.requestrocket.com/api/msps/" + mspId + "/configurations?configurationType=msp"))
.header("Authorization", System.getenv("USER_TOKEN"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());Client Configuration
Each managed client has its own configuration. It controls who is billed for usage, what fraction of the retail price that client pays, and their credit balance.
Get Client Configuration
Retrieve the configuration for a specific managed client.
Request
GET /api/msps/{mspId}/clients/{clientId}/configurations HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}Response
{
"configuration": {
"regionAccess": ["us-east-1", "eu-west-1"],
"billingType": "stripe",
"billingTo": "msp",
"billingStatus": "active",
"topUpMethod": "automatic",
"promotionalCodes": null,
"sharing": {
"proxyCredentials": true,
"targetCredentials": true,
"targets": true,
"proxies": true
},
"limits": {
"requestsPerMinute": 300,
"requestsPerDay": 20000
},
"budget": {
"current": 45.20,
"minimumTopUpThreshold": 10,
"maximumTopUpThreshold": 100
},
"rates": {
"apiSeconds": 0.85,
"storageGB": 0.85,
"aiTokens": 0.85,
"plan": 0.85
},
"planTier": "team",
"planStatus": "active",
"planPendingTier": null,
"planPendingInvoiceId": null,
"planPendingEffectiveAt": null,
"planExpiresAt": null,
"planRenewedAt": null,
"planBillingAnchor": null,
"planStripeInvoiceId": null,
"featureOverrides": [],
"promoOverrides": []
},
"message": "Success"
}Response Fields
| Field | Type | Description |
|---|---|---|
billingType | string | How the client is billed: stripe, marketplace, or invoice |
billingTo | string | Who is charged: "client" (client pays directly) or "msp" (your MSP is charged) |
billingStatus | string | Account status: active or suspended |
topUpMethod | string | automatic tops up when the balance falls below the minimum. manual tops up on demand. |
regionAccess | string[] | Allowed deployment regions for this client |
promotionalCodes | object[] | null | Promotional codes on the client. Each entry has name, createdAt, and expiresAt. |
rates | object | Fraction of the retail price for each metric. 1 means 100% of that retail charge. Stored values stay between 0.7 and 1, and at or above your MSP's rate for the same metric. |
rates.apiSeconds | number | Fraction of the retail API-seconds price. 1 is 100% of retail. 0.85 is 85% of retail. |
rates.storageGB | number | Fraction of the retail storage price. |
rates.aiTokens | number | Fraction of the retail AI-token price. |
rates.plan | number | Fraction of the retail plan price. |
budget.current | number | Current credit balance. Read only. |
budget.minimumTopUpThreshold | number | Balance at which an automatic top-up starts. Cannot be stored below 5. |
budget.maximumTopUpThreshold | number | Balance a top-up restores the client to. Cannot be stored below 20, and must be at least 10 above minimumTopUpThreshold. |
sharing | object | Which resources this client shares: proxyCredentials, targetCredentials, targets, proxies. |
limits.requestsPerMinute | number | Request rate limit. Capped at the platform maximum. |
limits.requestsPerDay | number | Daily request limit. Capped at the platform maximum. |
planTier | string | Current plan: basic, team, enterprise_basic, enterprise_security, enterprise_governance, or enterprise_custom |
planStatus | string | active, upgrade_requested, downgrade_scheduled, payment_failed, or expired |
featureOverrides | string[] | Extra features enabled for this client |
promoOverrides | string[] | Extra features granted by promotional codes |
rates values are not unit prices. apiSeconds: 1 means the client pays 100% of the retail API-seconds charge. apiSeconds: 0.85 means they pay 85% of that retail charge. The same applies to storageGB, aiTokens, and plan.
When billingTo is "client", consumption is priced with these client rates. When billingTo is "msp", consumption is priced with your MSP's own rates. In both cases a client rate below your MSP rate is raised to the MSP rate.
budget.minimumTopUpThreshold and budget.maximumTopUpThreshold are only updated when billingTo is "msp" and billingType is "stripe". When the client pays directly, the client manages those thresholds. budget.current is never set from this API.
Update Client Configuration
Update billing mode, rate multipliers, and, when billing to the MSP, credit top-up settings for a managed client.
Submitted rates are clamped into 0.7–1, then raised to your MSP's rate for that metric when they are still lower. They are not rejected. The stored rate is max(submittedRate, mspRate) after the 0.7–1 clamp. A metric you omit keeps its current value.
Request
PUT /api/msps/{mspId}/clients/{clientId}/configurations HTTP/1.1
Host: api.requestrocket.com
Authorization: {user_token}
Content-Type: application/json
{
"billingTo": "msp",
"topUpMethod": "automatic",
"rates": {
"apiSeconds": 0.9,
"storageGB": 0.9,
"aiTokens": 0.9,
"plan": 0.9
},
"budget": {
"minimumTopUpThreshold": 10,
"maximumTopUpThreshold": 100
}
}Request Body
| Field | Type | Required | Description |
|---|---|---|---|
billingTo | string | No | "client" or "msp". Defaults to the existing value |
billingType | string | No | Only "stripe" is settable by MSP admins |
topUpMethod | string | No | "automatic" or "manual" |
regionAccess | string[] | No | Deployment regions this client may use |
rates.apiSeconds | number | No | Fraction of the retail API-seconds price. Clamped to 0.7–1, then raised to the MSP rate if lower |
rates.storageGB | number | No | Fraction of the retail storage price. Same clamp as apiSeconds |
rates.aiTokens | number | No | Fraction of the retail AI-token price. Same clamp as apiSeconds |
rates.plan | number | No | Fraction of the retail plan price. Same clamp as apiSeconds |
budget.minimumTopUpThreshold | number | No | Applied only when billingTo is "msp" and billingType is "stripe". Raised to 5 if lower |
budget.maximumTopUpThreshold | number | No | Applied only when billingTo is "msp" and billingType is "stripe". Raised so it is at least 20 and at least 10 above the minimum |
Response
{
"configuration": {
"billingType": "stripe",
"billingTo": "msp",
"billingStatus": "active",
"topUpMethod": "automatic",
"rates": {
"apiSeconds": 0.9,
"storageGB": 0.9,
"aiTokens": 0.9,
"plan": 0.9
},
"budget": {
"current": 45.20,
"minimumTopUpThreshold": 10,
"maximumTopUpThreshold": 100
}
},
"message": "Configuration updated successfully"
}Example
curl -X PUT "https://api.requestrocket.com/api/msps/${MSP_ID}/clients/${CLIENT_ID}/configurations" \
-H "Authorization: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"billingTo": "msp",
"topUpMethod": "automatic",
"rates": {
"apiSeconds": 0.9,
"storageGB": 0.9,
"aiTokens": 0.9,
"plan": 0.9
},
"budget": {
"minimumTopUpThreshold": 10,
"maximumTopUpThreshold": 100
}
}'const response = await fetch(
`https://api.requestrocket.com/api/msps/${mspId}/clients/${clientId}/configurations`,
{
method: 'PUT',
headers: {
'Authorization': process.env.USER_TOKEN,
'Content-Type': 'application/json'
},
body: JSON.stringify({
billingTo: 'msp',
topUpMethod: 'automatic',
rates: { apiSeconds: 0.9, storageGB: 0.9, aiTokens: 0.9, plan: 0.9 },
budget: { minimumTopUpThreshold: 10, maximumTopUpThreshold: 100 }
})
}
);
const data = await response.json();
console.log('Updated config:', data.configuration);import requests, os
response = requests.put(
f'https://api.requestrocket.com/api/msps/{msp_id}/clients/{client_id}/configurations',
headers={'Authorization': os.getenv('USER_TOKEN')},
json={
'billingTo': 'msp',
'topUpMethod': 'automatic',
'rates': {'apiSeconds': 0.9, 'storageGB': 0.9, 'aiTokens': 0.9, 'plan': 0.9},
'budget': {'minimumTopUpThreshold': 10, 'maximumTopUpThreshold': 100}
}
)
print(response.json())payload := `{
"billingTo": "msp",
"topUpMethod": "automatic",
"rates": {"apiSeconds": 0.9, "storageGB": 0.9, "aiTokens": 0.9, "plan": 0.9},
"budget": {"minimumTopUpThreshold": 10, "maximumTopUpThreshold": 100}
}`
body := bytes.NewBufferString(payload)
req, _ := http.NewRequest("PUT",
fmt.Sprintf("https://api.requestrocket.com/api/msps/%s/clients/%s/configurations", mspId, clientId), body)
req.Header.Set("Authorization", os.Getenv("USER_TOKEN"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
fmt.Println(string(respBody))String json = """
{
"billingTo": "msp",
"topUpMethod": "automatic",
"rates": {"apiSeconds": 0.9, "storageGB": 0.9, "aiTokens": 0.9, "plan": 0.9},
"budget": {"minimumTopUpThreshold": 10, "maximumTopUpThreshold": 100}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.requestrocket.com/api/msps/" + mspId + "/clients/" + clientId + "/configurations"))
.header("Authorization", System.getenv("USER_TOKEN"))
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());Billing Mode: billingTo
The billingTo field controls which Stripe account is charged for a client's consumption.
| Value | Behaviour |
|---|---|
"client" | The client's own Stripe account is charged. Budget thresholds on this API are left unchanged. Consumption is priced with the client rates. |
"msp" | Your MSP's Stripe account is charged. You set topUpMethod and the budget thresholds. Consumption is priced with your MSP's rates. |
Switching a client to billingTo: "msp" requires your MSP to have a valid Stripe payment method on file. If no payment method exists, the request will fail with a 400 error.
Switching billingTo does not change which budget balance tracks usage. The client's own budget always records consumption. It changes which Stripe customer is charged when a top-up occurs, and which rate multipliers are used to price that consumption.
Rates
Each rate is the fraction of the published retail price charged for that metric.
| Value | Meaning |
|---|---|
1 | 100% of the retail charge |
0.9 | 90% of the retail charge |
0.8 | 80% of the retail charge |
0.7 | 70% of the retail charge, the lowest value the API stores |
apiSeconds, storageGB, aiTokens, and plan all use this scale. A value outside 0.7–1 is moved into that range. A value still below your MSP's rate for the same metric is then raised to the MSP rate:
storedRate = max(clamp(submittedRate, 0.7, 1), mspRate)The client therefore cannot be charged a smaller fraction of retail than your MSP pays. When billingTo is "msp", usage is priced from the MSP rates directly. The client rates object is still stored and still follows the same floor.
Error Responses
| Status | Message | Cause |
|---|---|---|
| 400 | Input failed data validation | Invalid field types or values in the request body |
| 400 | Cannot bill to MSP: no payment method on file | Switching to billingTo: "msp" but MSP has no Stripe payment method |
| 400 | Cannot bill to MSP: no payment method on file. Please add a payment method... | MSP has a Stripe customer but no saved payment method |
| 404 | Client not found or not linked to this MSP | The clientId does not exist or is not a managed client of this MSP |