AI video API cancellation: States, Billing, and Retention
A developer clicks Cancel on a video generation screen, closes the tab, and later discovers a completed video and a charge. AI video API cancellation explains why those events are not necessarily contradictory: a user interface action, a local scheduling decision, a provider execution state, and a financial adjustment describe different things. A button proves that your application recorded an intention, not that remote computation stopped or money returned.
This distinction matters when building video features with GenRelay or another generative media API. The useful mental model is a set of independent facts, rather than a single Boolean named cancelled. This explainer defines those facts and demonstrates their separation with executable local code.
What is AI video API cancellation?
AI video API cancellation is the process of attempting to prevent or stop a video generation job, with the outcome determined by where that job exists and what the provider documents.
A job is one tracked unit of generation work. A terminal state is a documented final execution outcome that no longer represents active processing. Cancellation intent is the user's request to stop; it is not itself a terminal provider state.
Four distinct actions commonly receive the same label:
| Action | What it establishes | What it does not establish |
|---|---|---|
| Cancel a locally queued job | Your scheduler will not dispatch that job, if cancellation wins the scheduling race | Anything about work already submitted |
| Abandon the interface | The user stopped watching or requesting updates | That generation stopped |
| Send a documented cancellation request | Your application attempted the provider's supported cancellation operation | A final outcome or refund |
| Observe a terminal provider state | The provider reported an execution outcome under its documented semantics | Output deletion or a billing adjustment |
These distinctions apply even when the screen displays one Cancel button. Internally, the application needs enough evidence to explain what that button accomplished.
Why does cancelling a local queue differ from stopping remote work?
Cancelling a local queue can prevent submission, whereas stopping remote work requires support and confirmation outside your scheduler.
A local queue holds work that your application has not yet dispatched. A worker is the process that takes queued work and submits it. If the worker claims the job while cancellation is being recorded, a simple check followed by a separate update can let both actions appear successful.
Use an atomic transition: a state change that competing processes cannot split into conflicting decisions. A database transaction can let either dispatch or local cancellation win. Once dispatch begins, treat the remote outcome as potentially unknown rather than assuming the job never left your system.
Closing a browser tab is different again. It may stop polling, which means repeatedly checking status, but does not establish anything about provider execution. Even interrupting an outbound connection does not prove the remote server rejected the request. Submission uncertainty belongs in your recovery process; the discussion of AI video API job recovery covers the related task of restoring reliable job tracking.
Does an accepted cancellation request prove generation stopped?
An accepted cancellation request proves a final stop only when the provider's documentation explicitly gives that response terminal meaning.
A cancellation operation may acknowledge intent before execution has stopped. A timeout leaves acknowledgement uncertain. An unsupported operation offers no cancellation guarantee at all. Interpret documented response semantics, not an optimistic label chosen by your frontend.
A completion race occurs when generation finishes while cancellation is being attempted. In that case, an observed successful terminal outcome can remain the execution truth even though the user no longer wants the video. Keep the user's intent alongside that outcome instead of rewriting success as cancellation.
For integrations using the GenRelay video API, verify the current documentation for the selected workflow before exposing remote cancellation behavior. This article does not establish that a GenRelay cancellation endpoint exists. If cancellation support is not documented, an interface can offer “Stop watching” or cancellation of undispatched local work without suggesting that provider computation will stop.
How can a local state reducer represent these facts?
A local state reducer can preserve cancellation intent, execution evidence, and financial evidence separately without implementing any provider API.
A reducer is a function that produces a new state from a previous state and an event. The following standard-library Python example uses application-owned event names and normalized states; none are provider fields or request formats. Save the block as a Python file and run it locally. It makes no network calls.
from __future__ import annotations
from dataclasses import dataclass, replace
from decimal import Decimal
TERMINAL = frozenset({"succeeded", "failed", "cancelled"})
@dataclass(frozen=True)
class State:
local: str = "queued"
watching: bool = True
cancel_intent: bool = False
cancel_attempted: bool = False
remote: str = "unknown"
charge: Decimal | None = None
refund: Decimal | None = None
conflict: bool = False
def reduce(state, event, value=None):
if event == "cancel_local":
local = "cancelled" if state.local == "queued" else state.local
return replace(state, local=local, cancel_intent=True)
if event == "dispatch":
if state.local != "queued":
raise ValueError("Job is not dispatchable")
return replace(state, local="dispatched")
if event == "abandon_ui":
return replace(state, watching=False)
if event == "documented_cancel_attempt":
if state.local != "dispatched":
raise ValueError("No dispatched job")
return replace(state, cancel_intent=True, cancel_attempted=True)
if event == "provider_observation":
if state.local != "dispatched":
raise ValueError("No dispatched job")
if value not in TERMINAL | {"queued", "running"}:
raise ValueError("Unrecognized normalized state")
if state.remote in TERMINAL:
if value in TERMINAL and value != state.remote:
return replace(state, conflict=True)
return state # Duplicate or late nonterminal observation.
return replace(state, remote=value)
if event == "billing_reconciled":
charge, refund = map(Decimal, value)
if charge < 0 or refund < 0:
raise ValueError("Negative amount")
return replace(state, charge=charge, refund=refund)
raise ValueError("Unknown local event")
local = reduce(State(), "cancel_local")
assert local.local == "cancelled" and local.remote == "unknown"
try:
reduce(local, "dispatch")
except ValueError:
pass
else:
raise AssertionError("Cancelled local job dispatched")
sent = reduce(State(), "dispatch")
abandoned = reduce(sent, "abandon_ui")
assert not abandoned.watching and abandoned.remote == "unknown"
assert not abandoned.cancel_intent
requested = reduce(sent, "documented_cancel_attempt")
assert requested.remote == "unknown" and requested.refund is None
finished = reduce(requested, "provider_observation", "succeeded")
assert finished.cancel_intent and finished.remote == "succeeded"
assert reduce(finished, "provider_observation", "running") == finished
assert reduce(finished, "provider_observation", "succeeded") == finished
assert reduce(finished, "provider_observation", "cancelled").conflict
stopped = reduce(requested, "provider_observation", "cancelled")
assert stopped.charge is None and stopped.refund is None
# Synthetic accounting evidence, not a provider price or refund policy.
settled = reduce(finished, "billing_reconciled", ("1.00", "0.00"))
assert settled.charge == Decimal("1.00")
assert settled.refund == Decimal("0.00")
assert settled.remote == "succeeded"
print("All local cancellation assertions passed.")
The example assumes serialized events for one job. Production systems must also validate event origin, associate evidence with the correct provider job, and persist transitions atomically. Conflicting terminal observations raise a review flag instead of silently replacing history. Ignoring late nonterminal observations prevents a completed job from appearing active again.
The financial event represents an already reconciled accounting snapshot, not an instruction to issue a refund. Likewise, the cancellation-attempt event should enter a real application only after a documented operation was attempted. Recording it cannot make an unsupported capability exist.
How should billing and retention relate to cancellation?
Billing and retention should be reconciled independently because execution cancellation does not establish either a refund or deletion.
Billing reconciliation means matching recorded usage, charges, credits, and adjustments to authoritative financial evidence. A budget reservation is an internal allowance held for anticipated spending, not proof of an actual provider charge. Keep uncertain submitted work distinguishable from undispatched work when deciding whether to release that allowance. See AI video API budget reservations for that accounting distinction.
Retention is the period and conditions under which inputs, outputs, and job records remain stored. A successfully cancelled execution might still have input files or diagnostic records. A completed generation that lost the cancellation race might leave an output your user does not want displayed. Suppressing that output locally is not remote deletion.
Record separate evidence for execution outcome, financial settlement, and deletion status. Apply documented retention controls where available, and communicate uncertainty where they are absent. The synthetic monetary values in the example illustrate state handling, not observed cancellation charges or refund rules for GenRelay or any model.
What are common questions about AI video API cancellation?
The recurring questions concern what the interface can promise and which evidence supports that promise.
Does closing the tab cancel my video generation?
No conclusion about remote execution follows from closing the tab. Your application may stop displaying progress while generation continues. Resume status tracking through a trusted job record rather than inferring cancellation from a disconnected client.
Can I mark a job cancelled immediately after the user clicks?
You can record cancellation intent immediately. Mark local cancellation complete when your scheduler has prevented dispatch. For submitted jobs, keep that intent separate from the provider outcome until documented evidence supports a terminal status.
Does a cancelled provider state mean I receive a refund?
Not by itself. Execution status and financial treatment are separate facts. Consult the applicable billing terms and reconcile actual accounting records before describing a charge reversal as completed.
What if a video finishes after cancellation was requested?
Preserve both facts: cancellation was requested and generation succeeded. Decide whether to show or retain the output under your application policy, then resolve charges and any deletion request separately. This gives developers and users an explanation that matches the evidence rather than the button label.