RequestRocketRequestRocketDocs
API ReferenceMSP API

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

MethodEndpointDescriptionMin Role
GET/api/msps/{mspId}/configurationsGet your MSP's own configurationmsp_user
PUT/api/msps/{mspId}/configurationsUpdate your MSP's own configurationmsp_admin
GET/api/msps/{mspId}/clients/{clientId}/configurationsGet a managed client's configurationmsp_user
PUT/api/msps/{mspId}/clients/{clientId}/configurationsUpdate a managed client's configurationmsp_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

FieldTypeDescription
billingTypestringHow your MSP is billed: stripe, marketplace, or invoice
billingStatusstringAccount status: active or suspended
promotionalCodesobject[] | nullPromotional codes on the MSP. Each entry has name, createdAt, and expiresAt.
ratesobjectFraction of the retail price your MSP pays for each metric. Managed client rates cannot be set below these values.
rates.apiSecondsnumberFraction of the retail API-seconds price. 1 is 100% of retail.
rates.storageGBnumberFraction of the retail storage price. 1 is 100% of retail.
rates.aiTokensnumberFraction of the retail AI-token price. 1 is 100% of retail.
rates.plannumberFraction 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

FieldTypeDescription
billingTypestringHow the client is billed: stripe, marketplace, or invoice
billingTostringWho is charged: "client" (client pays directly) or "msp" (your MSP is charged)
billingStatusstringAccount status: active or suspended
topUpMethodstringautomatic tops up when the balance falls below the minimum. manual tops up on demand.
regionAccessstring[]Allowed deployment regions for this client
promotionalCodesobject[] | nullPromotional codes on the client. Each entry has name, createdAt, and expiresAt.
ratesobjectFraction 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.apiSecondsnumberFraction of the retail API-seconds price. 1 is 100% of retail. 0.85 is 85% of retail.
rates.storageGBnumberFraction of the retail storage price.
rates.aiTokensnumberFraction of the retail AI-token price.
rates.plannumberFraction of the retail plan price.
budget.currentnumberCurrent credit balance. Read only.
budget.minimumTopUpThresholdnumberBalance at which an automatic top-up starts. Cannot be stored below 5.
budget.maximumTopUpThresholdnumberBalance a top-up restores the client to. Cannot be stored below 20, and must be at least 10 above minimumTopUpThreshold.
sharingobjectWhich resources this client shares: proxyCredentials, targetCredentials, targets, proxies.
limits.requestsPerMinutenumberRequest rate limit. Capped at the platform maximum.
limits.requestsPerDaynumberDaily request limit. Capped at the platform maximum.
planTierstringCurrent plan: basic, team, enterprise_basic, enterprise_security, enterprise_governance, or enterprise_custom
planStatusstringactive, upgrade_requested, downgrade_scheduled, payment_failed, or expired
featureOverridesstring[]Extra features enabled for this client
promoOverridesstring[]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

FieldTypeRequiredDescription
billingTostringNo"client" or "msp". Defaults to the existing value
billingTypestringNoOnly "stripe" is settable by MSP admins
topUpMethodstringNo"automatic" or "manual"
regionAccessstring[]NoDeployment regions this client may use
rates.apiSecondsnumberNoFraction of the retail API-seconds price. Clamped to 0.7–1, then raised to the MSP rate if lower
rates.storageGBnumberNoFraction of the retail storage price. Same clamp as apiSeconds
rates.aiTokensnumberNoFraction of the retail AI-token price. Same clamp as apiSeconds
rates.plannumberNoFraction of the retail plan price. Same clamp as apiSeconds
budget.minimumTopUpThresholdnumberNoApplied only when billingTo is "msp" and billingType is "stripe". Raised to 5 if lower
budget.maximumTopUpThresholdnumberNoApplied 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.

ValueBehaviour
"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.

ValueMeaning
1100% of the retail charge
0.990% of the retail charge
0.880% of the retail charge
0.770% 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

StatusMessageCause
400Input failed data validationInvalid field types or values in the request body
400Cannot bill to MSP: no payment method on fileSwitching to billingTo: "msp" but MSP has no Stripe payment method
400Cannot bill to MSP: no payment method on file. Please add a payment method...MSP has a Stripe customer but no saved payment method
404Client not found or not linked to this MSPThe clientId does not exist or is not a managed client of this MSP

Next Steps

On this page