Guides
How to Prevent Presigned Video URLs from Expiring in AI API Jobs
- Written by
- Sonilo Team
- Published

Mint the source URL as late as possible and submit it only when its remaining lifetime covers your maximum queue delay, bounded retry window, provider fetch-start budget, and safety margin. If you cannot guarantee that window, upload the video file instead.
Mint the source URL as late as possible and submit it only when its remaining lifetime covers your maximum queue delay, bounded retry window, provider fetch-start budget, and safety margin. If you cannot guarantee that window, upload the video file instead.
By Sonilo Team · Facts verified August 13, 2026
Disclosure: Sonilo publishes this guide and is used as the API example. The URL-window formula and tests below are an application design, not a Sonilo, Amazon Web Services, or Google Cloud service-level guarantee.
A URL returning a video now is not enough. An application may queue the generation, retry after a temporary failure, or hand the URL to another service that begins reading later. The access credential must still work at the latest acceptable fetch start.
The safe rule for source-video URLs
Use this budget before submitting a signed URL:
Required URL window = maximum queue delay + bounded retry window + provider fetch-start budget + safety margin*
Compare that total with the URL's remaining lifetime. Reject the submission when the remaining lifetime is shorter, even if a preflight request succeeds now. A successful check proves present access only. It does not reserve future access.
The Sonilo Video to Music API accepts exactly one source: an uploaded `video` file or a `video_url`. That one-of-two contract gives an application a practical fallback. When a URL's access window is uncertain, send the file rather than forwarding a fragile credential.
Why signed input URLs fail
Amazon S3 documents presigned URLs as time-limited object access. The configured expiry is not the only clock: a URL minted with temporary credentials can stop working when those credentials expire or are revoked, even when the URL requested a later expiry.
Google Cloud Storage likewise documents that anyone possessing an active signed URL can use it for the permitted operation until its access period ends. In both systems, the URL carries access authority. Treat the full query string as a secret and keep it out of logs, analytics, support screenshots, and customer-visible error messages.
The failure boundary is therefore wider than “URL expired before POST.” A source can also become unavailable while work waits in an application queue, between bounded retries, or before a downstream reader starts its request.
A worked URL-window calculation
Suppose a platform has measured or deliberately capped these values:
| Budget component | Example | What it covers |
|---|---|---|
| Maximum application queue delay | 5 minutes | Time between URL minting and the first generation attempt |
| Bounded retry window | 10 minutes | The last permitted retry after a definitive temporary failure |
| Provider fetch-start budget | 10 minutes | Application allowance for the remote reader to begin its request |
| Safety margin | 5 minutes | Clock skew, scheduling jitter, and normal variance |
The required remaining lifetime is 30 minutes. A URL with 45 minutes left passes with 15 minutes spare. A URL with 20 minutes left fails, even though it is still valid at submission.
Do not copy these numbers as universal defaults. Measure queue delay in your system, cap the retry window, and set the provider-start allowance from observed storage access logs or a conservative operational target. If that last value is unknown, prefer file upload or mint the URL inside the worker immediately before the API call.
The tested acceptance contract
The accompanying `video-url-window-v1` Node.js gate takes an explicit expiry timestamp and four budgets. It never tries to reverse-engineer provider-specific signature parameters. The same application code that creates the signed URL must pass the authoritative `expiresAt` value.
The gate performs seven tested checks:
- Accept a URL only when its remaining lifetime exceeds the complete budget.
- Reject a URL that is valid now but too short for the complete budget.
- Expose an exact-boundary result with zero spare time instead of hiding it.
- Require HTTPS.
- Reject usernames or passwords embedded in the URL.
- Require an explicit expiry rather than guessing from query parameters.
- Remove the query string and fragment before producing a log-safe URL.
All seven deterministic tests passed on August 13, 2026. They prove the calculator and input rules, not remote storage availability or provider fetch timing.
| Acceptance record | Why retain it |
|---|---|
| Internal request ID | Joins the URL decision to the generation request |
| Storage provider and immutable object key | Identifies the exact source without storing the signed query |
| Object version, generation, or ETag when available | Detects accidental source replacement within the storage provider's semantics |
| URL minted time and explicit expiry | Reconstructs the credential window |
| Each budget component | Makes the acceptance decision auditable |
| Required, remaining, and spare window | Shows why the gate passed or failed |
| API endpoint and attempt number | Connects the source decision to retry history |
Mint the URL at the last responsible moment
Do not mint a signed URL in the browser and let it age through editing, moderation, and queue backlogs. Store an immutable source-object identity instead. When a worker is ready to submit the generation request, mint a fresh read URL, apply the window gate, and call the API immediately.
If a definitive temporary failure permits a retry, mint a new URL for that retry instead of reusing the aging one. If the POST outcome is ambiguous, do not assume a new URL makes replay safe. Apply the separate duplicate AI audio job guard before resubmitting a generation request.
For accepted async requests, persist the returned task ID and use the bounded polling workflow. Source readiness, request deduplication, and task polling are three different controls.
Preflight helps, but it is not a guarantee
A server-side `HEAD` or small authorized read can catch an already-expired URL, missing object, or obvious permission problem. It cannot prove the URL will remain valid later. Some origins also handle `HEAD` differently from `GET`, so treat preflight as an early rejection signal, not proof of future fetchability.
Query Sonilo account services before choosing file upload so the application uses the current account's max upload size and capabilities instead of hardcoding a universal limit.
When your backend fetches a user-controlled URL itself, expiry is only one concern. The OWASP SSRF Prevention Cheat Sheet recommends allowlisting trusted destinations where possible, checking resolved IPv4 and IPv6 addresses, controlling redirects, and adding network-layer egress restrictions. A syntax check alone is not a complete SSRF defense. Stage untrusted remote media into controlled storage through a reviewed ingestion service before sending it to a generation API.
Choose file upload when the URL contract is weak
Use a direct file upload when the source exists only on a user device, the signed expiry is unknown, queue delay is unbounded, retries can extend beyond the URL window, or storage access depends on headers the API cannot send.
Use `video_url` when the object is already in controlled storage, the application can mint a fresh read credential inside the worker, and the remaining lifetime passes the complete budget. The Sonilo video-to-music API guide covers the broader request and response workflow; this page governs only the source-access decision.
What this pattern does not guarantee
The URL-window gate does not guarantee that a storage service stays available, that an object contains valid video, that a provider begins fetching within your allowance, or that an ambiguous generation POST is safe to repeat. It also does not replace storage access controls, SSRF defenses, media validation, monitoring, or the provider's current API contract.
The narrow promise is useful: no job enters your queue with a source credential that your own published timing budget already proves is too short.
If your application already stores edited video and needs a soundtrack generated from it, review the current Sonilo endpoint contract. Decide the source-access window before the first production request, not after the first expired input.


