Skip to main content

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:

MethodExample
X-API-Key headercurl -H "X-API-Key: YOUR_KEY" ...
Bearer tokencurl -H "Authorization: Bearer YOUR_KEY" ...
api_key POST paramcurl -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"
ParameterRequiredDescription
fileYesBinary file (.apk, .aab, or .ipa)
changelogNoRelease notes. Also accepted as comment or release_notes
notifyNoSet to on or 1 to email testers about the new build
testers_groupsNoComma-separated group names to notify. Also accepted as groups or invitation_groups
app_versionNoOverride the auto-detected version string
version_codeNoOverride the auto-detected version code
folder_nameNoAssign 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.

ParameterDescription
commentUpdate release notes
tagsComma-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.

ParameterRequiredDescription
emailYesTester's email address
groupNoGroup 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.

ParameterRequiredDescription
groupNameYesName 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.

ParameterRequiredDescription
emailYesTester's email address

DELETE /api/1/testers/groups/{groupId}​

Remove a tester from a group by email. Requires admin permissions.

ParameterRequiredDescription
emailYesTester'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.

ParameterRequiredDescription
urlYesWebhook callback URL
nameNoDisplay name (defaults to URL)
actionsNoComma-separated event types to listen for
project_idsNoComma-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.

ParameterRequiredDescription
nameYesSite (team) name

Audit Logs​

Requires admin permissions. All audit endpoints support the following query parameters:

ParameterDescription
pagePage number (default: 1)
limitResults per page (default: 25, max: 100)
actionFilter by action type
searchSearch in email and action data
fromStart date (ISO 8601)
toEnd 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​

CodeHTTP StatusMeaning
1400Missing or invalid required parameter
2400Duplicate resource (already exists)
5401/403Invalid API key or insufficient permissions
112400Empty file uploaded
121400Invalid file type
133400Organization not configured (no team found)
404404Resource 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.