The build you were about to submit
An .ipa exported from Xcode, or an .apk or .aab from your Gradle release task.
Upload the build you are about to submit. Verdict reports what App Review would find, with the guideline and the fix.
Drop your .ipa, .apk, or .aab here
or click to choose a file. Up to 450MB.
Analyzed in seconds. Deleted right after. Never executed.
App Store risk
Trailhead 2.1.0 · com.example.trailhead
4 to resolve
Three steps, no configuration, and no account for the first look. Drop in the build you were about to ship and you get back the same findings a reviewer would reach, each one cited and paired with the change that clears it.
App review is the last gate before a release, and it is the one part of shipping a mobile app that developers have the least visibility into. Roughly a quarter of submissions are rejected, usually for something small and mechanical, and the feedback arrives days later as a guideline number with little explanation.
Verdict closes that gap. It reads the build you are about to submit and reports what a reviewer would find, before you spend a review cycle finding out. Every finding names the rule it comes from and shows the evidence in your own binary, so you can judge it rather than take our word for it.
It is built for the teams who feel this most: solo developers shipping their first app, studios releasing on a schedule, and anyone who has watched a launch slip because of a missing key in a configuration file.
A reviewer’s-eye read of the build you are about to submit, every finding cited to the rule it comes from.
Not an approval guarantee, and it does not speak for Apple or Google, or judge whether an app is original enough.
An independent tool. Not affiliated with, endorsed by, or sponsored by Apple or Google.
Apple publishes what it rejects and why. Five categories account for roughly nine in ten rejections, and most of what drives them is visible in the build before anyone submits it.
Share of rejections by guideline family. Highlighted rows are categories Verdict inspects directly in your build.
Apple App Store transparency reporting and published rejection analyses, 2025 data.
Share of all submissions rejected. Apple reports this annually, so 2025 is the most recent complete year on record.
0%in 2025, the latest full year
Apple App Store transparency reports, 2025 figures published May 2026: 2M+ rejections across 9.1M submissions. Updated when Apple publishes the next report.
The same release, submitted twice versus checked once. Width is proportional to elapsed days.
Eight days back. Most of a rejection cycle is not your work, it is waiting. Reviewers usually stop at the first problem they hit, so the second pass often fails on something they never mentioned in the first.
Illustrative timeline based on commonly reported review and resubmission windows.
These are the rejections developers actually receive, paraphrased from Apple and Google's published templates. Most of them come down to a fact that was already sitting in the build, which is the whole reason this tool exists.
Your app requests access to the camera but the purpose string does not explain how the data will be used.
We were unable to review your app because it was signed with a distribution profile that is not valid for the App Store.
Your app targets an API level below the current requirement. Update targetSdkVersion before this release can be published.
Your app supports account creation but does not include an option to initiate account deletion from within the app.
Your app declares QUERY_ALL_PACKAGES without a permitted use case for broad package visibility.
Your app links against a non public API, which is not permitted on the App Store.
The data safety section does not accurately reflect the data types your app collects and shares.
Your app requests access to the camera but the purpose string does not explain how the data will be used.
We were unable to review your app because it was signed with a distribution profile that is not valid for the App Store.
Your app targets an API level below the current requirement. Update targetSdkVersion before this release can be published.
Your app supports account creation but does not include an option to initiate account deletion from within the app.
Your app declares QUERY_ALL_PACKAGES without a permitted use case for broad package visibility.
Your app links against a non public API, which is not permitted on the App Store.
The data safety section does not accurately reflect the data types your app collects and shares.
Your app uses the AdSupport framework but does not request permission through App Tracking Transparency.
The screenshots in your App Store listing do not show the app in use on the device it targets.
Your app declares a foreground service type that is not matched by a declared and permitted use.
Your app includes user generated content but does not provide a mechanism to report offensive material.
Your app requests background location access without an approved declaration for that use.
Your app unlocks features using a purchase mechanism other than in-app purchase.
We noticed your app provides the same feature set as other apps submitted to the App Store.
Your app uses the AdSupport framework but does not request permission through App Tracking Transparency.
The screenshots in your App Store listing do not show the app in use on the device it targets.
Your app declares a foreground service type that is not matched by a declared and permitted use.
Your app includes user generated content but does not provide a mechanism to report offensive material.
Your app requests background location access without an approved declaration for that use.
Your app unlocks features using a purchase mechanism other than in-app purchase.
We noticed your app provides the same feature set as other apps submitted to the App Store.
Paraphrased from published App Store Review Guidelines and Google Play policy pages. Not quotations from named developers.
The checks
Each check reads a fact out of your build and compares it against a rule Apple or Google published. Nothing here is inferred.
We read the provisioning profile out of its CMS envelope and pull entitlements from the Mach-O code signature blob, so we see the same facts App Store Connect validates against. A debug entitlement or the wrong distribution profile stops a submission before review even begins.
Continuous integration
The expensive rejections are the ones nobody thought to check for. Put Verdict in the pipeline that already builds your artifact and the check stops depending on anyone remembering it.
name: App Store gate
on: [pull_request]
jobs:
verdict:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# ... your existing build step, producing build/App.ipa
- name: Fail if this build would be rejected
run: |
REPORT=$(curl -sS -X POST https://verdict-umber.vercel.app/api/v1/scans \
-H "Authorization: Bearer ${{ secrets.VERDICT_API_KEY }}" \
-F "file=@build/App.ipa")
echo "$REPORT" | jq -r '"Approval risk: \(.score)/100"'
echo "$REPORT" | jq -r '.findings[] | "[\(.severity)] \(.ruleId) \(.title)"'
BLOCKERS=$(echo "$REPORT" | jq '.counts.blocker')
if [ "$BLOCKERS" -gt 0 ]; then
echo "::error::$BLOCKERS blocker(s) would fail App Review"
exit 1
fiVerdict unzips the archive and reads the parts a reviewer's tooling reads: Info.plist or the binary AndroidManifest, the Mach-O load commands, entitlements out of the code signature blob, the provisioning profile inside its CMS envelope, every embedded framework, and the DEX string table. Seconds, not hours, because nothing is ever executed.
A warning that says something is wrong is the easy half. Verdict names the guideline a reviewer would cite, links the official Apple or Google document so you can check the claim yourself, quotes the exact evidence pulled out of your binary, and gives you the specific key, capability, or line to change — ordered by how much score each fix gives back for the work it costs.
Camera API is used but NSCameraUsageDescription is missing
VD-PRIV-01 · Guideline 5.1.1 · Legal · Privacy
What we found
The app binary references AVCaptureDevice, which requires a purpose string. Info.plist has no NSCameraUsageDescription. Apple flags this as ITMS-90683 at upload.
The fix
Add the key to Info.plist with one sentence naming the feature that needs camera access. Write it for the person reading the permission alert, not for the reviewer.
Rejection notices say what, never why. Paste yours and Verdict identifies the guideline behind it, explains what reviewers actually mean when they cite it, lists the changes that resolve it, and drafts your Resolution Center reply. It runs in your browser and nothing is stored.
Pasted from App Store Connect
Guideline 2.1 · Performance · App Completeness
We were unable to review your app as it crashed on launch.
The reviewer could not get the app into a working state: a crash, a login they could not pass, or a feature that did nothing on their device.
Reply draft
Thank you for the detailed report. We reproduced the issue and fixed it in this build. We also verified the flow end to end on a clean install with the demo account provided.
Your build is the most sensitive artifact you own before a release, so the handling rules are worth stating plainly rather than burying in a policy page. Here is exactly what happens to the file you upload, and what does not.
Removal happens in a finally block, so it runs whether the scan succeeded, failed, or timed out. What persists is the report: the score, the findings, and the app name and version.
Verdict reads bytes. It does not run your app in a simulator, on a device, or in a sandbox. There is no environment where your code executes on our infrastructure.
Every check is a rule with an explicit condition, written by hand and covered by tests. Two scans of the same build always agree, and a finding cannot be invented.
A scheduled job reads Apple and Google's published policy pages every morning and flags changes, and every report records the engine version that produced it.
Pricing
Every build gets a score and a category breakdown at no cost, because a score you cannot check is worth nothing.
Free
$0forever
Every finding on every build, counted and graded. No account needed.
Pro
Save 75%$119.99 / yearly
The same Pro, paid once a year. Works out at $10.00 a month instead of $39.99.
Billed once a year
Team
Save 75%$239.99 / yearly
The whole team, paid once a year. Works out at $20.00 a month for 5 seats of Pro, or $4.00 a seat.
Billed once a year
If something here is not answered, write to us before you buy rather than after.
Ask about a finding you disagree with, report a rule that misfired, or tell us what your build hit that Verdict missed. We read every message.