inExternalTesting property

bool? inExternalTesting
final

Whether external testers can install this build now, or null when that cannot be said.

Nullable rather than false-by-default, and the choice is the one usable argues in the other direction. That flag gates an action — releasing a build whose state is not understood — so failing closed to false is a refusal and is safe. This one gates a report: false here is the claim external testers do not have this build, and making an unread relationship or an unnamed state say it out loud is the defect this field was added to fix rather than a safe default. Null says the question was not answered, which is what a consumer should show.

False for an expired build whatever else is true of it. TestFlight withdraws a build after ninety days, so a build that cleared review and is attached to an external group is still one nobody can install — and this answered true for exactly that combination until review caught it. The false is a refusal like usable's rather than a claim, and it is the one reading here that does not need betaGroups to have been read.

Two facts and not one, once it is not expired: true when the build has cleared beta review — ExternalBuildState.betaApproved, ExternalBuildState.readyForBetaTesting or ExternalBuildState.inBetaTestingand betaGroups holds at least one group whose kind is BetaGroupKindEntry.external. Apple's verdict is not delivery, and an attachment made while review is still pending is not delivery either, so neither half answers on its own.

Reading the state alone was this field's first shape, and it was a constant false against a real account: over 51 iOS builds measured 2026-09-14, Apple's terminal external state after review is BETA_APPROVED and IN_BETA_TESTING did not occur once, so fourteen builds external testers demonstrably had reported that they did not.

Null when this listing was answered short and the missing part could have changed the answer — see unresolvedBetaGroups and unresolvedBuildBetaDetail, which say which of the two inputs went missing and are 0 and false on a complete read.

The qualifier is load-bearing and this said null when answered short without it, which is wrong in the one case a reader would hit first: a build with a resolved external group and a shortfall beside it answers true, because the groups that did not arrive could only have added attachments. A shortfall makes an empty external list uninformative, not a non-empty one.

Implementation

final bool? inExternalTesting;