> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appeeky.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TestFlight

> Beta groups, testers, test notes, and external beta review — manage TestFlight distribution programmatically

Manage the full TestFlight lifecycle: create beta groups, invite testers, set per-build "What to Test" notes, and submit builds for external beta review.

<Note>
  All endpoints require [App Store Connect authentication](/docs/app-store-connect-overview#authentication). Destructive operations require `"confirm": true` in the request body.
</Note>

***

## Beta Groups

### List / Create / Delete

```
GET    /v1/connect/apps/:appId/beta-groups
POST   /v1/connect/apps/:appId/beta-groups
DELETE /v1/connect/beta-groups/:betaGroupId        (confirm: true)
```

### Create Body

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "name": "External Beta",
  "publicLinkEnabled": true,
  "publicLinkLimit": 1000,
  "publicLinkLimitEnabled": true,
  "feedbackEnabled": true
}
```

Only `name` is required. Enabling the public link returns a shareable TestFlight invite URL.

### Manage Group Membership

Add or remove **builds** or **testers** in a group:

```
PATCH /v1/connect/beta-groups/:betaGroupId/builds
PATCH /v1/connect/beta-groups/:betaGroupId/testers
Body: { "operation": "add", "ids": ["BUILD_OR_TESTER_ID"] }
```

`operation` is `add` or `remove`.

***

## Beta Testers

### List Testers

```
GET /v1/connect/beta-testers?appId=...&email=...&groupId=...
```

### Create Tester

```
POST /v1/connect/beta-testers
Body: {
  "email": "tester@example.com",
  "firstName": "Test",
  "lastName": "User",
  "betaGroupIds": ["GROUP_ID"]
}
```

`email` and at least one `betaGroupIds` entry are required — Apple only accepts testers created directly into a group.

### Delete Tester

```
DELETE /v1/connect/beta-testers/:betaTesterId
Body: { "confirm": true }
```

Removes the tester from **all** your apps.

### Resend Invitation

```
POST /v1/connect/beta-testers/:betaTesterId/invitations
Body: { "appId": "APP_ID" }
```

***

## TestFlight Metadata

### App-level (Test Information tab)

Beta description, feedback email, marketing and privacy URLs — per locale:

```
GET   /v1/connect/apps/:appId/beta-app-localizations
POST  /v1/connect/apps/:appId/beta-app-localizations
PATCH /v1/connect/beta-app-localizations/:localizationId
```

Create body: `{ "locale": "en-US", "description": "...", "feedbackEmail": "...", "marketingUrl": "...", "privacyPolicyUrl": "..." }`

### Build-level ("What to Test")

```
GET    /v1/connect/builds/:buildId/beta-localizations
POST   /v1/connect/builds/:buildId/beta-localizations
Body:  { "locale": "en-US", "whatsNew": "New tape styles. Please test export." }
PATCH  /v1/connect/beta-localizations/:localizationId
DELETE /v1/connect/beta-localizations/:localizationId   (confirm: true)
```

### Beta App Review Details

Contact and demo account shown to Apple's beta review team:

```
GET   /v1/connect/apps/:appId/beta-review-detail
PATCH /v1/connect/beta-review-details/:reviewDetailId
```

Attributes match [App Review Details](/docs/app-store-connect-release#app-review-details) (contact fields, demo account, notes).

### Build Beta Detail (notifications)

```
GET   /v1/connect/builds/:buildId/beta-detail
PATCH /v1/connect/build-beta-details/:buildBetaDetailId
Body: { "autoNotifyEnabled": true }
```

***

## External Beta Review

Builds must pass Apple's beta review before external testers can install them.

### Get / Submit

```
GET  /v1/connect/builds/:buildId/beta-review-submission
POST /v1/connect/builds/:buildId/beta-review-submission
Body: { "confirm": true }
```

The submit endpoint verifies the build is valid and not expired before submitting.

### Withdraw from Review

```
DELETE /v1/connect/builds/:buildId/beta-review-submission
Body: { "confirm": true }
```

<Note>
  Apple's API has no "cancel beta review" call — the only supported withdrawal is **expiring the build**, which is what this endpoint does. The build can no longer be tested afterwards, so use it deliberately.
</Note>

***

## Typical Beta Workflow

```
1. POST /connect/apps/:appId/beta-groups                       → create group w/ public link
2. POST /connect/beta-testers                                  → invite testers by email
3. POST /connect/builds/:buildId/beta-localizations            → "What to Test" notes
4. POST /connect/builds/:buildId/beta-review-submission        → external review
5. PATCH /connect/beta-groups/:groupId/builds {operation:add}  → distribute build to group
```

## Role Requirements

| Action                              | Minimum Role |
| ----------------------------------- | ------------ |
| Beta groups, testers, localizations | App Manager  |
| Beta review submission              | App Manager  |
