tvlabs upload
Supported Platforms
- Tizen (.wgt, .tpk)
- WebOS (.ipk)
- Android TV (.apk)
- Roku (.zip)
- SmartCast (.zip)
- tvOS (.ipa)
- iOS (.ipa)
- VegaOS (.vpkg)
Don't see the platform you're looking for? Contact us to request support.
Uploading a build
Use tvlabs upload to upload build packages to the TV Labs Platform. This command will create a build in your organization's default App that can be used in access, automation or appium sessions.
tvlabs upload <path-to-build-package>

Figure: Example output of the tvlabs upload command.
For usage in a scripting context, use the -i option to output only the build ID. For example:
tvlabs upload -i <path-to-build-package>
408cb137-1b75-4322-b8f6-9eccf5b6b149
Uploading builds to a specific App
Use the --application or -a option to upload a build for a specific App in your TV Labs organization. You can create a new App in the App Management page.
tvlabs upload -a <application-slug> <path-to-build-package>
Tizen .wgt package IDs
A Tizen application ID is <package ID>.<app name>, and the package ID Samsung issues is exactly 10 alphanumeric characters. TV Labs checks the tizen:application id declared in your .wgt's config.xml when the build is processed, and rejects a package ID that does not conform — a device otherwise accepts the sideload and fails with the opaque install failed[118, -19], reason: Parsing error.
A rejected build gets a Failed processing status, and the reason names the offending value both in the upload result and on the build page:
config.xml declares tizen:application id "ExampleApp1.main"; its package ID "ExampleApp1" is 11 characters, but Tizen requires exactly 10 alphanumeric characters.
Rebuild the package with a conforming package ID and upload it again. Native .tpk packages are exempt from this rule — their application IDs are reverse-DNS and may contain hyphens.
RESTful API
Builds may also be uploaded via the TV Labs platform API. POST /api/build/upload creates the build and returns its ID along with a pre-signed URL that you then PUT the package to:
BUILD_UPLOAD=$(curl -X POST -H "Authorization: Bearer <your-api-key>" 'https://tvlabs.ai/api/build/upload')
BUILD_ID=$(echo $BUILD_UPLOAD | jq -r '.build_id')
UPLOAD_URL=$(echo $BUILD_UPLOAD | jq -r '.url')
curl -X PUT -T <path-to-build-package> $UPLOAD_URL
The pre-signed URL is valid for 5 minutes. If your upload has not started within that window, request a new one with another POST.
Builds uploaded this way are always created in your organization's default App. To target a specific App, use tvlabs upload -a <application-slug> instead.
The Content-Type does not matter
No Content-Type header is required, and the one you send does not decide how your package is read. TV Labs identifies the archive from its leading bytes — every supported package is a zip (.wgt, .tpk, .apk, .zip, .ipa), an ar archive (.ipk), or zstd-compressed (.vpkg) — so a Content-Type that disagrees with the file is ignored rather than believed. Neither curl -T nor tvlabs upload sends one, and both extract fine.
The stored Content-Type is only consulted for an archive whose leading bytes TV Labs does not recognize, where these types select the format:
| Package format | Content-Type |
|---|---|
.wgt, .tpk (Tizen) | application/zip |
.apk (Android TV) | application/vnd.android.package-archive or application/zip |
.zip (Roku) | application/zip |
.zip (SmartCast) | application/zip |
.ipa (tvOS, iOS) | application/zip |
.ipk (WebOS) | application/vnd.debian.binary-package or application/x-deb |
.vpkg (VegaOS) | application/zstd |
Extraction is asynchronous
The POST only reserves the build. TV Labs extracts the package metadata — including the application ID that drivers such as appium-lg-webos-driver need — after your PUT completes, so a build's application ID is populated shortly after the upload finishes rather than when the POST returns.
A session started immediately after the PUT can therefore race extraction. On WebOS that surfaces as 'appId' can't be blank. Either wait until the build reports a Completed processing status, or pass the application ID yourself with appium:appId — see Build-derived capabilities.
Checking the build
Open the build at https://tvlabs.ai/app/builds/<build_id>, or find it from the App management page. The build shows a Processing Status of Unprocessed while extraction is pending, then Completed or Failed, alongside the extracted Application ID. A Failed build also shows a Failure Details card explaining why.
A build whose PUT never completed is marked Failed roughly 15 minutes after the POST, with no application ID and a failure reason saying the upload never completed — it does not sit in Unprocessed forever. Upload it again with a fresh URL from a new POST.
tvlabs upload is the fully supported path: it names the build after your file, records its size, and reports the extracted application ID before it exits. Reach for the REST API when the CLI is not available in your environment.