For AI agents: markdown of this page — /docs-content-en/cowork/subscription-preview.md documentation index — /llms.txt
Tier change preview for Cowork/Code
GET /v1/cowork/subscription/preview
Returns the amount that will be debited immediately when switching to the specified tier, and the date the change takes effect. This previews one specific operation, not a tier's catalog price.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parametertier (query) |
Typestring | Requiredyes | DescriptionTier to switch to: FREE, PRO, MAX, ULTRA. For the tier catalog, see GET /v1/cowork/state |
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/cowork/subscription/preview?tier=PRO" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/cowork/subscription/preview?tier=PRO" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
const url = 'https://vibecode.bitrix24.com/v1/cowork/subscription/preview?tier=PRO'
const res = await fetch(url, {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
if (!res.ok) {
const { error } = await res.json()
console.error(error.code, error.message)
} else {
const preview = await res.json()
console.log(preview.scheduled
? `No charge now; the change takes effect on ${preview.effectiveFrom}`
: `Charge: ${preview.netVibes} Vibe credits`)
}
JavaScript — OAuth application
const url = 'https://vibecode.bitrix24.com/v1/cowork/subscription/preview?tier=PRO'
const res = await fetch(url, {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const preview = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldtier |
Typestring | DescriptionThe tier from the request |
FieldchargeVibes |
Typestring | DescriptionPrice of the operation in Vibe credits, returned as a decimal string. Includes a platform promotion discount when one applies to this purchase. "0" when the operation is free |
FieldcreditVibes |
Typestring | DescriptionCredit for the unused portion of the paid month. Nonzero only for an upgrade and only when this feature is enabled for the account |
FieldnetVibes |
Typestring | DescriptionAmount debited immediately: chargeVibes minus creditVibes, never below zero. Show this value to the user |
FieldeffectiveFrom |
Typestring | DescriptionWhen the change takes effect, in ISO 8601 format: either the response time or the end of the paid period when scheduled: true |
Fieldscheduled |
Typeboolean | Descriptiontrue — the change takes effect at the end of the paid period and nothing is debited now |
Fieldcurrency |
Typestring or null | DescriptionISO 4217 currency code for topping up the wallet, or null when top-up is unavailable |
FieldtopUpAvailable |
Typeboolean | DescriptionWhether topping up the wallet is available for this account |
Vibe credit amounts are returned as decimal strings with an integer part and up to six digits after the decimal point, using the same format as balances and transactions. Do not convert them to floating-point numbers because this loses precision for fractional amounts.
Response example
Switching from the free tier to PRO when wallet top-up is available:
{
"tier": "PRO",
"chargeVibes": "20",
"creditVibes": "0",
"netVibes": "20",
"effectiveFrom": "2026-08-11T11:11:14.115Z",
"scheduled": false,
"currency": "USD",
"topUpAvailable": true
}
Error response example
400 — the tier parameter is missing or has an unsupported value:
{
"success": false,
"error": {
"code": "INVALID_QUERY",
"message": "Query parameter `tier` is required and must be one of FREE, PRO, MAX, ULTRA."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_QUERY |
DescriptionThe tier parameter is missing, or its value is not one of FREE, PRO, MAX, ULTRA |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
| HTTP401 | CodeINVALID_API_KEY |
DescriptionThe key is not recognized — no such key exists on the platform |
| HTTP403 | CodeINSUFFICIENT_SCOPE |
DescriptionThe key lacks the vibe:cowork scope |
| HTTP404 | CodeCOWORK_NOT_ACTIVATED |
DescriptionNo Cowork/Code subscription found for the user and portal |
| HTTP429 | CodeRATE_LIMITED |
DescriptionThe rate limit for the portal-user pair has been exceeded. The platform-wide limit is 30 requests per minute. The limit currently in effect for your key is returned in the x-ratelimit-limit header. |
| HTTP503 | CodeCOWORK_FEATURE_DISABLED |
DescriptionCowork/Code is disabled at the platform level |
For the full list of common API errors, see Errors.
Known specifics
A successful response (200) is the preview object itself, without a success wrapper. Errors arrive in the envelope { success: false, error: { code, message } }. Determine success by the HTTP status (res.ok).
The tier price and the debited amount are different numbers. The tiers[].feeVibes field in the Cowork/Code subscription state is the tier's catalog price. The actual amount already differs from it in five cases:
- selecting the active tier again — no charge,
- a downgrade queued for the end of the paid period — no immediate charge,
- requesting an already queued downgrade again — also no charge,
- an upgrade with credit for the unused portion of the paid month — full price minus the credit,
- an active platform promotion —
chargeVibesandnetVibescontain the promotional price, which is exactly the amount that will be charged. The discount does not apply when renewing an already paid tier.
The platform enables the last three features, and they become available without a client update. For this reason, build the confirmation screen from the preview rather than the catalog price.
The netVibes and scheduled fields tell you whether a charge occurs immediately. You do not need to reimplement the rules for no-charge tier changes: netVibes: "0" together with scheduled: true means nothing is charged now and the change takes effect at the end of the paid period.
If the request fails, show the tier price as the upper bound. The actual charge never exceeds the tier price, so after a network error or rejected request, show feeVibes as an upper bound on the confirmation screen. The actual charge may be lower. This matches the behavior in your Vibecode account.
Show the wallet top-up button based on the value of topUpAvailable, not on whether the field is present in the response. A response with topUpAvailable: false and currency: null is a normal state: top-up is currently unavailable for this account. It is not a request error.
Amounts are returned only in Vibe credits: the response has no monetary tier price, and currency is not one. currency is the currency the wallet owner uses for top-up; there is no amount-and-currency pair for a tier. This is not an omission from the response schema: there is no single Vibe-to-money rate. The rate is determined when a specific top-up package is purchased and varies by package and currency. Vibe credits are granted based on the pre-tax amount, while the customer pays the amount including tax. A Bitrix24 promotion changes the amount paid without changing the number of credits granted. Any single number would be a promise the platform does not make.
In the UI, show netVibes in Vibe credits and, when topUpAvailable is true, provide a link to checkout. Before payment, checkout shows the monetary amount in the user's currency, including tax.
The platform-wide limit is 30 requests per minute. The limit currently in effect for your key is returned in the x-ratelimit-limit header. The limit applies to each user in each Bitrix24 account. The response is not cached (Cache-Control: no-store): amounts are calculated at request time.
A limit reset granted by a promotion does not increase the credit. After a limit reset, creditVibes is computed as if there had been no reset: the part of the monthly quota used before the reset stays used and does not count towards the credit for the remainder.