Update an installed app
const url = 'https://qinto-api.blotout.io/teams/7b8d1a52-6c1e-4b6f-9a30-2f8a54d1c3e9/domains/3f2a9c81-5d47-4e0b-8c66-91b2a7f04d15/apps/facebook-capi';const options = { method: 'PATCH', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"enabled":false,"approvedCharges":{"pixel-sync":{"upToCents":4900,"trialDays":14}}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PATCH \ --url https://qinto-api.blotout.io/teams/7b8d1a52-6c1e-4b6f-9a30-2f8a54d1c3e9/domains/3f2a9c81-5d47-4e0b-8c66-91b2a7f04d15/apps/facebook-capi \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "enabled": false, "approvedCharges": { "pixel-sync": { "upToCents": 4900, "trialDays": 14 } } }'Flips the app-level kill switch with { enabled }, or moves the app to another ready version with { appVersionId }. A disabled app stops receiving everything while keeping its configuration.
How it works
A version move is the site’s own decision and needs no membership of the app’s organization. With installDependencies the apps the version needs install in the same step, and if one fails nothing changes. Enabling an app installed under a bundle purchase that has ended gives it the app’s current price: charge_approval_required carries appSlug and charge; repeat with them in approvedCharges once a person accepts it. Approving needs purchase_apps on the credential and on its user.
Required permissions
domain:manage_domain_apps:writeon all domains, or on the addressed domain when its id is in the route
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Unique id (UUID) of the team that owns the addressed resources, as shown in the team settings on the Blotout platform.
Example
7b8d1a52-6c1e-4b6f-9a30-2f8a54d1c3e9Unique id (UUID) of the team that owns the addressed resources, as shown in the team settings on the Blotout platform.
Unique id (UUID) of the site, as returned by the site operations.
Example
3f2a9c81-5d47-4e0b-8c66-91b2a7f04d15Unique id (UUID) of the site, as returned by the site operations.
Immutable slug of the app, as shown by the list operation.
Example
facebook-capiImmutable slug of the app, as shown by the list operation.
Request Bodyrequired
Section titled “Request Bodyrequired”The switch state, or the version to move to.
object
The replacement app-level switch state.
Example
falseThe app’s current price a person was shown, by app slug, when enabling an app installed under a bundle purchase that has ended; required when the call answers charge_approval_required.
object
object
The most the install can charge one site in a month, in US cents: the base price plus the usage cap.
Example
4900The free days before the first charge; 0 when the app has no trial.
Example
14Example
{ "pixel-sync": { "upToCents": 4900, "trialDays": 14 }}object
The ready version to move the app to.
Example
7d8e9f0a-1b2c-4d3e-9f4a-5b6c7d8e9f0aInstalls the apps the version needs that the site does not have yet, in the same step as the install or version move, and approves the plan’s private-function calls; required to answer dependencies_required.
Example
trueThe slugs of the apps this call installs as dependencies that run without visitor consent, each acknowledged; required when acknowledgement_required names one.
Example
[ "consent-manager"]Accepts the additional access a newer version requests, including any query params or cookies it newly captures; required when the change answers approval_required.
Example
falseRecords that this app runs without visitor consent; required when the call answers acknowledgement_required.
Example
falseThe charge a person was shown for each app that charges the team, by app slug: this app and every app the call installs with it, as charge_approval_required or the dependencies_required plan gave them. Approving it also accepts the developer’s terms. The call is refused with the current charge when an entry is missing, the amount went up or the free days went down since it was shown.
object
object
The most the install can charge one site in a month, in US cents: the base price plus the usage cap.
Example
4900The free days before the first charge; 0 when the app has no trial.
Example
14Example
{ "pixel-sync": { "upToCents": 4900, "trialDays": 14 }}Responses
Section titled “Responses”The switch outcome, or what the version change did.
object
Whether the switch actually changed.
object
Id of the installation the call affected.
What the call did: a first install, a version move, or nothing (the version was already selected).
Example
{ "updated": true}invalid_params — A path parameter failed validation (for example a malformed UUID); details pinpoints the offending parameter. invalid_body — The JSON body is unparseable or failed schema validation; details pinpoints the offending fields when the body could be parsed.
object
Machine-readable error slug; switch on this value rather than on the HTTP status alone.
Field-level validation errors: a tree keyed by input property, each node carrying an errors array of human-readable messages. Render it to help the caller correct the request.
object
Example
{ "error": "invalid_params", "details": { "errors": [], "properties": { "teamId": { "errors": [ "Invalid UUID" ] } } }}unauthenticated — The Authorization: Bearer token is missing, malformed, or no longer valid. Generate a team API token or obtain a new OAuth access token.
object
Machine-readable error slug; switch on this value rather than on the HTTP status alone.
Example
{ "error": "unauthenticated"}no_payment_method — The team pays by card and has no payment method on file, so nothing was deployed or installed. Add a card on the team’s Billing page, then retry. team_unpaid — The team has an unpaid invoice, so it cannot install or enable an app that charges, buy a bundle, or add a site that charges. Nothing changed. Pay what is owed on the team’s Billing page, then retry.
object
Machine-readable error slug; switch on this value rather than on the HTTP status alone.
Human-readable reason for this specific failure, intended for display — do not parse it programmatically.
Example
{ "error": "no_payment_method", "message": "The Cloudflare API token is invalid or expired."}forbidden — The bearer credential lacks the required permission or belongs to another team, or its user lacks the organization role a developer operation needs. Update its policies, use a credential bound to the addressed team, or ask an organization owner for the role; message states the reason when one is known.
object
Machine-readable error slug; switch on this value rather than on the HTTP status alone.
Human-readable reason for this specific failure, intended for display — do not parse it programmatically.
Example
{ "error": "forbidden", "message": "The Cloudflare API token is invalid or expired."}not_found — The addressed resource does not exist within this team; check the id and retry.
object
Machine-readable error slug; switch on this value rather than on the HTTP status alone.
Example
{ "error": "not_found"}version_not_ready — The addressed version is still a draft; finalize the push, then retry. version_not_approved — The site got the app from the app store, so it can run only approved versions. Name another version, or omit the version to get the newest approved one. version_below_minimum — Blotout set a minimum version for this app, and the named version is below it. Name the minimum version or a newer one, or omit the version to get the newest one the site may run. version_not_offered — Blotout has suspended this app, and the named version was published during the suspension. Name a version published before the suspension, or retry once the suspension is lifted. cap_reached — The operation would exceed a site-app capacity limit — either the installed-app count or the worker access-token environment. message names the exhausted capacity. subscription_item_limit — The team’s Stripe subscription holds the most lines it can, so no further app or bundle that charges can be added to it; message names the app or bundle. Nothing was installed or bought. Contact support. quota_reached — An object the version declares (a KV namespace, Durable Object class, Pipeline, Hyperdrive config, …) would push the site’s host Cloudflare account past its per-account ceiling. message names the object type and the account’s count; free objects or have the ceiling raised, then retry. multiple_not_allowed — The app allows only one install per site, or a version change would leave more installs than the target version allows. message states the conflict. browser_budget — A version’s browser code, or a large value its browser code reads, would push the site’s q.js past its size budget; shrink the value, or remove or shrink another app first. removal_pending — A previous uninstall of this app is torn down as part of this call, and that teardown could not finish — because a deployment for the site is already running, or Cloudflare refused a delete. Nothing was left half-removed and the site’s scheduled cleanup carries on, so retry. install_changed — The app installation was removed or replaced while this request was being prepared. Retry to check the current installation and its charges. app_suspended — Blotout has suspended this app, so nothing ran and nothing changed. The call works again once the suspension is lifted. app_taken_down — Blotout has taken this app down for good, so nothing changed. message states what the call cannot do. Do not retry. binding_conflict — The target version binds a resource name that a version still running on this site binds to something else; message names both. Retrying cannot resolve it — the app must use a different binding name, or remove the binding in one version and re-add it in the next. schema_incompatible — The site has completed a contract D1 migration that the target app version does not include unchanged; select a schema-compatible version. variable_retype — The target version changes a variable’s kind or type while a version still running on this site declares the old shape; message names both. Retrying cannot resolve it — the app must use a different variable name, or remove the variable in one version and re-add it in the next. linked — The app’s storage is shared through a storage link: a child site binds this site’s objects, or this site binds a parent’s. message names the sites; change the link first, or make the change on the parent site. When a child site lacks an app the version needs, message names it; install it on that child first. approval_required — The target version requests more access than the installed one — API scopes, data buckets, or newly captured query params and cookies; message names the additions. Repeat the call with acceptCapabilities once a site manager accepts them. acknowledgement_required — The app, or an app it needs, declares necessary consent, so it runs without visitor consent; message names it. Repeat the call with acknowledgeNecessary for the app, or with the slug of the app it needs in acknowledgeNecessaryDependencies. charge_approval_required — The call charges the team and did not approve that charge, or the charge went up, or its free days went down, after it was shown. charge holds the current charge and message states it. For an app, appSlug names the app the charge belongs to: once a person allowed to purchase apps accepts the charge and the developer’s terms, repeat the call with { "<appSlug>": <charge> } in approvedCharges, keeping the other entries. For a bundle, repeat the call with charge as approvedCharge. Nothing was installed or bought. dependencies_required — The app needs other apps the site does not have yet; plan lists every app it needs, at any depth, and whether the site has it. Nothing was installed. Repeat the call with installDependencies to install the missing apps first, then the app, and approve the plan’s private-function calls. dependency_unavailable — The app needs an app that cannot be installed on this site: it is not in the app store and you are not in its organization, it is suspended or deleted, or it has no version the site may run, or it was removed from this site recently and must be restored or installed on its own first. message names it. Nothing was installed. registry_budget — The change would grow the site’s app configuration past the size the site worker can deploy. Remove an app or an install, or shorten install labels and geo filters, then retry. message states the refusal. sites_paused — Blotout has paused this team’s sites, so nothing was deployed or installed. Every site of the team answers 410 until the pause ends, and uninstalls, switches and settings changes are still recorded. A payment does not end the pause; contact Blotout. deploys_blocked — Blotout has blocked this team’s deploys, so nothing was deployed or installed. The team’s live sites keep running, and uninstalls, switches and settings changes still roll out. A payment does not lift the block; contact Blotout.
object
Machine-readable error slug; switch on this value rather than on the HTTP status alone.
Human-readable reason for this specific failure, intended for display — do not parse it programmatically.
With dependencies_required: what a confirmed call installs and the grants it approves.
object
Every app the app needs, at any depth, in install order (each before the apps that need it).
One app the installed app needs, directly or through another app it needs.
object
Slug of the app that is needed.
Display name of the app that is needed.
Why it is needed, from the app that needs it, or else the description of the needed app; null when neither gives one.
Slug of the app that needs it: the app being installed or another app in the plan.
Whether the site has the app: missing (installed by a confirmed call), installed, or installed-disabled (on the site but switched off).
The version a confirmed call installs; only for a missing app.
Whether the app runs without visitor consent, so its slug must be in acknowledgeNecessaryDependencies; only for a missing app.
The developer’s legal documents, accepted by approving its charge; only for a missing app.
object
The developer’s terms for this app.
The developer’s privacy policy for this app.
What installing it charges, sent back in approvedCharges under this app’s slug to approve it; null when it charges nothing; only for a missing app.
object
The most the install can charge one site in a month, in US cents: the base price plus the usage cap.
The free days before the first charge; 0 when the app has no trial.
The calls the app and the missing apps make to private functions of apps the site would run. A confirmed call approves their grants. Calls to public functions need no grant and are not listed.
Calls from one app to the private functions of another, which need a grant on the site.
object
Slug of the calling app: the app being installed or a missing app.
Slug of the app whose functions it calls.
The private functions it calls, sorted by name.
With charge_approval_required: the current charge to send back under appSlug in approvedCharges.
object
The most the install can charge one site in a month, in US cents: the base price plus the usage cap.
The free days before the first charge; 0 when the app has no trial.
With charge_approval_required: the app the charge belongs to.
Example
{ "error": "version_not_ready", "message": "The Cloudflare API token is invalid or expired.", "plan": { "dependencies": [ { "slug": "consent-manager", "name": "Consent Manager", "reason": "Reads the visitor’s consent state", "neededBy": "facebook-capi", "state": "missing", "version": "1.2.0", "necessary": false, "legal": { "termsUrl": "https://example.com/legal/terms", "privacyUrl": "https://example.com/legal/privacy" }, "charge": { "upToCents": 4900, "trialDays": 14 } } ], "rpcCalls": [ { "callerAppSlug": "facebook-capi", "providerAppSlug": "consent-manager", "functions": [ "getConsent" ] } ] }, "charge": { "upToCents": 4900, "trialDays": 14 }, "appSlug": "pixel-sync"}internal — Unexpected server error. Nothing is guaranteed to have been persisted; idempotent operations are safe to retry.
object
Machine-readable error slug; switch on this value rather than on the HTTP status alone.
Example
{ "error": "internal"}