Legacy API (v1 Compatibility)
If you are migrating from TestFairy, your existing CI/CD scripts and plugins will continue to work without changes. The legacy API endpoints are fully supported alongside the new API v3.
Authentication
All endpoints require authentication. You can authenticate using any of the following methods:
| Method | Example |
|---|---|
X-API-Key header | curl -H "X-API-Key: YOUR_KEY" ... |
Bearer token | curl -H "Authorization: Bearer YOUR_KEY" ... |
api_key POST param | curl -F api_key=YOUR_KEY ... |
Response Format
All responses return JSON with a status field ("ok" or "fail").
Success
{ "status": "ok", ... }
Error
{ "status": "fail", "code": 5, "message": "..." }
Upload
POST /api/upload
Upload an APK, AAB, or IPA file. The app is automatically matched by package name, or created if it doesn't exist.
curl https://saucelabs-poc.testfairy.com/api/upload \
-F api_key=YOUR_API_KEY \
-F file=@app-release.apk \
-F changelog="Bug fixes and improvements" \
-F notify=on \
-F testers_groups="QA,Beta"
| Parameter | Required | Description |
|---|---|---|
file | Yes | Binary file (.apk, .aab, or .ipa) |
changelog | No | Release notes. Also accepted as comment or release_notes |
notify | No | Set to on or 1 to email testers about the new build |
testers_groups | No | Comma-separated group names to notify. Also accepted as groups or invitation_groups |
app_version | No | Override the auto-detected version string |
version_code | No | Override the auto-detected version code |
folder_name | No | Assign the app to a folder |
Projects
GET /api/1/projects/
List all apps in the organization.
curl -H "X-API-Key: YOUR_KEY" https://saucelabs-poc.testfairy.com/api/1/projects/
Response includes: id, name, packageName, platform, icon, folder_name, created.
Builds
GET /api/1/projects/{projectId}/builds/
List all builds for an app.
GET /api/1/projects/{projectId}/builds/{buildId}
Get a single build.
Response includes: id, projectId, appName, appVersion, appVersionCode, filesize, iconUrl, fileName, uploadedAt, uploadedVia, installsCount, tags, releaseNotes, installLink.
PATCH /api/1/projects/{projectId}/builds/{buildId}/
Update a build's metadata.
| Parameter | Description |
|---|---|
comment | Update release notes |
tags | Comma-separated tags |
DELETE /api/1/projects/{projectId}/builds/{buildId}
Delete a build. Requires admin permissions.
GET /api/1/projects/{projectId}/builds/{buildId}/download/
Get the download URL for a build. Returns a pre-signed URL or install page link.
POST /api/1/projects/{projectId}/builds/{buildId}/invites/
Send install invitations to testers for a build.
Testers
GET /api/1/testers
List all testers in the organization.
Response includes: id, email, name.
POST /api/1/testers/
Add a tester. Creates the user if they don't exist. Requires admin permissions.
| Parameter | Required | Description |
|---|---|---|
email | Yes | Tester's email address |
group | No | Group name to add the tester to |
GET /api/1/testers/{testerId}
Get a single tester's details.
DELETE /api/1/testers/{testerId}
Remove a tester from the organization. Requires admin permissions.
POST /api/1/testers/{testerId}/block/
Block a tester. Requires admin permissions.
DELETE /api/1/testers/{testerId}/block/
Unblock a tester. Requires admin permissions.
Tester Groups
GET /api/1/testers/groups
List all tester groups. Response includes: id, name, testersCount.
POST /api/1/testers/groups
Create a tester group. Requires admin permissions.
| Parameter | Required | Description |
|---|---|---|
groupName | Yes | Name for the new group |
POST /api/1/testers/groups/{groupId}
Add a tester to a group by email. Auto-creates the tester if they don't exist. Requires admin permissions.
| Parameter | Required | Description |
|---|---|---|
email | Yes | Tester's email address |
DELETE /api/1/testers/groups/{groupId}
Remove a tester from a group by email. Requires admin permissions.
| Parameter | Required | Description |
|---|---|---|
email | Yes | Tester's email address (POST body or query param) |
Groups
GET /api/1/groups/
List all groups in the organization. Response includes: id, name, testersCount.
GET /api/1/groups/{groupId}
Get a single group.
GET /api/1/groups/{groupId}/testers/
List all testers in a group. Response includes: id, email, name.
GET /api/1/groups/{groupId}/projects/
List all apps assigned to a group. Response includes: id, name, packageName, platform.
Webhooks
GET /api/1/webhooks/
List all webhooks for the organization.
Response includes: id, name, url, status, actions, projectIds, createdAt.
POST /api/1/webhooks/
Create a webhook. Requires admin permissions.
| Parameter | Required | Description |
|---|---|---|
url | Yes | Webhook callback URL |
name | No | Display name (defaults to URL) |
actions | No | Comma-separated event types to listen for |
project_ids | No | Comma-separated app IDs (empty = all apps) |
GET /api/1/webhooks/{webhookId}
Get a single webhook.
POST /api/1/webhooks/{webhookId}
Update a webhook. Requires admin permissions. Accepts the same parameters as create (all optional).
DELETE /api/1/webhooks/{webhookId}
Delete a webhook. Requires admin permissions.
Sites (Teams)
In the legacy API, "sites" correspond to "teams" in the current platform.
GET /api/1/sites/
List all sites (teams) in the organization.
Response includes: id, name, projectsCount, membersCount.
GET /api/1/sites/{siteId}
Get a single site (team).
POST /api/1/sites/
Create a site (team). Requires admin permissions.
| Parameter | Required | Description |
|---|---|---|
name | Yes | Site (team) name |
Audit Logs
Requires admin permissions. All audit endpoints support the following query parameters:
| Parameter | Description |
|---|---|
page | Page number (default: 1) |
limit | Results per page (default: 25, max: 100) |
action | Filter by action type |
search | Search in email and action data |
from | Start date (ISO 8601) |
to | End date (ISO 8601) |
GET /api/1/audits/
List audit log entries.
GET /api/2/audits/
List audit log entries (v2 format with pagination metadata).
GET /api/2/audits/admin-trail/
List admin activity audit trail.
GET /api/2/audits/tester-trail/
List tester activity audit trail.
Response includes: id, user (id, email), ipAddress, action, data, createdAt, plus pagination object.
Error Codes
| Code | HTTP Status | Meaning |
|---|---|---|
1 | 400 | Missing or invalid required parameter |
2 | 400 | Duplicate resource (already exists) |
5 | 401/403 | Invalid API key or insufficient permissions |
112 | 400 | Empty file uploaded |
121 | 400 | Invalid file type |
133 | 400 | Organization not configured (no team found) |
404 | 404 | Resource not found |
CI/CD Examples
Gradle (Android)
curl https://saucelabs-poc.testfairy.com/api/upload \
-F api_key=$API_KEY \
-F file=@app/build/outputs/apk/release/app-release.apk \
-F changelog="$(git log -1 --pretty=%B)"
Xcode (iOS)
curl https://saucelabs-poc.testfairy.com/api/upload \
-F api_key=$API_KEY \
-F file=@build/MyApp.ipa \
-F changelog="$(git log -1 --pretty=%B)" \
-F notify=on
List apps and builds
# List apps
curl -H "X-API-Key: $API_KEY" https://saucelabs-poc.testfairy.com/api/1/projects/
# List builds for an app
curl -H "X-API-Key: $API_KEY" https://saucelabs-poc.testfairy.com/api/1/projects/123/builds/
# Get download URL
curl -H "X-API-Key: $API_KEY" https://saucelabs-poc.testfairy.com/api/1/projects/123/builds/456/download/
Migration to API v3
To migrate, see the API Migration Guide.