AkaPhoneDocs
REST API

Uploads API

Upload an APK straight to storage with a presigned PUT URL, confirm it, then install it on any device for 7 days.

Uploads move APK files from you to AkaPhone storage without passing through the API. The full walk-through, including the install step and a one-file script, is in Install an APK.

Create an upload#

POST/v1/uploads

Declares a file and returns a presigned URL to PUT it to.

Body field Type Default Description
filename string required 5–128 characters: letters, digits, ., _, -, spaces; must start with a letter or digit and end in .apk. Spaces become _. Android App Bundles (.aab) are rejected; build a universal APK.
size_bytes integer required Exact file size in bytes; at most 314,572,800 (300 MB).
content_type string "application/vnd.android.package-archive" The Content-Type you will PUT with.
curl -X POST https://akaphone.abhgnx-417.workers.dev/v1/uploads \
  -H "Authorization: Bearer $AKAPHONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename": "app-release.apk", "size_bytes": 48211337}'

Response 201 Created

JSON
{
  "upload": {
    "id": "upl_01m5vqsywgw57haqkjnexz",
    "filename": "app-release.apk",
    "size_bytes": 48211337,
    "status": "pending"
  },
  "put_url": "https://<account>.r2.cloudflarestorage.com/akaphone-artifacts/apks/usr_01m5vqsywg3mxj7dyxv9q9/upl_01m5vqsywgw57haqkjnexz/app-release.apk?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&...",
  "headers": { "content-type": "application/vnd.android.package-archive" },
  "expires_in": 900
}
Error When
400 invalid_request Bad filename, including .aab bundles (filename must be a plain .apk file name …), or size_bytes missing, not positive, or over 300 MB (APK must be at most 300 MB).

Upload the file#

PUT the bytes to put_url within expires_in seconds, sending each header in headers and exactly size_bytes bytes. This request goes to storage, not to the API: do not add your Authorization header.

curl -X PUT "$PUT_URL" \
  -H "Content-Type: application/vnd.android.package-archive" \
  --data-binary @app-release.apk

Storage answers 200 on success. A 403 usually means the URL expired, or the Content-Type or length differs from what you declared.

Complete an upload#

POST/v1/uploads/:id/complete

Confirms the object is in storage and marks the upload uploaded. Idempotent.

curl -X POST https://akaphone.abhgnx-417.workers.dev/v1/uploads/upl_01m5vqsywgw57haqkjnexz/complete \
  -H "Authorization: Bearer $AKAPHONE_API_KEY"

Response 200 OK

JSON
{ "upload": { "id": "upl_01m5vqsywgw57haqkjnexz", "status": "uploaded" } }
Error When
404 not_found Unknown upload.
409 conflict The file is not in storage yet (Object not found in storage: upload the file to put_url first).
400 invalid_request The stored file is over 300 MB; it is deleted.

Install it#

Pass the upload id to POST /v1/devices/:id/apps. One upload can be installed on any number of devices. Uploads are deleted after 7 days.