Automation API Reference
Overview
The Automation API lets CI/CD pipelines, release scripts, and internal build systems protect mobile app artifacts programmatically. It is intentionally focused: request a signed upload URL for an APK, AAB, or IPA, upload the artifact, monitor the protection job, and download the protected output from a signed URL.
Use the Automation API when AppTego protection is one step in a larger mobile release pipeline. If your integration needs to manage users, tenant settings, logs, support records, security configuration, signing-key administration, or build reporting, use the Management API instead.
Base URL: https://api.apptego.com or your custom endpoint.
Workflow At A Glance
| Step | Endpoint | Result |
|---|---|---|
| Authenticate | Request header | AppTego validates the automation key. |
| Request upload | POST /automate/upload | A build job ID and signed upload URL are returned. |
| Upload binary | Signed URL from the upload response | Your pipeline uploads the APK, AAB, or IPA directly to the signed URL. |
| Complete multipart upload | POST /automate/upload/complete | Required only when the upload response uses multipart upload. |
| Abort multipart upload | POST /automate/upload/abort | Optional cleanup if a multipart upload fails. |
| Check status | GET /automate/status/{jobId} | Your pipeline can wait, fail, retry, or continue based on status. |
| Download | GET /automate/download/{jobId} | A signed download URL is returned when the job completes. |
There is no GET /automate/jobs endpoint. Use the Management API when an integration needs broader build history or reporting.
Authentication
All Automation API requests require an automation key in the Authorization header:
Authorization: Bearer <key_id>:<key_secret>
Create automation keys in the AppTego Portal under Automation Keys. Store the full key_id:key_secret value in your CI or release-secret manager. Automation keys require a Team or Enterprise plan, and a disabled key is rejected immediately. Each tenant can have up to 10 automation keys. The secret is shown only when the key is created and cannot be retrieved later.
Automation API keys use the raw key_id:key_secret pair in the Bearer token. Do not Base64-encode automation keys; Base64 encoding is used by Management API tokens instead.
Production Integration Checklist
| Check | Recommended practice |
|---|---|
| Secret storage | Store the automation key in a secret manager, not in source control or job output. |
| Environment | Use dev or staging for validation jobs and prod only for approved release candidates. |
| Artifact metadata | Save the source artifact name, protected artifact name, AppTego job ID, commit SHA, configuration version, and release metadata. |
| Upload handling | Upload the binary to the signed URL returned by AppTego. Do not send the binary directly to /automate/upload. |
| Timeout handling | Treat processing builds as pending until your pipeline timeout is reached. |
| Error handling | Surface AppTego error messages in CI logs, but redact secrets, signed URLs, and sensitive paths. |
| QA | Test the protected output before publishing it to users. |
Request An Upload URL
POST /automate/upload
Content-Type: application/json
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
file_name | String | Yes | Base filename for the APK, AAB, or IPA. Path components are stripped. The filename must use a lowercase .apk, .aab, or .ipa extension. |
platform | String | Yes | android or ios. Use APK or AAB for Android and IPA for iOS. |
version | String | Yes | Configuration version. Accepted aliases are case-insensitive and include dev, development, stg, staging, prod, and production. Responses use development, staging, or production. |
file_size | Number | No | Artifact size in bytes. Include this so the API can reject files over 2 GB and return multipart instructions for files 100 MB or larger. If omitted, the API cannot preflight size or switch to multipart upload. |
signing_key_id | String | No | Signing key to use for this build. Omit it to use the tenant default signing key when one is configured, or set none to skip signing-key metadata. |
{
"file_name": "app-release.apk",
"platform": "android",
"version": "prod",
"file_size": 52428800
}
The upload request validates the tenant plan, active automation key, build limits, enabled controls for the selected platform/version, filename, file size, platform, version, and signing key selection. At least one protection or detection control must be enabled for the selected platform and configuration version before a build can start.
Single-Part Response
For files below the multipart threshold, or when file_size is omitted, the response includes upload_url. Upload the binary with an HTTP PUT to that URL.
{
"url": "https://apps.apptego.com/signed-upload-url",
"upload_url": "https://apps.apptego.com/signed-upload-url",
"file_path": "tenant-123/uploads/android/production/1700000000/app-release.apk",
"start_time": 1700000000,
"expires_in": 3600,
"signing_key_id": null,
"job_id": "1700000000"
}
job_id is returned as a string. Pass it exactly as returned to the status and download endpoints.
Upload The Binary
curl -sS -X PUT \
-H "Content-Type: application/octet-stream" \
--data-binary "@app-release.apk" \
"$UPLOAD_URL"
Large File Upload
First-party CI/CD integrations handle large files automatically. Custom integrations should include file_size in the upload request. Files at or above 100 MB return multipart upload instructions with 10 MB chunks.
Multipart Initiation Response
{
"multipart": true,
"upload_id": "multipart-upload-id",
"part_urls": [
"https://apps.apptego.com/signed-part-1",
"https://apps.apptego.com/signed-part-2"
],
"chunk_size": 10485760,
"total_parts": 2,
"file_path": "tenant-123/uploads/android/production/1700000000/app-release.apk",
"start_time": 1700000000,
"expires_in": 3600,
"signing_key_id": null,
"job_id": "1700000000"
}
Upload each chunk with PUT to the matching part_urls entry. Preserve the ETag response header for each part. If any part upload fails, abort the multipart upload before retrying the whole upload. After all parts are uploaded, complete the multipart upload and then poll the same job_id returned by the initiation response.
Complete Multipart Upload
POST /automate/upload/complete
Content-Type: application/json
{
"file_path": "tenant-123/uploads/android/production/1700000000/app-release.apk",
"upload_id": "multipart-upload-id",
"parts": [
{ "ETag": "\"abc123\"", "PartNumber": 1 },
{ "ETag": "\"def456\"", "PartNumber": 2 }
]
}
Abort Multipart Upload
POST /automate/upload/abort
Content-Type: application/json
{
"file_path": "tenant-123/uploads/android/production/1700000000/app-release.apk",
"upload_id": "multipart-upload-id"
}
Check Job Status
GET /automate/status/{jobId}
Begin polling after the binary upload, or multipart completion, has succeeded. A newly uploaded job can briefly return 404 while the build record is being created; retry during normal polling. A persistent 404 means the job ID does not exist for the authenticated tenant.
Processing Response
{
"job_id": "1700000000",
"status": "processing",
"platform": "android",
"version": "production",
"file_name": "app-release.apk",
"created_at": 1700000000,
"updated_at": 1700000000,
"progress": "Queued"
}
Completed Response
{
"job_id": "1700000000",
"status": "completed",
"platform": "android",
"version": "production",
"file_name": "app-release.apk",
"created_at": 1700000000,
"updated_at": 1700000300
}
Failed Response
{
"job_id": "1700000000",
"status": "failed",
"platform": "android",
"version": "production",
"file_name": "app-release.apk",
"created_at": 1700000000,
"updated_at": 1700000300,
"error_message": "Signing failed"
}
Status Values
| Status | Description |
|---|---|
processing | The build record exists and AppTego is queued, launching a worker, downloading inputs, applying protection, packaging, signing, or uploading output. Use progress for the current human-readable stage when present. |
completed | Build succeeded and is ready for download. |
failed | Build failed. Review error_message. |
Download Protected App
GET /automate/download/{jobId}
The response returns a signed download URL. The protected binary is not returned directly from /automate/download/{jobId}.
{
"job_id": "1700000000",
"file_name": "app-release.apk",
"download_url": "https://apps.apptego.com/signed-download-url",
"expires_in": 3600
}
Download links are time-limited. Request a new download URL when a link expires.
Error Responses
| Code | Description |
|---|---|
400 | Invalid JSON, missing or invalid fields, invalid job ID, job not completed, file too large, no enabled controls for the selected platform/version, invalid filename, or invalid signing key selection. |
401 | Authentication failed because the automation key is missing, malformed, unknown, disabled, invalid, or unavailable on the tenant plan. |
403 | Multipart completion or abort was denied because the upload path does not belong to the authenticated tenant. |
404 | Job or endpoint not found. |
405 | HTTP method not allowed for the endpoint. |
429 | Concurrent build or weekly build limit exceeded. Wait for in-progress jobs to finish or reduce pipeline parallelism. |
500 | Internal server error. Retry when appropriate or contact support with the job ID. |
Error Response Format
{
"error": "Description of the error"
}
Rate Limits And Concurrency
- Automation API jobs share build capacity with portal uploads.
- Free tenants cannot use the Automation API. Team and Enterprise tenants can use it, subject to plan limits and tenant-specific overrides.
- Concurrent build limits apply tenant-wide across portal and Automation API builds. Team defaults to 2 concurrent builds and Enterprise defaults to 5 concurrent builds.
- Weekly build limits apply per platform and configuration version. Team defaults to 10 builds per platform/version over 7 days; Enterprise is effectively unlimited unless a tenant-specific limit is configured.
- Status checks should use a reasonable polling interval. The first-party CI integrations use 15 seconds by default.
- If you receive
429 Too Many Requests, wait for another job to complete before uploading another app.
Example: Single-Part Workflow
This example covers artifacts below 100 MB. For larger artifacts, follow the multipart response fields described above or use a first-party CI/CD integration.
set -euo pipefail
API_URL="https://api.apptego.com"
APP_FILE="app-release.apk"
PLATFORM="android"
VERSION="prod"
OUTPUT_FILE="app-release-protected.apk"
FILE_SIZE=$(wc -c < "$APP_FILE" | tr -d '[:space:]')
# 1. Request a signed upload URL.
UPLOAD_RESPONSE=$(jq -n \
--arg file_name "$(basename "$APP_FILE")" \
--arg platform "$PLATFORM" \
--arg version "$VERSION" \
--argjson file_size "$FILE_SIZE" \
'{file_name: $file_name, platform: $platform, version: $version, file_size: $file_size}' | \
curl -sS -X POST "$API_URL/automate/upload" \
-H "Authorization: Bearer $APPTEGO_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @-)
JOB_ID=$(echo "$UPLOAD_RESPONSE" | jq -r '.job_id')
UPLOAD_URL=$(echo "$UPLOAD_RESPONSE" | jq -r '.upload_url')
IS_MULTIPART=$(echo "$UPLOAD_RESPONSE" | jq -r '.multipart // false')
if [ "$IS_MULTIPART" = "true" ]; then
echo "This file requires multipart upload. Use the part_urls, upload_id, and file_path fields."
exit 1
fi
# 2. Upload the app binary to the signed URL.
curl -sS -X PUT \
-H "Content-Type: application/octet-stream" \
--data-binary "@$APP_FILE" \
"$UPLOAD_URL"
# 3. Wait for completion.
while true; do
STATUS_RESPONSE=$(curl -sS "$API_URL/automate/status/$JOB_ID" \
-H "Authorization: Bearer $APPTEGO_API_KEY")
STATUS=$(echo "$STATUS_RESPONSE" | jq -r '.status')
if [ "$STATUS" = "completed" ]; then
echo "Build complete"
break
elif [ "$STATUS" = "failed" ]; then
echo "$STATUS_RESPONSE" | jq -r '.error_message // "Build failed"'
exit 1
fi
sleep 15
done
# 4. Request a signed download URL and download the protected app.
DOWNLOAD_RESPONSE=$(curl -sS "$API_URL/automate/download/$JOB_ID" \
-H "Authorization: Bearer $APPTEGO_API_KEY")
DOWNLOAD_URL=$(echo "$DOWNLOAD_RESPONSE" | jq -r '.download_url')
curl -sS -L "$DOWNLOAD_URL" -o "$OUTPUT_FILE"