Upload a build
Uploads do not pass through the Appsinity API. Studio asks a worker for a presigned URL and the browser PUTs the file directly to storage.appsinity.com.
The two-request flow
- Presign. The page POSTs
{ fileName, contentType, contentEncoding, size, type, gameId, appId, version }to the upload worker's/upload-urlwith your bearer token. - PUT. A single
XMLHttpRequest PUTsends the whole File to the returned URL. SigV4 signs the request in the worker; the payload is unsigned. - Verify. The client asks
/api/storage/file-infofor the stored byte size and compares it to the local file. A mismatch is fatal; an unreachable lookup is not — it logs and marks the resultsizeVerified: false. - Attach. The resulting URL is written onto the build or media record, and the listing's download chain begins to resolve.
POST https://appsinity-upload.virexeonofficial-aaa.workers.dev/upload-url
{
"fileName": "mygame-release.aab",
"contentType": "application/octet-stream",
"size": 48227328,
"type": "game-build",
"gameId": "<game id>",
"version": "<key prefix or timestamp>"
}
PUT https://storage.appsinity.com/public/games/<gameId>/builds/<version>/mygame-release.aab
?X-Amz-Algorithm=AWS4-HMAC-SHA254&X-Amz-SignedHeaders=content-type%3Bhost
&X-Amz-Expires=10800&X-Amz-Signature=...Where your file lands
Two consequences follow. First, the bucket name is part of the path: a public file is storage.appsinity.com/public/<key>, and a URL without /public/ will not resolve. Second, version defaults to Date.now() when you do not supply a prefix, so two uploads of the same file create two distinct build directories rather than overwriting one.
| Upload category | Object key | Public URL |
|---|---|---|
game-build | games/{gameId}/builds/{version}/{file} | storage.appsinity.com/public/games/… |
game-web | games/{gameId}/web/[{version}/]{relPath} | Folder root is served as a directory |
app-file | apps/{appId}/files/{version}/{file} | storage.appsinity.com/public/apps/… |
app-media | apps/{appId}/media/{file} | No version segment at all |
What the progress bar means
- The strip shows the file name,
loaded / totalbytes, and a rounded percent. - For a web-game folder it is cumulative bytes across every file in the folder, uploaded sequentially.
- The only literal label is Preparing web game. There is no "Uploading…", "Processing…" or "Complete" string, no ETA and no speed.
- On success the bar goes to 100% and hides. On failure it only hides — the reason appears in the browser console under
[Appsinity upload]. - The presigned URL is valid for 3 hours (10,800 s), but the page never reads that expiry.
Every error string you can meet
Nothing is retried automatically. Every one of these is a single attempt you either repeat by hand or report.
| Message | Cause | What to do |
|---|---|---|
| Sign in again before uploading. | No bearer token in localStorage | Log out of Studio and back in |
| File too large (X GB). Max 5.00 GB. | Above the client's 5 GiB ceiling | Split or rebuild with fewer assets |
| Blocked file type: <ext> | The extension is on the denylist | Repackage; see Upload limits and file types |
| Presign API failed (401). | Token rejected by the worker | Sign in again |
| Presign API failed (400). | Bad payload — missing gameId or appId | Retry from the correct sheet |
| Upload API did not return a signed URL. | Worker secrets missing or storage unreachable | Wait and retry, then report to devhelp |
| Upload API returned a stale signed URL without Content-Encoding. Hard refresh the dashboard and upload again. | Cached worker bundle | Hard-refresh Studio, then retry |
| Direct MinIO PUT failed (503): … | Storage host refused the write | Retry later; if it repeats, report the file name and time |
| Direct MinIO PUT could not reach storage at <host>. | DNS or CORS failure on storage.appsinity.com | Corporate proxy; try another network |
| Direct MinIO PUT blocked: backend returned unsafe upload host … | The presigned URL was not the public HTTPS storage domain | Report it — the backend handed out a wrong URL |
| Could not verify file size: (console only) | The file-info lookup failed | No action; the upload succeeded but is unverified |
Frequently asked questions
Can I upload with curl instead of the dashboard?
The presign endpoint needs your Studio bearer token, and the PUT it returns is ordinary S3, so a scripted upload is possible in principle. Nothing on Appsinity documents or supports it, and the version key you invent will not match what the listing expects.
Does the uploader record which platform the build is for?
No. There is no platform field anywhere in the upload or the presign payload — the platform is inferred from the extension and from the listing's own platform string.
How do I replace a bad upload?
Upload the correct file and save the build record so the listing points at the new URL. The old object stays in storage until Appsinity prunes it.
Developer publishing support: [email protected]
General support: [email protected]
Partnerships: [email protected]
APPSINITY