taool --help
taool CLI
taool in your terminal, for agents and humans alike. Get a version out from your repo, with its listing, screenshots, build and release. Run TestFlight, feature flags, experiments and update prompts, and answer reviews. All with the App Store Connect key taool already holds, so there's no key on your Mac or in CI.
macOS 14 or later. Every sign-in is approved in the taool app, and what reaches users waits for you there.
brew install taoolcom/cli/taool
Install
For macOS 14 or later, signed and notarized, from Homebrew, the install script or the download.
From taool's tap. brew upgrade taool updates it.
brew install taoolcom/cli/taool
Without Homebrew: it checks the download's SHA-256, then puts taool in /usr/local/bin, or ~/.local/bin when that isn't yours to write to. Run it again to update.
curl -fsSL https://taool.com/install | sh
The zip below holds the binary alone.
unzip taool-*-macos.zip
sudo mkdir -p /usr/local/bin && sudo mv taool /usr/local/bin/
- taool-1.1.2-macos.zip macOS 14 or later
- taool-1.1.2-macos.zip.sha256 its SHA-256
- Signed and notarized
- With our Developer ID, so Gatekeeper runs it without a warning.
- Nothing else to install
- No Ruby, no Node, no App Store Connect key: taool's server holds the key and runs App Store Connect's calls.
- Updates
- When a newer taool is out, the day's first command says so once it's done, with what's new, and
taool updateupdates it the way you installed it. It stays quiet in CI, andTAOOL_NO_UPDATE_NOTIFIER=1turns it off anywhere.taool --versionis the version you have.
taool login
Sign in
taool login prints a code and a QR code. Scan it with your phone, or open the link, and approve in the taool app, which asks for Face ID or Touch ID first. Then taool link in your app's repo, and every command there is about that app.
Each sign-in has its own scopes and apps, and picks once what waits for you in the app: every change, the changes that reach users or can't be undone (to start with), or nothing at all (Full Auto, on Pro). Settings → Agents lists every sign-in, and revoking one ends it at once.
taool release prepare 1.3
Ship a version
Your repo says what 1.3 is: its notes in every language, its screenshots and previews, its build and how it's released. release prepare makes App Store Connect say the same, sending only what differs, so it's safe to run again. release check says what App Review would trip on, and submit --wait waits for App Review's decision without asking App Store Connect over and over.
- Only what differs
- Each run compares the repo with App Store Connect and sends the difference, so running it again after a fix changes only the fix.
--dry-run- On every command that changes something: what it would do, and whether it would wait for you, changing nothing.
- What reaches users waits
- Releasing, raising the minimum version, widening a flag and replying to reviews wait for Face ID or Touch ID in the taool app, unless the sign-in is Full Auto.
taool metadata push
Your listing, in every language
A JSON file per language with Apple's own field names, and a folder per release that keeps its notes and What to Test. A Mac version's own text goes beside what every platform has. An agent translates by writing the file beside it, and metadata validate checks Apple's limits, wasted keywords and translations older than their English before anything's sent. metadata categories set and metadata age-rating set answer the rest of what a first version needs, and versions delete takes back one never sent to App Review.
A key left out keeps App Store Connect's; null clears it. "macos" holds only what the Mac's differs in.
{
"name": "Tidepool",
"subtitle": "Tide tables and alerts",
"description": "Tide charts for every beach…",
"keywords": "tide,tides,surf,beach,swell",
"macos": {
"description": "Tide charts on your desk…"
}
}
Every release keeps its folder, so the notes you shipped stay in git.
{
"whatsNew": "Tide alerts for any beach, an hour before the turn.",
"whatToTest": "Set an alert, then wait for the tide."
}
fastlane's folders are read as they are, too.
metadata/
app.json copyright, content rights
review.json App Review Information, only
with pull --app-review-info
listing/en-US.json … each language's listing
screenshots/en-US/iPhone 6.9/01.jpg …
previews/en-US/iPhone 6.9/01.mov …
header/en-US/ · search-results/en-US/
releases/1.3/
en-US.json … What's New and What to Test
release.json build, release type, phased
taool builds upload Tidepool.ipa --wait
TestFlight
Upload straight to Apple, never through taool, and wait until testers can install it. Then see how much they use each build day by day, which App Store Connect doesn't show, and what they sent from TestFlight. testflight info set gives Beta App Review its contact and sign-in, and testers the beta's description and where their feedback goes, so a first build for external testers goes out from your terminal too.
taool kit
TaoolKit
What TaoolKit does inside your app is under taool kit: feature flags, experiments, update prompts and What's New pages. taool kit alone shows which of its products have checked in from the app, and when. Every command is in the reference below.
A What's New page here is TaoolKit's, shown in your app. The App Store's own What's New text goes with your listing. What's on Pro is what's on Pro in the taool app.
taool kit flags rollout new-paywall
Feature flags
Create a flag with the code that reads it, turn it on for TestFlight, then roll it out on the App Store a step a day. kit flags check finds keys your code reads that taool doesn't have yet, and kit flags off is the kill switch, at once.
taool reviews list --unread
Reviews
Every storefront's reviews and App Store Connect's, read or unread as in the taool app. Reply to one, or up to 10 from a file an agent wrote. Replies wait in the taool app until you send them.
taool assets push
Assets
Everything on your product page that isn't text, kept in your repo: screenshots, app previews, and the header and search results assets iOS 27 shows. Each kind has a folder in metadata/, with a folder per language and display inside it. taool assets push sends every kind at once, as one change, and taool assets screenshots push (or previews, header or search-results) sends one. Start from what's live with taool assets pull.
- The folders
metadata/screenshots/(or fastlane'sfastlane/screenshots/),metadata/previews/,metadata/header/andmetadata/search-results/, each<language>/<display>/:metadata/previews/en-US/iPhone 6.9/01.mov. A folder's files go in their names' order, 2 before 10.- A display by its name or its ID
- Name a display's folder as App Store Connect names the display,
iPhone 6.9(the inch mark left out, case-insensitive), or by Apple's ID for it,IPHONE_DYNAMIC_ISLAND_LARGE_PROFILE; both are in the list of devices, andtaool assets sizesprints the current device sizes from App Store Connect. A file straight in the language's folder goes to the display its size fits.taool config screenshot-folders idshaspullname new folders by ID. - Sent once
- A file App Store Connect has already is never sent again, whatever language or display shows it, so renaming two files is a reorder with nothing uploaded.
- Only what the repo has
- A display with no folder is left as it is; one with files shows exactly those, in that order.
- Checked first
- Every file against Apple's catalog before anything's sent: an image's size and alpha channel, a video's size, length, frame rate and sound (on a Mac).
- A version being prepared
- Apple takes assets on a version that's still being prepared.
release preparesends them with the rest;--no-assetsleaves them out.
taool assets screenshots push
Screenshots
Up to 10 per display size, in metadata/screenshots/en-US/iPhone 6.9/. iPhone and iPad screenshots can be portrait or landscape.
taool assets previews push
App previews
The videos before your screenshots, up to 3 per display size, as .mov, .mp4 or .m4v in metadata/previews/en-US/iPhone 6.9/. Apple processes a video after it's uploaded, which can take a while. taool adds it to the version right away, and it shows once Apple's done. Each preview's poster frame, the still shown before it plays, goes in metadata/previews/frames.json, by the video's path from there; one without gets Apple's.
{
"en-US/iPhone 6.9/01.mov": "00:00:05:00",
"de-DE/iPhone 6.9/01.mov": "00:00:03:12"
}
- Hours, minutes, seconds and frames
- A poster frame is
HH:MM:SS:FF, so00:00:03:12is 3 seconds and 12 frames in. Changing it alone sends nothing again. - Apple's limits
- Each display's size, length and frame rate are in the list of devices; a preview needs a sound track, even a silent one.
taool assets header push
Header
The image or video atop your product page on iOS 27 and iPadOS 27, one a language, in metadata/header/en-US/. A video loops, muted until someone turns its sound on. Its poster frame goes in metadata/header/frames.json, as a preview's does.
taool assets search-results push
Search results
The image or video your app shows in App Store search results on iOS 27 and iPadOS 27, one a language, in metadata/search-results/en-US/. Without one, the App Store shows your in-app events, previews and screenshots there. The same file as your header is sent once and shown in both.
taool assets sizes
Devices
Apple's displays and the sizes each takes, by the name to give a display's folder and Apple's ID, which works too. taool assets sizes reads them from Apple as you run it, so a device Apple adds is there at once.
- Not the name App Store Connect shows?
- App Store Connect's upload screen can name a display after the newest device that uses it, while the display's name and ID keep the device it was made for: where App Store Connect says Apple Watch Series 12, the folder and ID say Series 10 (
WATCH_SERIES_10_PROFILE). It's the same display; name the folder either way this list does.
| display | ID | screenshots | app previews |
|---|---|---|---|
| iPhone 6.9" | IPHONE_DYNAMIC_ISLAND_LARGE_PROFILE | 2796 × 1290 1290 × 2796 2868 × 1320 1320 × 2868 2736 × 1260 1260 × 2736 | 1920 × 886, 15–30 s, 23–30 fps, with sound 886 × 1920, 15–30 s, 23–30 fps, with sound |
| iPhone Duo | IPHONE_DUO_PROFILE | 2034 × 1398 1398 × 2034 2853 × 2007 2007 × 2853 | 1920 × 886, 15–30 s, 23–30 fps, with sound 886 × 1920, 15–30 s, 23–30 fps, with sound |
| iPhone 6.5" | IPHONE_FACE_ID_LARGE_PROFILE | 2688 × 1242 1242 × 2688 2778 × 1284 1284 × 2778 | 1920 × 886, 15–30 s, 23–30 fps, with sound 886 × 1920, 15–30 s, 23–30 fps, with sound |
| iPhone 6.3" | IPHONE_DYNAMIC_ISLAND_MEDIUM_PROFILE | 2556 × 1179 1179 × 2556 2622 × 1206 1206 × 2622 | 1920 × 886, 15–30 s, 23–30 fps, with sound 886 × 1920, 15–30 s, 23–30 fps, with sound |
| iPhone 6.1" | IPHONE_FACE_ID_MEDIUM_PROFILE | 2532 × 1170 1170 × 2532 2340 × 1080 1080 × 2340 2436 × 1125 1125 × 2436 | 1920 × 886, 15–30 s, 23–30 fps, with sound 886 × 1920, 15–30 s, 23–30 fps, with sound |
| iPhone 5.5" | IPHONE_HOME_BUTTON_LARGE_PROFILE | 2208 × 1242 (alpha) 1242 × 2208 (alpha) | 1920 × 1080, 15–30 s, 23–30 fps, with sound 1080 × 1920, 15–30 s, 23–30 fps, with sound |
| iPhone 4.7" | IPHONE_HOME_BUTTON_MEDIUM_PROFILE | 1334 × 750 (alpha) 750 × 1334 (alpha) | 1334 × 750, 15–30 s, 23–30 fps, with sound 750 × 1334, 15–30 s, 23–30 fps, with sound |
| iPhone 4" | IPHONE_HOME_BUTTON_40_PROFILE | 1136 × 640 (alpha) 640 × 1136 (alpha) 1136 × 600 (alpha) 640 × 1096 (alpha) | 1920 × 1080, 15–30 s, 23–30 fps, with sound 1080 × 1920, 15–30 s, 23–30 fps, with sound |
| iPhone 3.5" | IPHONE_HOME_BUTTON_35_PROFILE | 960 × 640 (alpha) 640 × 960 (alpha) 960 × 600 (alpha) 640 × 920 (alpha) 480 × 320 (alpha) 320 × 480 (alpha) 480 × 300 (alpha) 320 × 460 (alpha) | – |
| iPad 13" | IPAD_13_PROFILE | 2732 × 2048 2048 × 2732 2752 × 2064 2064 × 2752 | 1600 × 1200, 15–30 s, 23–30 fps, with sound 1200 × 1600, 15–30 s, 23–30 fps, with sound |
| iPad 11" | IPAD_11_PROFILE | 2266 × 1488 1488 × 2266 2420 × 1668 1668 × 2420 2388 × 1668 1668 × 2388 2360 × 1640 1640 × 2360 | 1600 × 1200, 15–30 s, 23–30 fps, with sound 1200 × 1600, 15–30 s, 23–30 fps, with sound |
| iPad Pro 12.9" (2nd generation) | IPAD_129_PROFILE | 2732 × 2048 (alpha) 2048 × 2732 (alpha) | 1200 × 900, 15–30 s, 23–30 fps, with sound 900 × 1200, 15–30 s, 23–30 fps, with sound 1600 × 1200, 15–30 s, 23–30 fps, with sound 1200 × 1600, 15–30 s, 23–30 fps, with sound |
| iPad 10.5" | IPAD_105_PROFILE | 2224 × 1668 (alpha) 1668 × 2224 (alpha) | 1600 × 1200, 15–30 s, 23–30 fps, with sound 1200 × 1600, 15–30 s, 23–30 fps, with sound |
| iPad 9.7" | IPAD_97_PROFILE | 768 × 1004 (alpha) 1024 × 748 (alpha) 1536 × 2008 (alpha) 2048 × 1496 (alpha) 1024 × 768 (alpha) 768 × 1024 (alpha) 2048 × 1536 (alpha) 1536 × 2048 (alpha) | 1200 × 900, 15–30 s, 23–30 fps, with sound 900 × 1200, 15–30 s, 23–30 fps, with sound |
| Apple Watch Ultra | WATCH_ULTRA_PROFILE | 410 × 502 422 × 514 | – |
| Apple Watch Series 10 | WATCH_SERIES_10_PROFILE | 416 × 496 | – |
| Apple Watch Series 7 | WATCH_SERIES_7_PROFILE | 396 × 484 | – |
| Apple Watch Series 4 | WATCH_SERIES_4_PROFILE | 368 × 448 (alpha) | – |
| Apple Watch Series 3 | WATCH_SERIES_3_PROFILE | 312 × 390 | – |
| Mac | MAC_PROFILE | 2880 × 1800 (alpha) 2560 × 1600 (alpha) 1440 × 900 (alpha) 1280 × 800 (alpha) | 1920 × 1080, 15–30 s, 23–30 fps, with sound |
| Apple TV | TV_PROFILE | 1920 × 1080 (alpha) 3840 × 2160 (alpha) | 1920 × 1080, 15–30 s, 23–30 fps, with sound |
| Apple Vision Pro | VISION_PRO_PROFILE | 3840 × 2160 (alpha) | 3840 × 2160, 15–30 s, 23–30 fps, with sound |
| kind | display | image | video |
|---|---|---|---|
| header | Every Device DEFAULT_PROFILE | 5244 × 2950 3840 × 1646 | 3840 × 1646, 5–30 s, 30 or 60 fps |
| search-results | Every Device DEFAULT_PROFILE | 5244 × 2950 1920–3840 × 1280–2560 | 1920–3840 × 1280–2560, 5–30 s, 30 or 60 fps |
taool events view "Winter Climb"
In-app events
Make an in-app event with everything App Review needs of it: its badge, deep link and dates, its name and descriptions in each language, and its card and details page, an image or a video each. events view says what's still missing, each with the command that gives it, and events submit sends it. Events are on every plan.
Times are on the 24-hour clock or with am or pm, 2026-11-20 16:00 or 2026-11-20 4pm, in your Mac's time zone unless you name another with --time-zone. They reach Apple as exact moments, so an event starts at the same moment everywhere: 16:00 in Stockholm is 15:00 in London. An event lasts 15 minutes to 31 days, and the App Store can promote it up to 14 days before it starts.
Sending one to App Review on its own, changing one App Review has approved and deleting one wait for your approval in the taool app.
taool products view tidepool.pro.monthly
Products
Make an in-app purchase or a subscription, with everything App Review needs of it: its display name and description in each language, a subscription group's name, its review screenshot and a promotional image. products view says what's still missing, each with the command that gives it, and products submit sends it. Making and changing products is on Pro; reading them is on every plan.
taool prices set 29.99 --product tidepool.pro.yearly --from soonest
Prices
Set a price as customers in one country pay it, the US unless you say --country, and every other country gets Apple's match of it, as in App Store Connect. The app's own price, an in-app purchase's or a subscription's. You can override countries, from the command or from the repo's metadata/pricing.json, and every price is one of Apple's, never a converted currency.
Before anything is sent, you see every country whose price moves, from what to what and why, and you're asked. Changing prices is on Pro; reading them and following a change are on every plan. A sign-in needs In-App Purchases, which starts unticked when you approve it.
Each product's overridden countries, by product ID, "app" for the app's own price, and introductory offers' under "intro-offers". A flag for a country takes the file's place for it.
{
"app": { "in": "-30%", "br": 9.90 },
"tidepool.pro.monthly": { "in": "-30%", "se": -1, "tr": "keep" },
"intro-offers": {
"tidepool.pro.monthly": { "in": "-50%", "tr": "keep" }
}
}
- Overriding a country
--override se=349is an exact price, in the country's currency.se=-2orse=+2moves down or up Apple's price list there from its match of your price, between -50 and +50 steps.se=-10%orse=+10%lowers or raises Apple's match by that percentage, then lands on the nearest of Apple's own prices at or past it, so the price moves at least that much: if the match is 109 kr,se=-10%gives the highest price at or below 98.10 kr. Supports percentages from -90% to +300%.--keep se, orse=keep, leaves the country as it is, for when you change your price but don't want it to move there: raise the US price to $9.99 and Sweden still pays 99 kr. Name one country,--override se=-1, or several with commas,--override se=-1,dk=+10%,no=keep;--keep se,dk,nokeeps three at once. Each country once. A region of several countries, aseu=-20%, works the same way: see countries and regions.- Why each country moves
baseis the price you set,autoApple's match of it, andexact,-2or+10%your override, as you gave it. Yours are always listed. Of the countries at Apple's price, a long list shows the top markets and how many more;--alllists every one.- Only some countries
- Leave the price out and only the countries overridden change, their steps and percentages counted from Apple's match of the price now: a subscription's in the US, or the country
--countrynames, the app's and an in-app purchase's in their base country. taool says which as it shows the change:taool prices set --product tidepool.pro.yearly --from soonest --override se=-1. - A sale for a while
- With
--until, the app's or an in-app purchase's change is temporary, as App Store Connect's Temporary Price Change is:taool prices set 0.99 --from 2026-12-01 --until 2026-12-26puts it on sale everywhere,--override eu=-30% --until 2026-12-26in the EU alone, and from that day each country is back to what it had, its own price or Apple's match.taool prices set 0makes the app free, for good or until a day. A subscription's sale is an introductory offer or an offer code. - Subscriptions
- Current price is preserved for existing subscribers, unless
--existing-tooapplies the price increase to them. taool sets a subscription's prices country by country, as your App Store Connect key's hourly allowance allows:--waitfollows it,taool prices statussays how far it's got, andtaool prices undotakes the prices back until 10:00 UTC the day before they start in the first country. The app's own price and an in-app purchase's are set in one go once you approve. - Asked first, or
--yes taool prices set,taool intro-offers createandtaool intro-offers deleteshow what they change and ask before anything is sent.--yessends it without asking, and--dry-runshows it and sends nothing. With no terminal to ask at, as for an agent or in CI, nothing is sent without--yes: the command exits 6, with the list as JSON under--json, so the agent can show you first. Once sent, the change waits for your approval in the taool app, unless the sign-in is Full Auto.
taool intro-offers list tidepool.pro.monthly
Introductory offers
A subscription's free trials and introductory prices, in every country or some: pay as you go, a price each period, or pay up front, one price for the whole offer. A paid one is priced as a price change is, your price in one country and Apple's match everywhere else, with the countries overridden from the command or the file's "intro-offers" entry. Or give a discount, which App Store Connect doesn't offer: --price -25% makes each country's offer at least 25% off what it pays on the offer's first day, landing on one of Apple's prices; a country overridden with a percentage, as se=-40%, takes that much off its own price instead. The preview shows every country's price and how much it takes off. Pay up front takes it off the whole stretch at the full price. A kept country gets no offer. Apple allows one introductory offer at a time in a country, so the one running there then ends as yours starts, as in App Store Connect, and undo puts its end back; one still to come is refused before you're asked.
The list shows each offer's terms and days, and what it costs in the top markets with how much that takes off the full price there; --all lists every country, and --regions only those. Taking offers off can't be undone, so it's asked about like any change. Making and taking off introductory offers is on Pro; listing them is on every plan. Like prices, they need a sign-in with In-App Purchases ticked.
taool offer-codes list tidepool.pro.monthly
Offer codes
An offer code is a deal that customers redeem in the App Store or in your app, and its codes are what they type. create makes the deal: a subscription's free trial, pay as you go or pay up front, for new, existing or expired subscribers, renewing at its price afterwards unless --no-auto-renew ends it with the offer; or an in-app purchase's price, or free, for non-spenders, active spenders or churned spenders. Its price is set in one country and Apple's equal everywhere else.
generate makes its codes: a batch of one-time use codes, up to 25,000, or with --code a custom code such as LAUNCH50, redeemable a number of times. Apple makes a batch over a while, up to an hour, so download writes it to a file once it has, or --wait --file waits and writes it in one. Every command after create names the offer with --offer, its name or its ID.
Codes are like cash: taool never prints them, not even with --json, and writes a batch only to a file only you can read, each download in the log in the taool app. They reach no one until you hand them out, so offers and codes don't wait for your approval unless your sign-in asks about every change; turning off an offer, or one batch or custom code, is asked about like any change that can't be undone. Offer codes are on every plan.
taool availability
Availability
Where the app, or with --product an in-app purchase or a subscription, is on sale, as App Store Connect's Pricing and Availability sets it. set puts it on sale in exactly the regions you name, add in those too, and remove takes it off sale in them. Each change shows every country it puts on sale or takes off, and you're asked; it then waits for your approval in the taool app, since it reaches customers at once and can't be undone, only changed again. The app's changes one country at a time as your key's hour allows, a product's in one go.
A product's --new-countries or --no-new-countries says whether Apple puts it on sale in countries it opens; the app's is set in App Store Connect. Listing availability and changing the app's are on every plan; changing an in-app purchase's or a subscription's is on Pro. A change needs In-App Purchases ticked for the sign-in.
taool prices parity tidepool.pro.monthly
Parity
Purchasing power pricing: a subscription's price in each country by what people there can pay. Parity sets each country's price as a share of Apple's match of your US price, following the taool Global Price Index: what each country really pays for subscriptions, from its top-grossing apps and the biggest services, or an estimate from World Bank figures where there's too little to go on. Each country goes into one of five zones, from A at 115% of Apple's match to E at 50%, never past half off, and a country within 15% of Apple's match keeps it, so most of Western Europe stays put. A price only goes up where more of your trials pay than at home.
--write keeps the suggestion in metadata/pricing.json, which taool prices set sends, and --check fails while a price is further off its target than the tolerance, for CI. Its suggestions are on Pro; below Pro, it says how many countries would move.
- How far it goes
--strengthis how much of the index to follow, 60% to start with, between--floorand--cap.--exactgives each country its own share rather than its zone's, and--only lowerleaves raises out.- How sure it is
- Each country's cells say how sure the index is there, from how closely its sources agree. One means too little data there, so the index is estimated from World Bank figures.
taool prices tiers tidepool.pro.monthly
Price tiers
Every price Apple has in a country for the app, an in-app purchase or a subscription, with your proceeds and how much of each price you don't get: Apple's commission and, where prices include it, tax. That's 15% in the US in the Small Business Program, and 32% in Sweden, where prices include VAT. Nice prices, the kind a customer reads as round ($4.99 and $4.49, 59 kr, ₹499), are marked, today's price is highlighted, and under them it says whether your team is in the Small Business Program.
It lists from half today's price to twice it, or a free app's cheapest 30, unless --from, --to or --all say otherwise. --country picks the country, the US unless you say.
taool intro-offers list tidepool.pro.monthly --regions us,eu
Countries and regions
--country takes a single country: the one whose currency --price is in, which Apple matches every other country from. Everywhere else taool takes regions, one or more separated by commas, a region being a country, eu, eur or one of Apple's regions, mixed as you like: --regions us,eu is the US and every EU country, and --keep tr,latinamerica keeps Türkiye and Latin America as they are.
- Where regions work
--regionsonintro-offers,offer-codes create,availability,salesandreviews;--keepand--overrideonprices setandintro-offers create; andmetadata/pricing.json.taool sales --regions europeadds up Europe's downloads, redownloads, updates and proceeds, and--alllists each of its countries.- Where a single country works
--countryonprices set,intro-offers createandoffer-codes create: the country your price is in.- A country
- Its two letters, as
se, or Apple's three, asSWE. Each country's are in the table below. euandeureuis the European Union's 27 countries.euris every country Apple prices in euros, which isn't the same: Sweden is in the EU but does not use EUR as currency. It's read from Apple as you make the change, so a country that changes its currency follows.- Apple's regions
europe,asiapacific,latinamerica,uscanadaandafricamiddleeast(Africa, the Middle East and India), with the same countries Apple defines for each, as App Store Connect groups them.- The narrowest wins
- A country named alone wins over
eur,eurovereu, andeuover Apple's regions, so--override eu=-20%,se=-10%gives Sweden 10% and the rest of the EU 20%. A region never moves the country your price is set in. - An exact price
- Only for a country or
eur, whose countries all pay in euros:--override eur=4.99. Other regions pay in more than one currency, so they take a percentage, steps or keep:--override europe=-10%. - Never
--country --country euis refused, since Apple matches every other country from one country's price. For one price in every euro country, set it in one of them and give the rest the same:--price 4.99 --country de --override eur=4.99.
| region | countries |
|---|---|
uscanada | The United States and Canada (2): Canada ca, United States us |
europe | Europe (42): Albania al, Austria at, Belarus by, Belgium be, Bosnia and Herzegovina ba, Bulgaria bg, Croatia hr, Cyprus cy, Czech Republic cz, Denmark dk, Estonia ee, Finland fi, France fr, Germany de, Greece gr, Hungary hu, Iceland is, Ireland ie, Italy it, Kosovo xk, Latvia lv, Lithuania lt, Luxembourg lu, Malta mt, Moldova md, Montenegro me, Netherlands nl, North Macedonia mk, Norway no, Poland pl, Portugal pt, Romania ro, Russia ru, Serbia rs, Slovakia sk, Slovenia si, Spain es, Sweden se, Switzerland ch, Türkiye tr, Ukraine ua, United Kingdom gb |
africamiddleeast | Africa, Middle East, and India (57): Afghanistan af, Algeria dz, Angola ao, Armenia am, Azerbaijan az, Bahrain bh, Benin bj, Botswana bw, Burkina Faso bf, Cameroon cm, Cape Verde cv, Chad td, Côte d’Ivoire ci, Democratic Republic of the Congo cd, Egypt eg, Eswatini sz, Gabon ga, Gambia gm, Georgia ge, Ghana gh, Guinea-Bissau gw, India in, Iraq iq, Israel il, Jordan jo, Kenya ke, Kuwait kw, Lebanon lb, Liberia lr, Libya ly, Madagascar mg, Malawi mw, Mali ml, Mauritania mr, Mauritius mu, Morocco ma, Mozambique mz, Namibia na, Niger ne, Nigeria ng, Oman om, Qatar qa, Republic of the Congo cg, Rwanda rw, Saudi Arabia sa, Senegal sn, Seychelles sc, Sierra Leone sl, South Africa za, São Tomé and Príncipe st, Tanzania tz, Tunisia tn, Uganda ug, United Arab Emirates ae, Yemen ye, Zambia zm, Zimbabwe zw |
latinamerica | Latin America and the Caribbean (37): Anguilla ai, Antigua and Barbuda ag, Argentina ar, Bahamas bs, Barbados bb, Belize bz, Bermuda bm, Bolivia bo, Brazil br, British Virgin Islands vg, Cayman Islands ky, Chile cl, Colombia co, Costa Rica cr, Dominica dm, Dominican Republic do, Ecuador ec, El Salvador sv, Grenada gd, Guatemala gt, Guyana gy, Honduras hn, Jamaica jm, Mexico mx, Montserrat ms, Nicaragua ni, Panama pa, Paraguay py, Peru pe, St. Kitts and Nevis kn, St. Lucia lc, St. Vincent and the Grenadines vc, Suriname sr, Trinidad and Tobago tt, Turks and Caicos Islands tc, Uruguay uy, Venezuela ve |
asiapacific | Asia Pacific (37): Australia au, Bhutan bt, Brunei bn, Cambodia kh, China mainland cn, Fiji fj, Hong Kong hk, Indonesia id, Japan jp, Kazakhstan kz, Kyrgyzstan kg, Laos la, Macau mo, Malaysia my, Maldives mv, Micronesia fm, Mongolia mn, Myanmar mm, Nauru nr, Nepal np, New Zealand nz, Pakistan pk, Palau pw, Papua New Guinea pg, Philippines ph, Singapore sg, Solomon Islands sb, South Korea kr, Sri Lanka lk, Taiwan tw, Tajikistan tj, Thailand th, Tonga to, Turkmenistan tm, Uzbekistan uz, Vanuatu vu, Vietnam vn |
eu | The European Union (27): Austria at, Belgium be, Bulgaria bg, Croatia hr, Cyprus cy, Czech Republic cz, Denmark dk, Estonia ee, Finland fi, France fr, Germany de, Greece gr, Hungary hu, Ireland ie, Italy it, Latvia lv, Lithuania lt, Luxembourg lu, Malta mt, Netherlands nl, Poland pl, Portugal pt, Romania ro, Slovakia sk, Slovenia si, Spain es, Sweden se |
eur | The euro's: every country Apple prices in euros, read from Apple as you make the change. |
taool ci token --scopes testflight,release
In CI
A CI token is one app's, with the scopes you pick, approved in the taool app like any sign-in. It's never printed: it goes straight into your GitHub repo's secrets, a file only you can read, or the clipboard. CI reads it as TAOOL_TOKEN. CI tokens are on Pro.
Each push to main builds the next number and puts it in TestFlight.
on:
push:
branches: [main]
jobs:
testflight:
runs-on: macos-15
env:
TAOOL_TOKEN: ${{ secrets.TAOOL_TOKEN }}
steps:
- uses: actions/checkout@v4
- run: brew install taoolcom/cli/taool
- run: |
number=$(taool builds next-number)
xcodebuild archive … CURRENT_PROJECT_VERSION=$number
xcodebuild -exportArchive … -exportPath build
- run: taool builds upload build/Tidepool.ipa --wait
claude "ship 1.3 once build 46 is in"
Coding agents
Agents such as Claude Code run the same commands you do. Every command takes --output json, or --json for short: its output is then taool's answer as JSON and nothing else, for an agent or a script to read, while anything said for people, such as waiting for your approval, is kept out of it. Each answer also carries next: the commands that make sense from there, ready to run, such as submit once a check passes, or what App Review still needs of a product. Every change takes --dry-run, but marking reviews read. A change that asks first (prices set, intro-offers create and intro-offers delete) sends nothing from an agent without --yes, so the agent shows you what it changes before it does. The exit code says why a command stopped. What reaches users still waits for your Face ID or Touch ID, however the agent asks, unless the sign-in is Full Auto.
- Exit codes
-
1 failed, 2 used wrongly, 3 not signed in, 4 not allowed (the sign-in's scopes or apps, or the plan), 5 denied (in the taool app, or at the question), 6 needs
--yes(no terminal to ask at), 7 not found, 8 over a quota, 9 taool unreachable, 10 still waiting when the time ran out, 11 taool needs updating. - Your apps only
- A sign-in reaches the apps you've added as yours in taool, never the charts or anyone else's apps. What goes through App Store Connect, such as releases, builds and sales, also needs your key to cover the app.
- Quotas
- Each account has a 5-hour and a weekly allowance of calls, and each sign-in a few a minute, larger on Pro.
taool whoamisays how much of the 5 hours and the week is used.
taool help
Commands
Every command, as taool help has it. Each also takes --help, and --output json (-o json, or --json) for taool's answer as JSON. Every command that prints a list, from apps and sales to builds, price tiers and the findings of release check, takes --output csv too, for a spreadsheet, and --output md, a Markdown table for a pull request, an issue or a README: taool sales --days 365 --output csv > sales.csv.
taool login
taool login [options]
Sign in to taool, approved in the taool app.
Prints a code, a link and, in a terminal, the link as a QR code: scan it with your phone or open the link to approve in the taool app, or type the code in its Settings → Agents → Approve a Code. The app confirms it's you (Face ID, Touch ID or the passcode) before it approves. The token is kept in the Keychain; TAOOL_TOKEN, when set, is used instead.
--scopes <scopes>- Which permissions to ask for, comma-separated: apps, reviews, replies, feedback, taoolkit, testflight, release, sales, store; all of them when left out. The taool app's approval screen lists only those asked for, some (such as sales) unticked to start with, and you choose there. One not asked for can't be allowed.
taool logout
taool logout
Sign out: taool revokes this sign-in, and the Keychain forgets it.
taool whoami
taool whoami
Who this sign-in is: the account, what it may do, and the calls used.
taool apps
taool apps [options]
Your apps this sign-in covers, the repo's linked one marked.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool link
taool link [<app>]
Tie this repo to one of your apps: writes taool.json at its root.
Left out, the app is the one whose bundle ID this repo's Xcode projects set.
<app>- The app: its App Store ID, bundle ID or name.
taool config
The repo's settings in its taool.json: show them, or set one.
taool config show
The app this repo is linked to, and its settings.
taool config screenshot-folders [<naming>]
How assets pull names a display's folder: names (iPhone 6.9) or ids (IPHONE_DYNAMIC_ISLAND_LARGE_PROFILE).
Every kind's display folders alike: screenshots', app previews', the header's and search results'. Either is read whatever this says; assets pull renames the repo's display folders to match. Left out, it says which.
<naming>- names or ids.
taool status
taool status [<app>] [options]
One app at a glance: where each platform's versions are, its rating, reviews, builds and ranks.
Ranks as the account's plan shows them: each app's best 5 charts on Free.
<app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--ranks <ranks>- How many ranks to list.
taool doctor
taool doctor [<app>]
What's set up for an app in taool, and what to do about what isn't.
<app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
taool update
taool update
Update taool the way it was installed: with Homebrew, or taool.com's install script.
taool reviews
An app's reviews, from the App Store and App Store Connect, with your read marks.
taool reviews list [options]
The newest reviews, 50 at a time.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--unread- Only those you haven't read.
--search <search>- Only those with these words.
--regions <regions>- Only these regions' reviews, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu).
--before <before>- The next 50 reviews, older than this one: the review ID in the "More:" line a list ends with.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool reviews mark-read [<review-ids>] [options]
Mark reviews read, as in the taool app: those named, or all of the app's.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
<review-ids>- Review IDs, as the list shows them.
--all- Every review of the app.
taool reviews reply [<review-id>] [options]
Reply to reviews through App Store Connect: one, or up to 10 from a file, waiting in the taool app until you send them.
Needs a sign-in with Reply to Reviews ticked (taool login asks for it; it starts unticked) and a key with Customer Support, App Manager or Admin. On Full Auto the replies go at once. A reply replaces the one a review has. The file is JSON: [{"reviewId": 123, "body": "Thanks!"}].
<review-id>- The review's ID, as taool reviews lists it.
--text <text>- The reply.
--file <file>- A JSON file of replies, each a reviewId and a body.
--wait- Wait until they're approved or denied in the taool app.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool sales
taool sales [options]
An app's downloads and proceeds by day, as Apple's reports count them: UTC days, or Pacific Time while its Analytics reports aren't in.
Proceeds are Apple's estimate, after its commission and taxes, in the currency asked for.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--days <days>- How many days, to the last one Apple's reports are complete for.
--currency <currency>- The currency for proceeds, as ISO's code: USD, EUR, SEK…
--regions <regions>- Only these regions' sales, added up, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu).
--all- Every country's downloads and proceeds, not only the 5 with the most downloads.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool payouts
taool payouts [options]
Apple's payouts: those paid, and the next ones with their expected date and amount, estimated until Apple's report is out.
Apple pays a team for all of its apps at once, not app by app, so only a sign-in that covers every app can read payouts.
--currency <currency>- The currency, as ISO's code: USD, EUR, SEK…
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool kit
TaoolKit in an app: its feature flags, experiments, update prompts and What's New pages.
taool kit alone shows which of TaoolKit's products have checked in from the app, and when.
taool kit flags
An app's feature flags: what each serves on the App Store and in TestFlight.
taool kit flags list [options]
Every flag, with its type and values.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool kit flags check [options]
Find flag keys the code reads that taool doesn't have; exit 1 if there are any.
--path <path>- The folder whose Swift code is read: the repo's root to start with.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool kit flags create <key> [options]
Make a flag in taool, serving its default to everyone until it's set: create it with the code that reads it.
<key>- The flag's key, as the app's code reads it.
--type <type>- bool (to start with), string, number or json.
--default <default>- What it serves when it's off, for a typed flag: its code's fallback.
--note <note>- A note for your team.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit flags set <key> [<value>] [options]
What a flag serves on the App Store, a value to a share of users, or with --testflight in TestFlight. Waits for your approval when it reaches more users.
<key>- The flag's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
<value>- on, off, a number, JSON, or text.
--percent <percent>- The share of users who get it, 0 to 100: a percentage (Pro).
--testflight- TestFlight's value, not the App Store's.
--same- With --testflight: the App Store's value, as it is.
--text- Take the value as text, whatever it looks like.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit flags rollout <key> [options]
Roll an on and off flag out on the App Store in steps (Pro), the first now. Waits for your approval.
<key>- The flag's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--steps <steps>- The steps' shares, in order.
--every <every>- Days between steps.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit flags on <key> [options]
Turn a flag back on on the App Store. Waits for your approval.
<key>- The flag's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit flags off <key> [options]
Turn a flag off for everyone, TestFlight too, at once: the kill switch.
<key>- The flag's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit flags pause <key> [options]
Hold a rollout at its step.
<key>- The flag's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit flags resume <key> [options]
Move a paused rollout on again. Waits for your approval.
<key>- The flag's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit flags delete <key> [options]
Delete a flag that's off everywhere, once no build reads it.
<key>- The flag's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit experiments
An app's experiments and their results.
taool kit experiments list [options]
Every experiment: running, waiting or ended, with each variant's results.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool kit experiments end <key> --winner <winner> [options]
End an experiment, serving its winner to everyone. Waits for your approval.
<key>- The experiment's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--winner <winner>- The variant everyone gets from now on.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit experiments rerun <key> [options]
Run an ended experiment again, its split as the code has it.
<key>- The experiment's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit experiments delete <key> [options]
Delete an experiment and its results.
<key>- The experiment's key.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit update-prompts
An app's update prompts: the latest version, the minimum, and the messages.
taool kit update-prompts alone shows the policy for each platform.
taool kit update-prompts minimum [<version>] [options]
The oldest version allowed (Pro; --clear on every plan): older ones see the update screen. Raising it waits for your approval.
<version>- The version, as 2.4.
--clear- No minimum.
-p, --platform <platform>- ios or macos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit update-prompts strict <state> [options]
Strict mode (turning it on is Pro): your servers refuse requests without the app's version too. Turning it on waits for your approval.
<state>- on or off.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit update-prompts language [<language>] [options]
The update screen's language for an app in one language whose bundle doesn't say which.
<language>- The language, as en or sv.
--clear- The app's own, as its bundle says.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit update-prompts message --kind <kind> --text <text> [options]
Your own words on the update banner or screen (Pro; removing them on every plan), in one language; translate them into the others by running it again.
--kind <kind>- available (the banner) or required (the screen).
--text <text>- The words; empty removes this language's.
--language <language>- The language, as en or sv.
--version <version>- Only for this version; every version when left out.
-p, --platform <platform>- ios or macos; both when left out.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit whats-new
An app's What's New pages.
taool kit whats-new list [options]
Every page: live, scheduled, draft or earlier.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool kit whats-new upload <path> --version <version> [options]
Upload a What's New page (Pro): a folder with index.html, or one HTML file, as a draft, published once its version is out.
Never in place of a live page: publishing one waits for your approval.
<path>- The folder or the HTML file.
--version <version>- The version it's about, as 2.5.
-p, --platform <platform>- ios or macos.
--draft- Keep it a draft, even once its version is out.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit whats-new publish <version> [options]
Publish a page now, its version out already (Pro). Waits for your approval.
<version>- The page's version, as 2.5.
-p, --platform <platform>- ios or macos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit whats-new unpublish <version> [options]
Take a page back to a draft, so no one sees it until it's published again (Pro).
<version>- The page's version, as 2.5.
-p, --platform <platform>- ios or macos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit whats-new testflight <version> <state> [options]
Show a page in TestFlight builds first, or not (Pro).
<version>- The page's version, as 2.5.
-p, --platform <platform>- ios or macos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
<state>- on or off.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool kit whats-new delete <version> [options]
Delete a page and its files.
<version>- The page's version, as 2.5.
-p, --platform <platform>- ios or macos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool builds
An app's TestFlight builds: list them, upload one, wait for Apple, and what to do with each.
A build is named by its number (45), its version and number ("1.2 (45)") or Apple's ID. Expiring one, or removing an unfinished upload, can't be undone, so it waits for your approval in the taool app; the rest apply at once. Waiting listens for App Store Connect's webhook, set up in the taool app's Settings → App Store Connect; without it, taool checks Apple itself at intervals.
taool builds list [options]
The app's newest builds on every platform, and where each is.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-p, --platform <platform>- Only one platform's: ios, macos, tvos or visionos.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool builds latest [options]
The newest build on a platform: its version and number, for scripts.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
taool builds next-number [options]
The build number after the app's highest on a platform, for CI to build with: 46 after 45, 1.0.8 after 1.0.7.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
--version <version>- Only builds of this version, for an app whose numbers start again with each version.
taool builds upload <file> [options]
Upload a build to TestFlight: its bytes go straight to Apple, never through taool.
An .ipa's version, build number and platform are read from its Info.plist; a Mac app's .pkg needs --version and --build. Apple then processes it, usually 5 to 30 minutes: --wait waits for that.
<file>- The .ipa or .pkg.
--version <version>- Its version, when the file doesn't say.
--build <build>- Its build number, when the file doesn't say.
-p, --platform <platform>- ios, macos, tvos or visionos, when the file doesn't say.
--wait- Wait until Apple has processed it.
--timeout <timeout>- How long --wait waits, in minutes.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool builds remove <build> [options]
Remove an unfinished upload: one Apple never got the whole file of. Can't be undone, so it waits for your approval.
An upload stopped part way stays at Apple waiting for its file, though it never becomes a build, and taool builds lists it only for its first half hour. Named by its build, the one unfinished upload of it is removed; where there are several, it lists them, and --upload names one.
<build>- The build: its number (45), or version and number ("1.2 (45)").
--upload <upload>- Which upload, by the ID listed where a build has several.
-p, --platform <platform>- ios, macos, tvos or visionos, where a number is on several.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool builds wait [<build>] [options]
Wait until Apple has processed a build, or until testers can install it.
taool hears from App Store Connect's webhook as Apple moves the build on, or without one checks Apple itself at intervals. Exits 10 when the time's up with the build still on its way: run it again to keep waiting.
<build>- The build: its number (45), version and number ("1.2 (45)"). The newest when left out.
-p, --platform <platform>- ios, macos, tvos or visionos.
--testable- Until testers can install it, not only until it's processed.
--timeout <timeout>- How long to wait, in minutes.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
taool builds expire <build> [options]
Expire a build: testers can't install it any more, nor open it. Can't be undone, so it waits for your approval.
<build>- The build: its number (45), version and number ("1.2 (45)") or Apple's ID.
-p, --platform <platform>- ios, macos, tvos or visionos, where a number is on several.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool builds compliance <build> [options]
Answer a build's export compliance: it uses no encryption that needs documents, so testers can have it.
An app that does use such encryption answers in App Store Connect, with its documents.
<build>- The build: its number (45), version and number ("1.2 (45)") or Apple's ID.
-p, --platform <platform>- ios, macos, tvos or visionos, where a number is on several.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool builds submit <build> [options]
Submit a build to Beta App Review, for external groups. A version's first build needs it; Apple approves later ones itself.
<build>- The build: its number (45), version and number ("1.2 (45)") or Apple's ID.
-p, --platform <platform>- ios, macos, tvos or visionos, where a number is on several.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool builds distribute <build> [options]
Put a build in TestFlight groups, or take it out, by the groups' names.
<build>- The build: its number (45), version and number ("1.2 (45)") or Apple's ID.
-p, --platform <platform>- ios, macos, tvos or visionos, where a number is on several.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--add <add>- A group to put it in. Repeat for several.
--remove <remove>- A group to take it out of. Repeat for several.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool builds test-notes <build> [<text>] [options]
A build's What to Test, what TestFlight shows its testers, in one language.
<build>- The build: its number (45), version and number ("1.2 (45)") or Apple's ID.
-p, --platform <platform>- ios, macos, tvos or visionos, where a number is on several.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
<text>- What to test; --file reads it from a file instead.
--file <file>- A file with what to test.
--locale <locale>- Apple's code for its language (en-US). The app's primary language when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool testers
An app's TestFlight testers, by email: list, invite, remove, invite again, and as a CSV.
taool testers --output csv writes the CSV invite --csv reads: four columns, first name, last name, email, and groups separated by ;. Inviting adds new testers to external groups, 50 addresses a day per app; removing can't be undone, so it waits for your approval in the taool app.
taool testers list [options]
The app's testers in every group, or one group's, and where each is.
--group <group>- Only one group's, by its name.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool testers invite [<emails>] [options]
Invite testers by email into external groups; Apple emails each the invite.
Hide My Email addresses can't get TestFlight's invites, so they're refused. 50 addresses a day per app.
<emails>- Their email addresses.
--csv <csv>- A CSV of testers: first name, last name, email, groups.
--group <group>- An external group, by its name. Repeat for several; a CSV row's groups win over these.
--first-name <first-name>- First name, for one new to your team.
--last-name <last-name>- Last name, for one new to your team.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool testers remove [<emails>] [options]
Take testers out of this app's TestFlight, every group of it; their testing of your other apps stays. Waits for your approval.
<emails>- Their email addresses.
--csv <csv>- A CSV of testers: first name, last name, email, groups.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool testers reinvite [<emails>] [options]
Have Apple email testers who haven't accepted their invite again.
<emails>- Their email addresses.
--csv <csv>- A CSV of testers: first name, last name, email, groups.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool testflight
An app's TestFlight: its test information, groups, automatic distribution, testers' sessions by day, and their feedback and crashes.
taool testflight groups [options]
The app's TestFlight groups, their testers, and which send each new build.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool testflight auto-distribute <group> <state> [options]
Have an external group get each new build, submitted to Beta App Review for it, or stop.
It sets up App Store Connect's webhook for the app, which tells taool of each upload, if it isn't already.
<group>- The external group, by its name.
<state>- on or off.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool testflight submit <build> [options]
Submit a build to Beta App Review, for external groups. A version's first build needs it; Apple approves later ones itself.
<build>- The build: its number (45), version and number ("1.2 (45)") or Apple's ID.
-p, --platform <platform>- ios, macos, tvos or visionos, where a number is on several.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool testflight sessions [options]
Testers' sessions and crashes a UTC day over the last 30, by build.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool testflight feedback [options]
What testers sent from TestFlight: screenshots and crashes, with their notes.
--save writes each to a folder (its note and facts, its screenshots, a crash's log), for reading later: Apple's screenshot links expire.
--kind <kind>- Only screenshot or crash, all of that kind rather than the newest of both.
--save <save>- A folder to write each one to, with its screenshots and crash log.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool testflight crash-log <feedback-id> [options]
A crash's log, printed: > 0aa1c3e9.crash saves it. Its ID is in taool testflight feedback.
<feedback-id>- The crash's ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
taool testflight info
The app's test information: what Beta App Review is told, and what testers read in each language.
taool testflight info alone shows it, and what Beta App Review still needs. A first build for external testers goes to Beta App Review only with a description and a feedback email in a language, and a contact.
taool testflight info set [options]
Set the app's test information: a language's description and links, and what Beta App Review is told; only what's given changes.
The demo account's password is --demo-password, else TAOOL_REVIEW_DEMO_PASSWORD where taool runs, as taool metadata push takes it; it's never printed or read back.
--language <language>- The language of the description and links, as App Store Connect writes it.
--description <description>- What testers read about the beta.
--feedback-email <feedback-email>- Where testers' feedback goes.
--marketing-url <marketing-url>- The beta's marketing URL.
--privacy-url <privacy-url>- The beta's privacy policy URL.
--contact-first-name <contact-first-name>- Beta App Review's contact: first name.
--contact-last-name <contact-last-name>- Last name.
--contact-email <contact-email>- Email.
--contact-phone <contact-phone>- Phone number, with its country code.
--sign-in-required, --no-sign-in-required- Whether Beta App Review signs in to try the app.
--demo-user <demo-user>- The demo account's user name.
--demo-password <demo-password>- The demo account's password.
--notes <notes>- Notes for Beta App Review.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool versions
An app's App Store versions: list them, make the next, or delete one never sent to App Review.
taool release prepare makes the version too, with the repo's listing; this is for making one on its own.
taool versions list [options]
The app's newest versions on every platform, and where each is.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-p, --platform <platform>- Only one platform's: ios, macos, tvos or visionos.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool versions create <version> [options]
Make a new App Store version, ready to prepare.
Apple allows one version being prepared per platform: taool release prepare renames that one instead.
<version>- Its number, as 1.2.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
--release-type <release-type>- manual, afterapproval or scheduled (with --earliest).
--earliest <earliest>- A scheduled release's earliest moment, as 2026-11-02T09:00:00Z.
--copyright <copyright>- Its copyright line, as 2026 Little Lantern.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool versions delete [<version>] [options]
Delete a version never sent to App Review, its listing's text with it. Can't be undone, so it waits for your approval.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool metadata
An app's App Store listing as files in its repo: pull it, push it, check it; and its categories, age rating and content rights.
Three layouts are read as they are: taool's own, JSON with Apple's field names (metadata/app.json, metadata/listing/<locale>.json, metadata/releases/<version>/<locale>.json with whatsNew and whatToTest; an "ios" or "macos" object holds what's only that platform's), fastlane's (fastlane/metadata/) and a JSON file per language (metadata/app-info/, metadata/version/<version>/). What App Review is told stays App Store Connect's unless metadata/review.json says otherwise, a release's own metadata/releases/<version>/review.json over it with only what differs for that release; metadata pull doesn't download it unless you pass --app-review-info, which writes metadata/review.json. The demo account's password comes from TAOOL_REVIEW_DEMO_PASSWORD where taool runs, else a review.json's demoAccountPassword or fastlane's demo_password.txt, and is never printed or pulled.
taool metadata pull [<version>] [options]
Write a version's listing from App Store Connect into the repo's files.
A file that says something else already is only written over with --force; files are never deleted. App Review Information (contact, demo account name, notes) isn't pulled unless you ask: --app-review-info writes it to metadata/review.json, and from then on each pull keeps that file up to date.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--layout <layout>- taool, fastlane or json: the repo's layout to read or write, when it has several or none yet.
--force- Write over files that say something else.
--app-review-info- Also write App Store Connect's App Review Information (contact, demo account name, notes) to metadata/review.json, which later pulls keep up to date.
taool metadata push [<version>] [options]
Send the repo's listing to App Store Connect: each language's text, the copyright, Content Rights and what App Review is told.
Only what differs is sent, checked against Apple's limits first. A version waiting for App Review takes its own text, What's New among it, never the name, subtitle or privacy links. A version that's out takes only its promotional text, which reaches users at once, so it waits for your approval. Content Rights is the app's, so it's sent whatever state the version's in.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--layout <layout>- taool, fastlane or json: the repo's layout to read or write, when it has several or none yet.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool metadata validate [<version>] [options]
Check the repo's listing on its own: Apple's limits, placeholder text, keywords, translations older than the primary language's, assets.
Only the assets (screenshots, app previews, header and search results assets) ask taool, for Apple's displays and specs they're checked against, when you're signed in and the app is known; videos are read on the Mac only. Exits 1 on an error, and with --strict on a warning too. taool release check also checks it against App Store Connect.
<version>- The version whose release files to read too, as 1.2.
--primary <primary>- The primary language, which translations are compared with: en-US to start with.
--strict- Fail on warnings too.
--layout <layout>- taool, fastlane or json: the repo's layout to read or write, when it has several or none yet.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool metadata categories
The app's primary and secondary categories on the App Store.
taool metadata categories alone shows them. Changed, they show with the next version App Review approves.
taool metadata categories set [options]
Set the app's categories, as App Store Connect names them: --primary Games --subcategory Puzzle --secondary Productivity.
--primary <primary>- The primary category.
--subcategory <subcategory>- A game's subcategory of the primary: up to two.
--secondary <secondary>- The secondary category, or none to take it off.
--secondary-subcategory <secondary-subcategory>- A game's subcategory of the secondary: up to two.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool metadata age-rating
The app's age rating: App Store Connect's questions, and the rating its answers give.
taool metadata age-rating alone shows the answers. Set them by Apple's question names: how often (none, infrequent-or-mild, frequent-or-intense), yes or no, or a value of the question's own: taool metadata age-rating set --answer violenceCartoonOrFantasy=infrequent-or-mild --answer messagingAndChat=yes, or a JSON file of them.
taool metadata age-rating set [options]
Answer App Store Connect's age rating questions: only those given change.
--answer <answer>- An answer, question=answer: violenceCartoonOrFantasy=none, messagingAndChat=yes. Repeat for each.
--file <file>- A JSON file of answers by question name, as taool metadata age-rating --json prints them.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool metadata content-rights
The app's Content Rights: whether it contains, shows or accesses content of others, which App Review requires answered.
taool metadata content-rights alone shows the answer. Content of others is anything the app didn't make: music, video or images it licenses, a data feed, maps, what its users upload. Answering yes says you have the rights to it in every country the app is sold in; App Review may ask you to show them. It's the app's, whatever version it's on, and metadata/app.json's contentRightsDeclaration in taool's layout, which metadata push sends.
taool metadata content-rights set --third-party-content <third-party-content> [options]
Answer Content Rights: yes, the app uses content of others and has the rights to it; or no, none.
--third-party-content <third-party-content>- yes: it contains, shows or accesses content of others, and you have the rights to it. no: it doesn't.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool assets
An app's App Store assets from its repo, sent straight to Apple: screenshots, app previews, its header and search results assets.
Each kind has a folder in metadata/: screenshots/ (or fastlane's fastlane/screenshots/), previews/, header/ and search-results/, each <locale>/<display>/, a folder named as App Store Connect names the display (iPhone 6.9) or as Apple's placement group (IPHONE_DYNAMIC_ISLAND_LARGE_PROFILE): taool assets sizes lists both, with the sizes each takes. A file straight in a language's folder goes by its size. Each folder's files go in their names' order (2 before 10). A display with no files in the repo is left as it is; one with files shows exactly those. taool assets pull starts the repo from what App Store Connect shows; push sends every kind at once.
taool assets screenshots
An app's App Store screenshots from its repo, sent straight to Apple.
In metadata/screenshots/<locale>/<display>/, or fastlane's fastlane/screenshots/<locale>/, each display told by its size.
taool assets previews
An app's app previews, the videos before its screenshots, from its repo, sent straight to Apple.
In metadata/previews/<locale>/<display>/, as .mov, .mp4 or .m4v, up to 3 per display size. Each video's poster frame can be set in metadata/previews/frames.json, by its path from there: {"en-US/iPhone 6.9/01.mov": "00:00:05:00"}; one without gets Apple's.
taool assets header
The image or video atop an app's product page, from its repo, sent straight to Apple.
One a language, in metadata/header/<locale>/: iOS and iPadOS 27 show it. A video's poster frame is set in metadata/header/frames.json, as previews' are.
taool assets search-results
The image or video an app shows in App Store search results, from its repo, sent straight to Apple.
One a language, in metadata/search-results/<locale>/: iOS and iPadOS 27 show it; without one, the App Store shows the app's events, previews and screenshots there. The same file as the header's is sent once. A video's poster frame is set in metadata/search-results/frames.json.
taool assets pull [<version>] [options]
Download a version's assets from App Store Connect into the repo, each display's in its order.
Each language's displays go in metadata/<kind>/<locale>/<display>/ as 01.jpg, 02.jpg… (a video as it comes) in App Store Connect's order: the folder the repo has for the display already, else one named as App Store Connect names it (iPhone 6.9), or as Apple's placement group after taool config screenshot-folders ids. The repo's display folders named the other way are renamed first, or merged into the one already so named, never writing over a different file, which is left where it was and said; and each kind's pulled.json says which of Apple's assets each file is, so pushing them back sends nothing: commit it with them. A video's poster frame goes in its kind's frames.json. A display folder with other files in it is only written over with --force.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--force- Write over display folders that have other files in them.
taool assets push [<version>] [options]
Send the repo's assets to a version, every language at once: each display shows the folder's, in its order.
A file App Store Connect has already, the same file in any language or display, isn't sent again; the bytes go straight to Apple, never through taool. Every kind goes as one change. A video is shown once Apple has processed it.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--locale <locale>- Only these languages, as en-US, several with commas (en-US,de-DE) or the flag again.
--display <display>- Only these displays, as iPhone Duo or IPHONE_DUO_PROFILE, several with commas or the flag again.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool assets sizes [options]
Apple's displays for each kind of asset, as App Store Connect has them now, and the sizes each takes.
Read from Apple's own catalog, so a display Apple adds is here at once. A folder named as a display's name (iPhone Duo; its inch mark left out) or its ID holds its files; iPhone's and iPad's screenshots and previews may be turned sideways.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool release
Get a version out: prepare it from the repo, check it, then release it and its phases.
taool release prepare 1.2 makes or renames the version being prepared, attaches its build and sends the repo's listing and assets; taool release check 1.2 says what App Review would trip on; taool submit 1.2 sends it. Releasing, and resuming or completing a phased release, reach users at once, so they wait for your approval. taool status says where each platform's versions are.
taool release prepare <version> [options]
Get a version ready for App Review from the repo: the version, its build and release, its listing and assets.
Makes the version, or renames the one being prepared (Apple allows one a platform); attaches the build; sets how it's released, whether in phases, and the copyright; sends each language's text and what App Review is told where they differ; sends the assets (screenshots, app previews, header and search results assets) as one change; and sets the build's What to Test. The release's settings come from metadata/releases/<version>/release.json in taool's layout, and the options here win over it.
<version>- The version, as 1.2.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
--build <build>- The build to submit, by its number (45), or latest: the newest of this version Apple has processed.
--release-type <release-type>- manual, afterapproval or scheduled (with --earliest).
--earliest <earliest>- A scheduled release's earliest moment, as 2026-11-02T09:00:00Z.
--phased, --no-phased- Release it in phases over 7 days, or to everyone at once.
--no-assets- Leave the screenshots, app previews, header and search results assets as they are.
--layout <layout>- taool, fastlane or json: the repo's layout to read or write, when it has several or none yet.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool release check [<version>] [options]
Say what App Review would trip on before you submit a version: exits 1 on an error, and with --strict on a warning.
Checks what App Store Connect will have, the repo's listing over its own: Apple's limits and what it requires in every language, placeholder text, translations older than the primary language's, keywords, the version and its build (processed, answered, not about to expire in TestFlight), what App Review is told, the assets (videos on the Mac only), the version's What's New page and the flags the code reads. Says how long App Review takes now.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--strict- Fail on warnings too.
--layout <layout>- taool, fastlane or json: the repo's layout to read or write, when it has several or none yet.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool release now [options]
Release a version App Review approved, which waits for you, to the App Store: it reaches users and can't be undone, so it waits for your approval.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool release phased <action> [options]
Pause, resume or complete the phased release of the version that's out.
Apple releases to more users each day over 7 days; paused, it waits up to 30 days in all. Resuming and completing reach more users at once, so they wait for your approval.
<action>- pause, resume or complete.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool submit
Send a version to App Review, or take it back.
taool submit 1.2 sends version 1.2; taool submit cancel 1.2 takes it back. A version Apple releases on its own once approved (after approval, or on its date) reaches users when it's submitted, so submitting it waits for your approval; one you release yourself doesn't. --wait waits for App Review's decision, hearing from App Store Connect's webhook, or without one from taool's own reads of App Review: exits 0 approved, 1 rejected, 10 when the time's up.
taool submit [<version>] [options]
Send a version to App Review: taool submit 1.2.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--wait- Wait for App Review's decision.
--timeout <timeout>- How long --wait waits, in minutes: a day to start with.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool submit cancel [<version>] [options]
Take a version back from App Review, to change it and submit it again.
<version>- The version, as 1.2. The one being prepared when left out.
-p, --platform <platform>- ios (to start with), macos, tvos or visionos.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events
An app's in-app events: list and view them, make one with its dates, give it its languages, card and details page, submit it, change or delete it.
An event is made as a draft, at once, and so are its languages, card and details page; taool events view says what App Review still needs. Name an event by its reference name or Apple's ID. Times are on the 24-hour clock or with am or pm (2026-11-20 16:00, 2026-11-20 4pm), in your Mac's time zone unless --time-zone names another, and reach Apple as exact moments: the event starts at that moment everywhere, 16:00 in Stockholm being 15:00 in London. An event lasts 15 minutes to 31 days, and the App Store promotes it up to 14 days before it starts (--promote-from). Sending one to App Review alone, changing one App Review approved and deleting one wait for your approval in the taool app.
taool events list [options]
The app's in-app events: where each stands, and when it runs.
--time-zone <time-zone>- The time zone of the times: Europe/Stockholm, America/New_York, CET, PST or UTC. Your Mac's to start with.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool events view <event> [options]
One in-app event in full: when and where it runs, its languages with their card and details page, and what App Review still needs.
<event>- The event: its reference name or Apple's ID.
--time-zone <time-zone>- The time zone of the times: Europe/Stockholm, America/New_York, CET, PST or UTC. Your Mac's to start with.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
taool events create <name> [options]
Make an in-app event, a draft until it's submitted, with its dates, and its first language, card and details page if you like.
taool events create "Winter Climb" --badge challenge --starts "2026-11-20 16:00" --ends "2026-11-20 18:00" --promote-from 2026-11-14 --deep-link https://example.com/climb --display-name "Winter Climb" --short-description "Reach the summit first" --long-description "A week of climbs, a leaderboard a day." --card card.png --details-page details.png. One command can give all App Review needs of it; taool events view says what's left.
<name>- Its reference name in App Store Connect, up to 64 characters, never shown on the App Store.
--badge <badge>- The label above its title: live-event, premiere, challenge, competition, new-season, major-update, special-event.
--deep-link <deep-link>- Where Open takes users in the app: a universal link (recommended) or the app's own URL.
--purpose <purpose>- Who it's for, which the App Store shows it to: everyone, new-users, active-users, lapsed-users. Everyone to start with.
--priority <priority>- high puts it before normal events on the app's page. Normal to start with.
--primary-language <primary-language>- Its primary language, what users whose language it hasn't see: en-US.
--starts <starts>- When it starts: 2026-11-20 16:00, or 2026-11-20 4pm.
--ends <ends>- When it ends, 15 minutes to 31 days after it starts: a time, or a day alone for its end.
--promote-from <promote-from>- When the App Store starts showing it, up to 14 days before it starts. Its start to start with.
--regions <regions>- The countries it shows in, separated by commas: countries (se,no), eu, eur or Apple's regions (europe). Every country to start with.
--time-zone <time-zone>- The time zone of the times: Europe/Stockholm, America/New_York, CET, PST or UTC. Your Mac's to start with.
--display-name <display-name>- Its name on the App Store in --language, up to 30 characters.
--short-description <short-description>- What its card says in --language, up to 50 characters.
--long-description <long-description>- What its details page says in --language, up to 120 characters.
--language <language>- The language of its name and descriptions, as App Store Connect writes it.
--card <card>- Its card: a landscape image or video, 16:9, from 1920 × 1080.
--details-page <details-page>- Its details page: a portrait image or video, 9:16, from 1080 × 1920.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events set <event> [options]
Change an in-app event: its name, badge, deep link, who it's for, priority, dates or countries; only what's given changes.
Before App Review has it, anything changes. Once approved, only its countries, priority and dates still to come, which reach users, so it waits for your approval in the taool app; once it's on the App Store, its start and end, and once it's started, its end alone. An event whose countries have dates of their own (App Store Connect's Customize Dates and Times) has those changed there.
<event>- The event: its reference name or Apple's ID.
--name <name>- A new reference name, up to 64 characters.
--badge <badge>- The label above its title: live-event, premiere, challenge, competition, new-season, major-update, special-event.
--deep-link <deep-link>- Where Open takes users in the app: a universal link (recommended) or the app's own URL.
--purpose <purpose>- Who it's for, which the App Store shows it to: everyone, new-users, active-users, lapsed-users. Everyone to start with.
--priority <priority>- high puts it before normal events on the app's page. Normal to start with.
--primary-language <primary-language>- Its primary language, what users whose language it hasn't see: en-US.
--starts <starts>- When it starts: 2026-11-20 16:00, or 2026-11-20 4pm.
--ends <ends>- When it ends, 15 minutes to 31 days after it starts: a time, or a day alone for its end.
--promote-from <promote-from>- When the App Store starts showing it, up to 14 days before it starts. Its start to start with.
--regions <regions>- The countries it shows in, separated by commas: countries (se,no), eu, eur or Apple's regions (europe). Every country to start with.
--time-zone <time-zone>- The time zone of the times: Europe/Stockholm, America/New_York, CET, PST or UTC. Your Mac's to start with.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events localize <event> --language <language> [options]
An in-app event's language: its name and descriptions on the App Store; only what's given changes.
taool events localize "Winter Climb" --language sv --display-name Vinterklättring --short-description "Nå toppen först" --long-description "En vecka av klättringar." A new language needs its name. Each language has its own card and details page: taool events card and taool events details.
<event>- The event: its reference name or Apple's ID.
--language <language>- The language, as App Store Connect writes it: en-US, sv, de-DE.
--display-name <display-name>- Its name on the App Store, up to 30 characters.
--short-description <short-description>- What its card says, up to 50 characters.
--long-description <long-description>- What its details page says, up to 120 characters.
--remove- Take this language off the event, with its card and details page.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events card <event> <file> [options]
Upload an in-app event's card, what Today and Search show of it: a landscape image or video, 16:9, in place of the one before.
Apple's sizes: taool assets sizes lists them (eventcard). A video loops, so it needs no sound.
<event>- The event: its reference name or Apple's ID.
<file>- The image (PNG or JPEG) or video (.mov, .mp4 or .m4v).
--language <language>- Only these languages, separated by commas: en-US,sv. Every language the event has to start with.
--frame <frame>- A video's poster frame, as HH:MM:SS:FF (00:00:05:00). Apple's choice to start with.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events details <event> <file> [options]
Upload an in-app event's details page, what opens from its card: a portrait image or video, 9:16, in place of the one before.
Apple's sizes: taool assets sizes lists them (eventdetails).
<event>- The event: its reference name or Apple's ID.
<file>- The image (PNG or JPEG) or video (.mov, .mp4 or .m4v).
--language <language>- Only these languages, separated by commas: en-US,sv. Every language the event has to start with.
--frame <frame>- A video's poster frame, as HH:MM:SS:FF (00:00:05:00). Apple's choice to start with.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events submit <event> [options]
Send an in-app event to App Review: on its own, which waits for your approval in the taool app, or with the version.
App Review looks at it with the platform's newest version. An app App Review hasn't approved yet sends its first event with its first version: --with-version adds it to the version's submission, and it goes when taool submit sends the version.
<event>- The event: its reference name or Apple's ID.
-p, --platform <platform>- The platform whose App Review submission it goes in: ios (to start with), macos, tvos or visionos.
--with-version- Go to App Review with the version being prepared, when taool submit sends it.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events cancel <event> [options]
Take an in-app event back from App Review, to change it and submit it again.
<event>- The event: its reference name or Apple's ID.
-p, --platform <platform>- The platform whose App Review submission it's in.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool events delete <event> [options]
Delete an in-app event: a draft, an approved one or an archived one, as Apple allows. Can't be undone, so it waits for your approval.
<event>- The event: its reference name or Apple's ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool products
An app's in-app purchases and subscriptions: list and view them, or make one, give it its languages and files, submit it or delete it (Pro).
A product is made as a draft, at once, and so are its languages, review screenshot and image; taool products view says what App Review still needs. Submitting it to App Review and deleting it wait for your approval in the taool app (but one going with a version, which taool submit sends); Apple deletes one only before it's approved.
taool products list [options]
The app's in-app purchases and subscriptions, and where App Store Connect has each.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool products view <product-id> [options]
One in-app purchase or subscription in full: its languages, review screenshot and image, and what App Review still needs.
<product-id>- Its product ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
taool products create <product-id> --kind <kind> --name <name> [options]
Make an in-app purchase or a subscription, a draft until it's submitted, with its first language and files if you like.
One command can make all App Review needs of it but its price (taool prices set --product) and where it's on sale (taool availability set --product): its display name and description in --language, a new subscription group's display name, its review screenshot and a promotional image. taool products view says what's left.
<product-id>- Its product ID, as the app's code asks StoreKit for it: com.littlelantern.tidepool.pro.
--kind <kind>- consumable, nonconsumable, nonrenewing or subscription (auto-renewable).
--name <name>- Its reference name in App Store Connect, up to 64 characters.
--group <group>- A subscription's group, by its name: made if the app has none of that name.
--period <period>- A subscription's period: 1w, 1m, 2m, 3m, 6m or 1y.
--level <level>- A subscription's level in its group, 1 the highest.
--family-sharable- Family Sharing on. Apple never lets it be turned off again.
--review-note <review-note>- A note for App Review.
--display-name <display-name>- The name customers see in --language, 2 to 30 characters.
--description <description>- Its description in --language, up to 45 characters.
--group-display-name <group-display-name>- A subscription's: its group's display name in --language, 2 to 30 characters, for a group that has none yet.
--language <language>- The language of the names and description, as App Store Connect writes it.
--review-screenshot <review-screenshot>- The screenshot App Review sees of it in the app, a PNG or JPEG.
--promo-image <promo-image>- Its promotional image, which customers see on the App Store: 1024 × 1024 pixels, PNG or JPEG.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool products localize [<product-id>] --language <language> [options]
A product's language: its display name and description, or with --group a subscription group's; only what's given changes.
Add a language or change one: taool products localize pro.monthly --language sv --display-name Pro --description "Allt, varje månad". A subscription group, each of its languages, shows its display name, and above it the app's name (App Store Connect's Use App Name) or --custom-name (Use Custom Name); --use-app-name goes back to the app's: taool products localize --group Pro --language en-US --display-name "Tidepool Pro". Each name is 2 to 30 characters, a description up to 45.
<product-id>- The product's ID; with --group, none.
--group <group>- A subscription group, by its name, in place of a product.
--language <language>- The language, as App Store Connect writes it: en-US, sv, de-DE.
--display-name <display-name>- The name customers see, 2 to 30 characters.
--description <description>- A product's description, up to 45 characters.
--custom-name <custom-name>- A group's: a name shown above it in place of the app's, 2 to 30 characters (App Store Connect's Use Custom Name).
--use-app-name- A group's: show the app's own name above it again (Use App Name).
--remove- Take this language off the product.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool products review-screenshot <product-id> <file> [options]
Upload the screenshot App Review sees of a product in the app, a PNG or JPEG, in place of the one before.
<product-id>- Its product ID.
<file>- The screenshot.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool products promo-image <product-id> [<file>] [options]
Upload a product's promotional image, which customers see on the App Store: 1024 × 1024 pixels, PNG or JPEG, in place of the one before; or take it off.
Optional: only for promoting it on the App Store, and shown when customers redeem a subscription's offer codes.
<product-id>- Its product ID.
<file>- The image; none with --remove.
--remove- Take the product's promotional image off.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool products submit <product-id> [options]
Send an in-app purchase or a subscription to App Review: on its own, which waits for your approval in the taool app, or with the version.
An app's first in-app purchase or subscription goes to App Review with a version: --with-version adds it to the version's submission, and it goes when taool submit sends the version, so it doesn't wait for approval here. A subscription's group goes with it while App Review hasn't approved the group.
<product-id>- Its product ID.
-p, --platform <platform>- The platform whose App Review submission it goes in: ios (to start with), macos, tvos or visionos.
--with-version- Go to App Review with the version being prepared, when taool submit sends it.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool products delete <product-id> [options]
Delete an in-app purchase or a subscription Apple hasn't approved. Can't be undone, so it waits for your approval.
<product-id>- Its product ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool prices
Change the price of the app, an in-app purchase or a subscription (Pro), starting on a date you choose, and follow or undo a subscription's change.
taool prices set [<price>] [options]
Set a price, starting on a date you choose, as customers in one country pay it; Apple works out every other country's. Waits for your approval.
The app's price, or with --product an in-app purchase's or a subscription's. Every country follows Apple's match of it, as in App Store Connect, but those overridden: --override and --keep, or the product's entry ("app" for the app's own) in the repo's metadata/pricing.json, a flag taking the file's place for its country. Without a price, only those countries change, their steps and percentages from Apple's match of the price now: a subscription's in the US or --country, the app's and an in-app purchase's in their base country. A percentage lands on one of Apple's prices at least that far (--round at-most or closest otherwise), and with --nice a percentage's or steps' price is the nearest nice one within 5%, as the file's "rounding" says too. With --until the app's or an in-app purchase's is temporary, a sale: from that day each country is back to what it had. A subscription's is set country by country by a job taool runs within the hour your App Store Connect key allows: --wait follows it, and taool prices undo takes the prices back until they start in the first country (10:00 UTC the day before). Current price is preserved for existing subscribers unless --existing-too applies the price increase to them. Every country whose price moves is shown first, from what to what and why, and asked about; --yes sends it without asking. With --derived-from in place of a price, a subscription's every country is another subscription's price there times --multiplier (a yearly at 7.5 times the monthly), landed on Apple's prices the closest way unless --round says otherwise, --nice the nearest nice one; --override and --keep still give countries their own (steps and percentages from the derived price), and the file's exact prices and keeps, never its steps and percentages, which are off Apple's match.
<price>- The price, as customers in the country pay it: 4.99, or 0 for a free app. Left out, only the countries overridden change.
--product <product>- An in-app purchase's or a subscription's product ID. The app's own price when left out.
--country <country>- The one country where customers pay it, never several: a storefront (se) or Apple's territory (SWE). Defaults to the United States when not provided.
--from <from>- The date it starts, within a year, as 2026-11-02; soonest when left out: the first date that hasn't begun anywhere yet, tomorrow or the day after.
--until <until>- A temporary price's end, as 2026-12-26: from then each country is back to what it had, its own price or Apple's match. The app's and an in-app purchase's; a subscription's sale is an introductory offer or an offer code.
--derived-from <derived-from>- Another subscription's product ID, in place of a price: each country's is its price there times --multiplier.
--multiplier <multiplier>- What --derived-from's price in each country is multiplied by, with a point for a part: 7.5.
--override <region=price>- Override a region's price, a country or several (eu, eur or Apple's regions such as europe): se=59 (exact), se=-2 or se=+2 (steps down or up Apple's price list there from its match), se=-10% or se=+10%, or se=keep. Several with commas (se=-1,eu=-10%) or the flag again; once each. An exact price only for a country or eur, whose countries all pay in euros: eur=4.99. A country named alone wins over eur, eur over eu, and eu over Apple's regions.
--keep <region>- A region left as it is, a country or several (eu, eur or Apple's regions such as europe): its price kept, or no introductory offer there. Several with commas (se,dk,eu) or the flag again; once each.
--parity- A subscription's Parity suggestion as its countries of their own: each storefront's share of Apple's match. Without a price only those change; with one, the rest go to Apple's match of it.
--index <index>- The index: taool (the taool Global Price Index), peers, worldbank, or one of the services it's the median of, by the name taool prices parity --help gives it. The taool Global Price Index to start with, the median of the others there.
--strength <strength>- How much of the index to follow, a percentage: 60% to start with.
--floor <floor>- The lowest share of Apple's match a price goes to: 50% to start with.
--cap <cap>- The highest share of Apple's match a price goes to: 125% to start with.
--tolerance <tolerance>- How near Apple's match counts as at it, either way: 15% to start with. --check allows as much off a target.
--exact- Each storefront's own share of Apple's match, rather than the nearest of the five zones.
--only <lower|raise>- Only lower prices, or only raise them: lower or raise.
--countries <countries>- Only these regions, separated by commas: countries (my,in), eu, eur or Apple's regions (asiapacific).
--round <at-least|at-most|closest>- How a percentage lands on Apple's prices: at-least (to start with: a cut at or past the percentage, a raise too), at-most or closest.
--nice- Each percentage's or steps' price the nearest nice one of Apple's within 5%, as a customer reads it: $4.99 or $4.49 near $5, 59 kr, ₹499.
--nice-within <percent>- How far a nice price may be from where the percentage or steps put it: 1% to 15%. With it, --nice.
--nice-ending <99|00>- Between two nice prices that read the same ($4.99 and $5.00), which to prefer: 99 (to start with) or 00. A preference, never a rule.
--all- List every country whose price moves, not only the top markets of those at Apple's price.
--existing-too- Apply price increase to existing subscribers, rather than preserve current price for them.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-y, --yes- Send it without asking. Otherwise what it changes is shown and asked about first, and without a terminal to ask at (an agent, CI) nothing's sent.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool prices tiers [<product-id>] [options]
Every price Apple has in a country for the app, an in-app purchase or a subscription, the nice ones marked.
What a price can be set to there, with your proceeds as Apple reports them and the share of the price that isn't (Apple's commission and any tax in the price): the app's own price without a product ID, else the product's (a subscription's list is its own). A nice price, as a customer reads it ($4.99 and $4.49, 59 kr, ₹499), is green and marked ●: the kind taool prices set --nice lands on. Today's price there is highlighted. From half today's price to twice it, or where it's free the cheapest 30, unless --all, --from or --to say otherwise (with no price there today, one of them says which); --json has every one.
<product-id>- An in-app purchase's or a subscription's product ID. The app's own price when left out.
--country <country>- The country: a storefront (se) or Apple's territory (SWE). The United States when left out.
--from <from>- The lowest price to list, as customers in the country pay it: 4.99.
--to <to>- The highest price to list.
--all- Every price Apple has there, the lowest to the highest.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool prices parity <product-id> [options]
Purchasing Power Pricing (PPP): a subscription's prices by what each market can pay, against the taool Global Price Index of what each country really pays for subscriptions (Pro).
Purchasing Power Pricing, also called PPP or regional pricing. Each storefront's price is a share of Apple's match of the US price (the price App Store Connect calculates automatically there from it, its equalized price): the index there (the taool Global Price Index, what each country really pays for subscriptions: the median of well-known subscription services and App Store peers, else estimated from World Bank figures; or one of them alone with --index), followed as far as --strength, held between --floor and --cap, kept at Apple's match within --tolerance, and put in the nearest of five zones (A 115%, B Apple's match, C 80%, D 65%, E 50%) unless --exact. A raise comes only where more of the subscription's trials pay than at home. It shows each storefront that would move, from its price now to its target with how sure the index is there, and what taool sees in your trials and prices. --write keeps it in the repo's metadata/pricing.json as each storefront's percentage off Apple's match, which taool prices set --product sends; --check fails (exit 1) while a price is further off its target than the tolerance, for CI. --round and --nice land each target on Apple's prices as taool prices set will (the pricing file's "rounding" under them). Below Pro, how many storefronts it would move.
<product-id>- The subscription's product ID.
--index <index>- The index: taool (the taool Global Price Index), peers, worldbank, or one of the services it's the median of, by the name taool prices parity --help gives it. The taool Global Price Index to start with, the median of the others there.
--strength <strength>- How much of the index to follow, a percentage: 60% to start with.
--floor <floor>- The lowest share of Apple's match a price goes to: 50% to start with.
--cap <cap>- The highest share of Apple's match a price goes to: 125% to start with.
--tolerance <tolerance>- How near Apple's match counts as at it, either way: 15% to start with. --check allows as much off a target.
--exact- Each storefront's own share of Apple's match, rather than the nearest of the five zones.
--only <lower|raise>- Only lower prices, or only raise them: lower or raise.
--countries <countries>- Only these regions, separated by commas: countries (my,in), eu, eur or Apple's regions (asiapacific).
--round <at-least|at-most|closest>- How a percentage lands on Apple's prices: at-least (to start with: a cut at or past the percentage, a raise too), at-most or closest.
--nice- Each percentage's or steps' price the nearest nice one of Apple's within 5%, as a customer reads it: $4.99 or $4.49 near $5, 59 kr, ₹499.
--nice-within <percent>- How far a nice price may be from where the percentage or steps put it: 1% to 15%. With it, --nice.
--nice-ending <99|00>- Between two nice prices that read the same ($4.99 and $5.00), which to prefer: 99 (to start with) or 00. A preference, never a rule.
--write- Write the suggestion into the repo's metadata/pricing.json: each storefront it moves off Apple's match, Parity's earlier entries replaced, your own kept where Parity leaves the storefront at Apple's match.
--check- Fail (exit 1) while any storefront's price is further off its target than the tolerance, listing them. For CI.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool prices status <job> [options]
How far a subscription's price change has got, country by country, and where it stopped.
<job>- Its ID, as the command that started it printed it.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
taool prices undo <job> [options]
Take back a subscription's price change while its day is still to come: what it made deleted country by country.
One done or stopped can be undone until it starts. Nothing it made has reached users, so it waits for your approval only where the sign-in asks about every change.
<job>- Its ID, as the command that started it printed it.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool intro-offers
A subscription's introductory offers: list them, make one in every country or some or take them off (Pro), and follow or undo the job.
taool intro-offers list <product-id> [options]
A subscription's introductory offers: each offer's terms and days, and its price and saving in the top markets.
Countries with the same offer are listed together, each with its price and what that takes off the full price there (pay as you go a period against a period; pay up front against as long at the full price). --all lists every country; --output json, csv and md always do, with the full price.
<product-id>- The subscription's product ID.
--all- Every country's price, not only the top markets'.
--regions <regions>- Only these regions, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu).
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool intro-offers create <product-id> --mode <mode> [options]
Make a subscription's introductory offer, starting on a date you choose, in every country or some: a free trial, or a price for some periods. Waits for your approval.
A paid one's price is set in one country and Apple's match everywhere else, or with --price -25% at least 25% off each country's own price, but the countries overridden (a percentage then off its own price): --override and --keep, or the subscription's entry under "intro-offers" in the repo's metadata/pricing.json, a flag taking the file's place for its country. A kept country gets no offer. Apple allows one introductory offer at a time in a country, so the one there then ends as this one starts, as in App Store Connect, and one still to come is refused. taool makes it country by country as your App Store Connect key's hour allows: --wait follows it, and taool intro-offers undo takes it back until it starts in the first country (10:00 UTC the day before), the one it ended ending as it did. What it makes is shown first and asked about; --yes sends it without asking.
<product-id>- The subscription's product ID.
--mode <mode>- freetrial, payasyougo (a price each period) or payupfront (one price for the whole).
--duration <duration>- How long it lasts: 3d, 1w, 2w, 1m, 2m, 3m, 6m or 1y.
--periods <periods>- Pay as you go's periods, the subscription's own, up to 12; 1 to start with, and always for the others.
--price <price>- A paid one's price, as customers in --country pay it (each period's, or the whole for payupfront), or -25% for at least 25% off each country's own price.
--country <country>- The one country where customers pay --price, never several: a storefront (se) or Apple's territory (SWE). Defaults to the United States when not provided.
--from <from>- The date it starts, within a year, as 2026-11-02; soonest when left out: the first date that hasn't begun anywhere yet, tomorrow or the day after.
--until <until>- The date it ends, as 2026-12-31; left out, it doesn't end.
--regions <regions>- Only these regions, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu). Every country the subscription is sold in when left out.
--override <region=price>- Override a region's price, a country or several (eu, eur or Apple's regions such as europe): se=59 (exact), se=-2 or se=+2 (steps down or up Apple's price list there from its match), se=-10% or se=+10%, or se=keep. Several with commas (se=-1,eu=-10%) or the flag again; once each. An exact price only for a country or eur, whose countries all pay in euros: eur=4.99. A country named alone wins over eur, eur over eu, and eu over Apple's regions.
--keep <region>- A region left as it is, a country or several (eu, eur or Apple's regions such as europe): its price kept, or no introductory offer there. Several with commas (se,dk,eu) or the flag again; once each.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-y, --yes- Send it without asking. Otherwise what it changes is shown and asked about first, and without a terminal to ask at (an agent, CI) nothing's sent.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool intro-offers delete <product-id> [options]
Take a subscription's introductory offers off, in every country or some: those running and those to come.
It can't be undone, so it waits for your approval; taool then takes them off country by country as your App Store Connect key's hour allows, and new subscribers in each stop getting them as it does. What it takes off is said first and asked about; --yes sends it without asking.
<product-id>- The subscription's product ID.
--regions <regions>- Only these regions, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu). Every country when left out.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-y, --yes- Send it without asking. Otherwise what it changes is shown and asked about first, and without a terminal to ask at (an agent, CI) nothing's sent.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool intro-offers status <job> [options]
How far an introductory offer has got, country by country, and where it stopped.
<job>- Its ID, as the command that started it printed it.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
taool intro-offers undo <job> [options]
Take back an introductory offer while its day is still to come: what it made deleted country by country.
One done or stopped can be undone until it starts. Nothing it made has reached users, so it waits for your approval only where the sign-in asks about every change.
<job>- Its ID, as the command that started it printed it.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool offer-codes
An in-app purchase's or a subscription's offer codes: list them, make one, generate and download its codes, or turn one off for good.
An offer code is the deal: what it costs, for how long and who can redeem it. Its codes come after, from taool offer-codes generate: a batch of one-time use codes, or a custom code of your own. Every command but list and create names the offer with --offer, its name or its ID. Codes are like cash: they're never printed, not even with --json, only written to a file only you can read, each download in the log in the taool app. An offer and its codes are made at once; turning one off waits for your approval.
taool offer-codes list <product-id> [options]
An in-app purchase's or a subscription's offer codes, each with its batches of codes and custom codes.
<product-id>- The in-app purchase's or subscription's product ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool offer-codes create <product-id> --name <name> --for <for> [options]
Make an offer code: a subscription's free trial or price for some periods, or an in-app purchase's price. No codes yet.
A subscription's offer takes --mode and --duration, and who can redeem it is new, existing or expired; an in-app purchase's takes --price (0 for free), and who can redeem it is nonspender, activespender or churnedspender. Its price is set in one country and Apple's equal everywhere else. Apple allows 10 active offers per subscription, and per app for in-app purchases; once made, an offer can only be turned off.
<product-id>- The in-app purchase's or subscription's product ID.
--name <name>- Its reference name, up to 64 characters.
--for <for>- Who can redeem it, several separated by commas, or all: a subscription's new, existing or expired; an in-app purchase's nonspender, activespender or churnedspender.
--mode <mode>- A subscription's offer: freetrial, payasyougo or payupfront.
--duration <duration>- A subscription's offer: how long each period lasts, 3d, 1w, 2w, 1m, 2m, 3m, 6m or 1y.
--periods <periods>- A subscription's offer: how many periods, 1 to start with.
--replace-intro- A subscription's offer: in place of an introductory offer, rather than after it.
--no-auto-renew- A subscription's offer: the subscription ends with the offer, rather than renewing at its price.
--price <price>- What it costs (a subscription's a period), as customers in --country pay it; an in-app purchase's 0 for free.
--country <country>- The one country where customers pay --price, never several: a storefront (se) or Apple's territory (SWE). Defaults to the United States when not provided.
--regions <regions>- Only in these regions, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu). Every country the product is sold in when left out.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool offer-codes generate <product-id> --offer <offer> --count <count> [options]
Make an offer's codes: a batch of one-time use codes, or with --code a custom code of your own.
A batch is 500 to 25,000 codes, or 10 to 10,000 in the sandbox, each redeemed once, which Apple makes over a while, up to an hour: taool offer-codes download writes them to a file once it has, or --wait --file waits and writes them in one. A batch works until the latest day Apple allows, 180 days on, unless --expires says sooner. A custom code, as LAUNCH50, is redeemable --count times.
<product-id>- The in-app purchase's or subscription's product ID.
--offer <offer>- The offer: its name, as taool offer-codes list shows it, or its ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--count <count>- How many codes in a batch, or with --code how many times it can be redeemed, up to 25,000.
--code <code>- A custom code: letters and digits, up to 64. A batch of one-time use codes when left out.
--expires <expires>- The date they stop working, as 2026-12-31: a batch's within 180 days, the 180th day when not provided; a custom code's any day, none when not provided.
--sandbox- A batch of sandbox codes, for testing: never redeemable on the App Store.
--wait- Wait for Apple to make the batch, up to an hour, then write it to --file.
--file <file>- With --wait, the file to write the batch's codes to, as Apple's CSV.
--force- Write over a file that's already there.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool offer-codes download <product-id> --offer <offer> --file <file> [options]
Write an offer's batch of one-time use codes to a file only you can read, its newest unless --batch. Never printed.
Each download is in the log in the taool app. Keep the file like cash, and never commit it.
<product-id>- The in-app purchase's or subscription's product ID.
--offer <offer>- The offer: its name, as taool offer-codes list shows it, or its ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--batch <batch>- The batch's ID, as taool offer-codes list shows it. The offer's newest batch still on when left out, a live one before a sandbox one.
--file <file>- The file to write them to, as Apple's CSV.
--force- Write over a file that's already there.
taool offer-codes deactivate <product-id> --offer <offer> [options]
Turn an offer off for good, or only one batch of its codes or one custom code. Can't be undone, so it waits for your approval.
<product-id>- The in-app purchase's or subscription's product ID.
--offer <offer>- The offer: its name, as taool offer-codes list shows it, or its ID.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--batch <batch>- Only this batch of one-time use codes, by its ID, as taool offer-codes list shows it.
--code <code>- Only this custom code, as LAUNCH50.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool availability
Where the app, an in-app purchase or a subscription is on sale: list it, set, add or remove regions (a product's on Pro), and follow the app's job.
The app's availability, or with --product an in-app purchase's or a subscription's. A change waits for your approval and reaches customers at once: the app's goes country by country as your App Store Connect key's hour allows, --wait following it; a product's is made in one go. Whether the app goes on sale in countries Apple opens is set in App Store Connect; a product's takes --new-countries or --no-new-countries.
taool availability list [options]
Where it's on sale now, and whether Apple puts it on sale in countries it opens.
--product <product>- An in-app purchase's or a subscription's product ID. The app's own availability when left out.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
-o, --output <format>- json for taool's answer as JSON, for scripts and agents (--json for short); csv for a spreadsheet (> file.csv saves it); md for a Markdown table. For people when left out.
taool availability set --regions <regions> [options]
Put it on sale in exactly these regions, and off sale everywhere else. Waits for your approval.
--regions <regions>- Regions, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu).
--product <product>- An in-app purchase's or a subscription's product ID. The app's own availability when left out.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--new-countries, --no-new-countries- A product's: whether Apple puts it on sale in countries it opens. As it is when left out; App Store Connect sets the app's.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-y, --yes- Send it without asking. Otherwise what it changes is shown and asked about first, and without a terminal to ask at (an agent, CI) nothing's sent.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool availability add --regions <regions> [options]
Put it on sale in these regions too. Waits for your approval.
--regions <regions>- Regions, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu).
--product <product>- An in-app purchase's or a subscription's product ID. The app's own availability when left out.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--new-countries, --no-new-countries- A product's: whether Apple puts it on sale in countries it opens. As it is when left out; App Store Connect sets the app's.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-y, --yes- Send it without asking. Otherwise what it changes is shown and asked about first, and without a terminal to ask at (an agent, CI) nothing's sent.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool availability remove --regions <regions> [options]
Take it off sale in these regions. Waits for your approval.
--regions <regions>- Regions, separated by commas: countries (se,no), eu, eur or Apple's regions (europe), mixed as you like (us,eu).
--product <product>- An in-app purchase's or a subscription's product ID. The app's own availability when left out.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--new-countries, --no-new-countries- A product's: whether Apple puts it on sale in countries it opens. As it is when left out; App Store Connect sets the app's.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
-y, --yes- Send it without asking. Otherwise what it changes is shown and asked about first, and without a terminal to ask at (an agent, CI) nothing's sent.
-n, --dry-run- Say what it would do, and whether it would wait for approval, changing nothing.
taool availability status <job> [options]
How far an availability change has got, country by country, and where it stopped.
<job>- Its ID, as the command that started it printed it.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.
--wait- Follow the job until it's done, stopped or undone.
--timeout <timeout>- How long --wait waits, in minutes: 4 hours to start with, since a busy key's job can take hours.
taool ci
taool in CI: a token for one app, kept in the CI's secrets.
taool ci token --scopes <scopes> [options]
Make a CI token for one app (taool Pro), approved in the taool app, and put it where CI reads it.
The token is never printed: it goes to a GitHub repo's secrets (with GitHub's gh), a file only you can read, or the clipboard, for a CI service's settings. CI reads it as TAOOL_TOKEN. Like any sign-in it's listed in the taool app's Settings → Agents, where revoking it ends it at once, and it waits for approval as you pick there; it works only while the account is on Pro.
--scopes <scopes>- What it may do, comma-separated: apps, reviews, replies, feedback, taoolkit, testflight, release, sales, store.
--name <name>- Its name in the taool app.
--github <github>- A GitHub repo (owner/name) to keep it in as a secret, with gh; this repo's when given as "".
--file <file>- A file to write it to, only you can read.
--force- Write over a --file that's already there.
--copy- Copy it to the clipboard, to paste into a CI service's settings.
--secret <secret>- The secret's name.
-a, --app <app>- The app: its App Store ID, bundle ID or name. The repo's linked app when left out.