MCP spending safeguards
Require concrete user approval, handle quote expiry and price changes, and preserve idempotency without silently increasing the allowed spend.
On this page
Authorization is not spending approval
The official MCP is available in public beta. These safeguards apply to real calls, including calls made by an AI on your behalf.
OAuth scopes permit actions on an account. They do not mean the user approved every future generation. generate_animation is a paid, side-effecting tool: first explain the input, settings, desired outputs, and proposed cost, then obtain approval.
Tool annotations are safety hints for clients, not substitutes for user consent or server enforcement. cancel_animation is also side-effecting; do not cancel somebody's task just to test a connection.
Two server-side guards
quote_id: a short-lived quote owned by the current user and OAuth client. Generation validates its pricing-relevant parameters, current price, expiry, and binding to one logical generation key.max_credits: an explicit nonnegative upper bound on the current quote for this generation.
At least one is required. They can be supplied together. Neither is a recurring budget for unlimited tasks: repeated new operations can spend repeatedly below the per-operation cap.
Keep the exact approved request stable even where a field is not part of the pricing calculation. User intent includes the image and prompt, not only price.
Refusals should pause generation
| Error | Correct next step |
|---|---|
SPEND_CONFIRMATION_REQUIRED |
Obtain approval and provide a quote or explicit cap |
QUOTE_EXPIRED |
Re-quote; show the updated amount before approval |
QUOTE_MISMATCH |
Reconcile the changed generation/export settings |
QUOTE_CHANGED |
Show the new price and request approval |
QUOTE_ALREADY_USED |
Recover the original task; do not recycle the quote for a new operation |
CREDIT_LIMIT_EXCEEDED |
Stop; ask whether to lower the request or approve a different cap |
INSUFFICIENT_CREDITS |
Report the balance issue; do not buy credits automatically |
Never “fix” a refusal by dropping the cap, silently raising it, switching accounts, changing the image, or generating a new idempotency key.
Retries and cancellation
Persist the approved request and idempotency_key before creation. A timeout does not mean nothing happened. Reuse the original logical key and request to recover the task, then poll its ID. Do not let an AI reconnect or restart create another generation by default.
The deduplication scope includes the user, operation, and OAuth client. Changing clients is not a safe retry of an uncertain creation, even with the same idempotency string. Refreshing an access token for the same client does not itself change that client identity.
If the user changes the desired output, treat that as a new decision requiring an updated quote and appropriate approval. Do not retry terminal failures without first checking their available outputs.
Cancellation is best effort; work already performed can remain charged. Wait for a terminal state and report the actual credit accounting and usable assets.
Confirmed Seedance content-review rejection before output/export returns the original one-click workflow credits. Report the task's credits.refunded, credits.released, and net credits.charged; do not promise a return before it is recorded, and do not treat returned credits as approval for another generation. Account/payment exceptions can require review.
Keep the trail useful but private
Keep task IDs, asset IDs, approved limits, error codes, and request IDs in the appropriate private application state. Do not emit API keys, OAuth tokens, Base64 images, signed upload/download URLs, or private prompts to analytics.
API callers should not copy these MCP-only parameters into POST /animations. The API quickstart explains its different quote semantics.
Was this page helpful?
No search queries, code, or free text are collected. This switch controls documentation interactions only; general site analytics follow the privacy policy. Privacy policy