Tinder Subscription Prices by Country and App Store Ratings avatar

Tinder Subscription Prices by Country and App Store Ratings

Pricing

from $5.00 / 1,000 storefront snapshots

Go to Apify Store
Tinder Subscription Prices by Country and App Store Ratings

Tinder Subscription Prices by Country and App Store Ratings

Live Tinder Gold/Plus/Platinum/Boost/Super Like prices by country from the App Store and Google Play, converted to USD, with ratings and change tracking between runs.

Pricing

from $5.00 / 1,000 storefront snapshots

Rating

0.0

(0)

Developer

Tim Zinin

Tim Zinin

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Tinder App Intel — Subscription Prices by Country and App Store Ratings

Tinder Gold, Plus, Platinum, Boost and Super Like prices, read straight from Tinder's own App Store and Google Play listings for any country you name, converted to USD and compared across storefronts, plus the app's rating, version and release notes — no login, no API key, no profile data, only what Tinder itself already publishes on its own store page.

Match Group, the company that owns Tinder, sets these prices per storefront, and the gap between the cheapest and most expensive country is often larger than most people assume — Gold ran from $13.99 to $24.99 across the US storefront alone at the time this README was written, and 32.99 € in Germany translates to roughly $37.62 at yesterday's ECB rate, well above every US price point. Nobody at Match Group publishes that comparison for you; this Actor builds it from the same page a phone would load, on a schedule, and hands it back as structured rows you can filter, chart or feed into a spreadsheet.

What you get

  • Real subscription prices, not an estimate. Every entry in inAppPurchases[] is read directly off the App Store's own in-app-purchase list for that country's storefront — Tinder Gold, Tinder Plus, 1 Boost, 3 Super Likes, Tinder Platinum, and so on — in the storefront's own currency and its own language. Nothing here is inferred from a marketing page or a press release; it is the same list a paying subscriber sees on their phone in that country, fetched fresh at run time.
  • planFamily normalizes the label across languages and punctuation. Apple's own feed spells the same plan differently depending on the storefront: 3 Super-Likes on the German page (hyphenated), 5 Super Likes on the same German page a few rows later (a space, no hyphen), Super Likes on the US page. All three collapse to the same stable planFamily: "SuperLike" so you can compare the same plan across a whole country list without writing your own string-matching logic. Anything this Actor's dictionary doesn't recognize comes back as planFamily: "other" — never a guess dressed up as a fact.
  • USD conversion, honestly null when the source currency has no published rate. Set convertToUsd (on by default) and every price in inAppPurchases[] gets a usd field computed from the European Central Bank's daily reference rate — the same rate a bank or an accountant would use, not a marked-up card-network rate. A handful of currencies this line's storefronts can show — Russian ruble, Kazakhstani tenge, UAE dirham, among others — are not part of the ECB's daily feed at all. For those, usd stays null and fxNote says exactly why, in the same row, instead of silently guessing a number that would be wrong by construction.
  • Track price and rating changes over time, per storefront. Set compareWithPreviousRun to true and give the run a watchId, and every row after the first for that watchId carries a changes[] array: new plans that appeared, plans that disappeared, price moves, rating moves of 0.05 or more, and version bumps, each compared against the last time you ran that exact country/platform pair under that watchId. The first run for a fresh watchId reports a clean baseline — changes: [] — never a false "everything changed" because there was nothing to compare against yet.
  • Google Play's own shape, not a forced match to the App Store's. The two stores do not publish the same information. Google Play's public listing exposes one aggregate iapPriceRange ({min, max, currency} across every in-app item the app sells) and never names individual plans; the App Store's listing does name them, one row per plan, but never states a plan's duration or the app's age rating anywhere in the feed this Actor reads. This Actor reports each store's own real shape side by side rather than inventing a merged view that would misrepresent what either store actually discloses.
  • Independent storefront reads, not a single global snapshot. Every country × platform pair is fetched on its own — a 404 for Russia does not affect the German row, a rating drop in the UK does not touch the US price list. You choose exactly which storefronts to check, from one country to sixty, and get one row per combination back.
  • Runs on Apify: schedule it daily or weekly to watch a price move, call it from the REST API or an SDK, wire it to a webhook, or export straight to JSON, CSV or Excel — see Integration recipes below for working examples of each.

Who uses it

  • Equity and credit analysts covering Match Group (NASDAQ: MTCH). Tinder is Match Group's largest single brand by revenue disclosure. A pricing-power read across storefronts — is Gold actually priced higher in high-income markets, did a price move follow a specific quarter's earnings call — is exactly the kind of primary-source input a research note cites, and it doesn't exist anywhere as a maintained dataset outside of building it yourself from the same public pages this Actor reads.
  • Competitor product and pricing teams at Bumble, Badoo, Hinge and every other dating app that competes with Tinder for the same subscriber. Before setting a Boost or Super Like price in a new country, a product team wants to know what the market leader charges there today, not last year. This Actor gives that read without anyone on the team manually opening the App Store in sixty different country settings.
  • ASO (App Store Optimization) and mobile-growth agencies that already track ratings, review velocity and keyword rank for a portfolio of dating apps and want subscription pricing folded into the same weekly report, from the same kind of public-page read they already trust for the rest of their dashboard.
  • Currency and FX researchers who use consumer subscription pricing as one input into purchasing-power-parity or price-discrimination studies — App Store and Google Play prices are set deliberately per country and are a cleaner signal for this than most retail goods, because there is no shipping, tariff or local-tax variance to strip out first.
  • Anyone tracking their own subscription cost over time or across a trip. A traveler who keeps Tinder Gold active while relocating between countries can watch whether re-signing up in a new storefront would be cheaper or more expensive than staying on their current billing country, using nothing but this Actor's own dataset history via watchId.

This Actor does not serve anyone looking for Tinder user profiles, photos, messages, match data or any other personal information about Tinder's own users — see "What this is NOT" under Evidence and boundaries. That is a different, and in this line's judgment indefensible, product; this one only ever reads the store listing every visitor to apps.apple.com or play.google.com already sees.

How to run it

  1. Click Try for free — no card is required on the free plan, and the default input below runs without any secret or account of your own.
  2. Pick your Countries — ISO-3166 alpha-2 codes, lowercase, e.g. us, gb, de. Leave the default (us, gb) for a first look, or list up to 60.
  3. Pick your Platforms — appstore, googleplay, or both (the default).
  4. Leave Convert prices to USD on unless you specifically want each storefront's own local currency and nothing else.
  5. Press Start. A run against the default input finishes in well under a minute; a full 60-country list against both platforms, at this Actor's own two-request-at-a-time pace toward Apple, takes longer — see Operating guide for what to expect on a large run.
  6. Pull the results from the Dataset tab (table, JSON, CSV, Excel or via the API), or read the free run-level summary from the Key-value store tab under the OUTPUT key.

Pricing

Pay-per-event, on the platform's standard PAY_PER_EVENT model: $0.005 charged once at run start, plus $0.005 per storefront that came back with real data (status: "ok", found: true — the platform calls this a result-found event internally; on the page it is simply "a storefront with data"). Every other outcome is free and is never billed under any event name: a country the app genuinely is not sold in (not_available_in_country), a source that did not answer after this Actor's own retries (rate_limited), a real parsing/source error (source_error), or a country code that was not a valid ISO territory in the first place (invalid_country). You are billed only for a storefront that actually delivered a usable row — never for one that came back empty, and never twice for the same storefront in one run.

The default prefill — two countries, two platforms, so up to four storefronts — resolves to $0.005 + up to 4 × $0.005 = up to $0.025 for a run where every storefront is genuinely on sale in that country (Tinder is sold in nearly every country checked in this line's testing, so in practice this usually lands at the full $0.025). Ten storefronts that all resolve — five countries across both platforms, say — comes to $0.005 + 10 × $0.005 = $0.055. maxStorefronts (default 10, maximum 120) is a hard ceiling on how many country × platform combinations one run will ever attempt; the excess combinations are dropped before a single request is made, with one free explanatory row pushed to the dataset (status: "truncated") naming exactly which storefronts were skipped — never a silent drop, and never a charge for work that never happened.

At startup, the Actor checks that result events are configured as paid events and that ordinary dataset writes are free. It reads the event price once at startup. Before each successful storefront row, it uses that price snapshot and reads the remaining run budget from the Apify SDK. It does not compare the configured prices with the numbers printed on this page. The live Pricing tab is authoritative; set a maximum run charge to bound your spend.

Input contract

FieldRequiredWhat it does
countriesnoISO-3166 alpha-2 codes, lowercase, e.g. ["us","gb","de"]. 1 to 60 codes. Duplicates (including different casing or stray whitespace, like "US" or " us ") are silently collapsed to one. A code that is not a real ISO-3166 territory at all comes back as a free invalid_country row rather than being rejected up front — the run still finishes and every other country in the list is still checked. A code that IS a real country, but one where the App Store or Google Play genuinely does not sell this app, comes back as a free not_available_in_country row, distinct from invalid_country — see Field dictionary for exactly how those two differ in the row itself. Default: ["us"].
platformsnoappstore, googleplay, or both. Up to 2 values. Any value this line does not recognize is dropped rather than failing the run. Default: both.
convertToUsdnoWhen true (the default), every priced entry in inAppPurchases[] gets a usd field computed from yesterday's published ECB daily reference rate. When false, usd is null throughout and no FX lookup happens at all — useful if you only ever want the storefront's own local price and plan to convert currencies yourself, on your own schedule, with your own rate source.
compareWithPreviousRunnoWhen true, every row is diffed against the last time this exact country/platform pair was run under the same watchId, and the result carries a populated changes[] array. Default: false.
watchIdnoNames which saved snapshot to diff against, so you can track several independent country/platform lists without them interfering with each other's history. Pattern: [a-zA-Z0-9_-]{1,40} — no colons or other punctuation (an early version of this line's diff logic used a colon-delimited key-value-store key internally, which broke on a watchId containing a colon; the pattern now simply forbids what would collide with that key format, and an invalid watchId falls back to "default" rather than failing the run). Default: "default".
maxStorefrontsnoHard ceiling on countries × platforms for one run, enforced before any request is made. Range: 1 to 120. Default: 10.
{
"countries": [
"us",
"gb"
],
"platforms": [
"appstore",
"googleplay"
],
"convertToUsd": true
}

Real happy, partial and failure output

One row per country × platform pair, plus one free explanatory row if maxStorefronts ever truncates the list. Every example below is real and unedited, copied as-is from an actual run of this exact code — never rewritten, trimmed of numbers, or invented for this page. For readability, a few fields that are either very long (releaseNotes) or genuinely empty for a given platform/status (installs, containsAds, iapPriceRange, fxNote, planSummary) are left out of some of the blocks below where they add nothing to read — the real Dataset row always contains every field regardless.

Happy path: a storefront that came back with real, priced data

App Store, United States — the full named plan list, all 10 entries this page carried at capture time. This is the block SPEC.md §7's own acceptance golden checks against: Gold and Plus must both be present, and every entry must carry amount > 0 with currency "USD".

{
"recordType": "storefront_snapshot",
"brand": "tinder",
"platform": "appstore",
"country": "us",
"appId": "547702041",
"observedAt": "2026-09-26T14:02:59.288Z",
"status": "ok",
"found": true,
"appTitle": "Tinder Dating App: Date & Chat App",
"rating": 4.2,
"ratingCount": 1751429,
"ratingHistogram": {
"1": 214657,
"2": 58997,
"3": 114363,
"4": 139574,
"5": 1223838
},
"version": "17.36.0",
"lastUpdated": "2026-09-22T16:46:21.000Z",
"inAppPurchases": [
{
"name": "Tinder Gold",
"priceText": "$14.99",
"amount": 14.99,
"currency": "USD",
"planFamily": "Gold",
"durationDays": null,
"usd": 14.99
},
{
"name": "Tinder Gold",
"priceText": "$18.99",
"amount": 18.99,
"currency": "USD",
"planFamily": "Gold",
"durationDays": null,
"usd": 18.99
},
{
"name": "1 Boost",
"priceText": "$7.99",
"amount": 7.99,
"currency": "USD",
"planFamily": "Boost",
"durationDays": null,
"usd": 7.99
},
{
"name": "Tinder Gold",
"priceText": "$13.99",
"amount": 13.99,
"currency": "USD",
"planFamily": "Gold",
"durationDays": null,
"usd": 13.99
},
{
"name": "1 Boost",
"priceText": "$6.99",
"amount": 6.99,
"currency": "USD",
"planFamily": "Boost",
"durationDays": null,
"usd": 6.99
},
{
"name": "Tinder Gold",
"priceText": "$24.99",
"amount": 24.99,
"currency": "USD",
"planFamily": "Gold",
"durationDays": null,
"usd": 24.99
},
{
"name": "Tinder Plus",
"priceText": "$9.99",
"amount": 9.99,
"currency": "USD",
"planFamily": "Plus",
"durationDays": null,
"usd": 9.99
},
{
"name": "3 Super Likes",
"priceText": "$9.99",
"amount": 9.99,
"currency": "USD",
"planFamily": "SuperLike",
"durationDays": null,
"usd": 9.99
},
{
"name": "1 Boost",
"priceText": "$3.99",
"amount": 3.99,
"currency": "USD",
"planFamily": "Boost",
"durationDays": null,
"usd": 3.99
},
{
"name": "5 Super Likes",
"priceText": "$4.99",
"amount": 4.99,
"currency": "USD",
"planFamily": "SuperLike",
"durationDays": null,
"usd": 4.99
}
],
"planSummary": {
"Gold": {
"minAmount": 13.99,
"maxAmount": 24.99,
"currency": "USD",
"minUsd": 13.99,
"maxUsd": 24.99
},
"Boost": {
"minAmount": 3.99,
"maxAmount": 7.99,
"currency": "USD",
"minUsd": 3.99,
"maxUsd": 7.99
},
"Plus": {
"minAmount": 9.99,
"maxAmount": 9.99,
"currency": "USD",
"minUsd": 9.99,
"maxUsd": 9.99
},
"SuperLike": {
"minAmount": 4.99,
"maxAmount": 9.99,
"currency": "USD",
"minUsd": 4.99,
"maxUsd": 9.99
}
},
"fx": {
"source": "ECB",
"date": "2026-09-25",
"rate": 1
},
"error": "",
"sourceUrl": "https://apps.apple.com/us/app/id547702041",
"changes": []
}

Google Play, United States — same app, the same run, this store's genuinely different shape. No named plans here at all; Google Play's public listing only ever exposes one aggregate price range across every in-app item Tinder sells on this platform.

{
"recordType": "storefront_snapshot",
"brand": "tinder",
"platform": "googleplay",
"country": "us",
"appId": "com.tinder",
"observedAt": "2026-09-26T14:02:59.291Z",
"status": "ok",
"found": true,
"appTitle": "Tinder Dating App: Chat & Date",
"rating": 3.9014534950256348,
"ratingCount": 9204414,
"installs": "500M+",
"lastUpdated": "2026-09-21T00:00:00.000Z",
"containsAds": true,
"iapPriceRange": {
"min": 0.49,
"max": 299.99,
"currency": "USD"
},
"inAppPurchases": [],
"fx": {
"source": "ECB",
"date": "2026-09-25",
"rate": 1
},
"error": "",
"sourceUrl": "https://play.google.com/store/apps/details?id=com.tinder&hl=en&gl=us",
"changes": []
}

App Store, Germany — a second country, a second currency, and both real Super Like spellings from the same live page. Captured from the same fixture this Actor's own test suite uses to guard the parser, then replayed through the real runDatingAppIntel entry point exactly the way tests/injected-fetch-paths.test.js replays a captured page through the same code path — the enrichment (currency, planFamily, USD conversion, planSummary) below is the real pipeline's own output, not hand-written. Notice "3 Super-Likes" (hyphen) and "5 Super Likes" (space, no hyphen) both landing on planFamily: "SuperLike", and every EUR amount carrying a real usd figure from that day's ECB rate (1.1403):

{
"recordType": "storefront_snapshot",
"brand": "tinder",
"platform": "appstore",
"country": "de",
"appId": "547702041",
"observedAt": "2026-09-26T15:50:13.855Z",
"status": "ok",
"found": true,
"appTitle": "Tinder Dating App: Chat & Date‑App",
"rating": 4.1,
"ratingCount": 235720,
"ratingHistogram": {
"1": 29076,
"2": 10790,
"3": 23341,
"4": 27875,
"5": 144638
},
"installs": null,
"version": "17.36.0",
"lastUpdated": "2026-09-22T16:46:21.000Z",
"releaseNotes": "Wir haben die Art und Weise verbessert, wie du Gleichgesinnte finden und kennenlernen kannst, die auch etwas Langfristiges, Aufregendes oder eine besondere Story suchen.\n\nFinde, was du wirklich suchst – mit Tinder.",
"containsAds": null,
"iapPriceRange": null,
"inAppPurchases": [
{
"name": "Tinder Gold",
"priceText": "13,99 €",
"amount": 13.99,
"currency": "EUR",
"planFamily": "Gold",
"durationDays": null,
"usd": 15.952797
},
{
"name": "Tinder Gold",
"priceText": "27,49 €",
"amount": 27.49,
"currency": "EUR",
"planFamily": "Gold",
"durationDays": null,
"usd": 31.346847
},
{
"name": "1 Boost",
"priceText": "9,99 €",
"amount": 9.99,
"currency": "EUR",
"planFamily": "Boost",
"durationDays": null,
"usd": 11.391597
},
{
"name": "1 Boost",
"priceText": "7,99 €",
"amount": 7.99,
"currency": "EUR",
"planFamily": "Boost",
"durationDays": null,
"usd": 9.110997
},
{
"name": "Tinder Gold",
"priceText": "13,99 €",
"amount": 13.99,
"currency": "EUR",
"planFamily": "Gold",
"durationDays": null,
"usd": 15.952797
},
{
"name": "Tinder Platinum",
"priceText": "32,99 €",
"amount": 32.99,
"currency": "EUR",
"planFamily": "Platinum",
"durationDays": null,
"usd": 37.618497
},
{
"name": "3 Super-Likes",
"priceText": "11,99 €",
"amount": 11.99,
"currency": "EUR",
"planFamily": "SuperLike",
"durationDays": null,
"usd": 13.672197
},
{
"name": "5 Super Likes",
"priceText": "5,99 €",
"amount": 5.99,
"currency": "EUR",
"planFamily": "SuperLike",
"durationDays": null,
"usd": 6.830397
},
{
"name": "Tinder Gold",
"priceText": "16,49 €",
"amount": 16.49,
"currency": "EUR",
"planFamily": "Gold",
"durationDays": null,
"usd": 18.803547
},
{
"name": "5 Super Likes",
"priceText": "9,99 €",
"amount": 9.99,
"currency": "EUR",
"planFamily": "SuperLike",
"durationDays": null,
"usd": 11.391597
}
],
"planSummary": {
"Gold": {
"minAmount": 13.99,
"maxAmount": 27.49,
"currency": "EUR",
"minUsd": 15.952797,
"maxUsd": 31.346847
},
"Boost": {
"minAmount": 7.99,
"maxAmount": 9.99,
"currency": "EUR",
"minUsd": 9.110997,
"maxUsd": 11.391597
},
"Platinum": {
"minAmount": 32.99,
"maxAmount": 32.99,
"currency": "EUR",
"minUsd": 37.618497,
"maxUsd": 37.618497
},
"SuperLike": {
"minAmount": 5.99,
"maxAmount": 11.99,
"currency": "EUR",
"minUsd": 6.830397,
"maxUsd": 13.672197
}
},
"fx": {
"source": "ECB",
"date": "2026-09-25",
"rate": 1.1403
},
"fxNote": null,
"error": "",
"sourceUrl": "https://apps.apple.com/de/app/id547702041",
"changes": []
}

Partial / "source said no": a country where Tinder genuinely is not sold

App Store, Russia — a real HTTP 404, not a guess. Apple's own App Store returned a genuine "this app is not available in this country's storefront" response for ru at capture time. error is an empty string here on purpose — the source answered cleanly, it is simply "no", not a technical failure, and the row is free, never billed:

{
"recordType": "storefront_snapshot",
"brand": "tinder",
"platform": "appstore",
"country": "ru",
"appId": "547702041",
"observedAt": "2026-09-26T13:21:46.294Z",
"appTitle": null,
"rating": null,
"ratingCount": null,
"ratingHistogram": null,
"installs": null,
"version": null,
"lastUpdated": null,
"releaseNotes": null,
"containsAds": null,
"iapPriceRange": null,
"inAppPurchases": [],
"planSummary": {},
"fx": null,
"fxNote": null,
"status": "not_available_in_country",
"found": false,
"error": "",
"sourceUrl": "https://apps.apple.com/ru/app/id547702041"
}

Failure path 1: a malformed country code, rejected before any request

A code that is not a real ISO-3166 territory at all. zz never reaches Apple or Google — this Actor's own input validation catches it first, and the free row explains exactly why, with an empty sourceUrl because no request was ever sent:

{
"recordType": "storefront_snapshot",
"brand": "tinder",
"platform": "appstore",
"country": "zz",
"appId": "547702041",
"observedAt": "2026-09-26T15:49:15.162Z",
"appTitle": null,
"rating": null,
"ratingCount": null,
"ratingHistogram": null,
"installs": null,
"version": null,
"lastUpdated": null,
"releaseNotes": null,
"containsAds": null,
"iapPriceRange": null,
"inAppPurchases": [],
"planSummary": {},
"fx": null,
"fxNote": null,
"sourceUrl": null,
"status": "invalid_country",
"found": false,
"error": ""
}

Failure path 2: the source did not answer after retries

A simulated exhausted-retries 429, run through the real code path. This Actor's fetch layer retries a rate-limited request with backoff before giving up; the row below is what the real runDatingAppIntel entry point produces once every retry has been exhausted, captured via the exact same fetchImpl injection point tests/injected-fetch-paths.test.js uses to test this path without spamming Apple's real servers on every node --test run — the row shape is identical to what a genuine live 429 produces, because it is the same code, the same real Apify ChargingManager, just with the network call itself swapped for a scripted response:

{
"recordType": "storefront_snapshot",
"brand": "tinder",
"platform": "appstore",
"country": "us",
"appId": "547702041",
"observedAt": "2026-09-26T15:49:06.492Z",
"appTitle": null,
"rating": null,
"ratingCount": null,
"ratingHistogram": null,
"installs": null,
"version": null,
"lastUpdated": null,
"releaseNotes": null,
"containsAds": null,
"iapPriceRange": null,
"inAppPurchases": [],
"planSummary": {},
"fx": null,
"fxNote": null,
"sourceUrl": "https://apps.apple.com/us/app/id547702041",
"status": "rate_limited",
"found": false,
"error": "http 429 after retries"
}

The free run-level summary for that same run (OUTPUT key in the key-value store) shows exactly how a rate-limited storefront is accounted for — storefrontsBilled: 0, partial: true, and the specific storefront named in rateLimitedStorefronts:

{
"brand": "tinder",
"watchId": "default",
"storefrontsRequested": 1,
"storefrontsProcessed": 1,
"storefrontsBilled": 0,
"storefrontsFree": 1,
"truncated": false,
"maxStorefronts": 1,
"deadlineHit": false,
"rateLimitedStorefronts": [
"appstore:us"
],
"notAvailableStorefronts": [],
"sourceErrorStorefronts": [],
"invalidCountryStorefronts": [],
"partial": true,
"fx": null,
"cheapestByFamily": {},
"mostExpensiveByFamily": {},
"generatedAt": "2026-09-26T15:49:06.513Z"
}

Field dictionary

FieldTypeMeaning
recordTypestringAlways "storefront_snapshot" — one fixed shape for every row this line's actors produce, across all five brands.
brandstringThis Actor's own brand key, always "tinder" here.
platformstring"appstore" or "googleplay" — which storefront this row is about.
countrystring | nullThe ISO-3166 alpha-2 code requested. null only ever appears on a sibling actor's RuStore row (RuStore doesn't vary by country) — every Tinder row always carries a real country code, since Tinder has no RuStore listing.
appIdstringThe App Store numeric id or the Google Play package name this row was fetched against — 547702041 or com.tinder, always the same two values for this Actor regardless of country.
observedAtstring (ISO 8601)The exact moment this Actor read the page, in UTC. Two rows from the same run typically differ by a few hundred milliseconds.
statusstringOne of five values, each described in its own row below.
foundbooleantrue only for status: "ok". false for every other status — a quick filter for "did this storefront actually deliver data" without checking the exact status string.
appTitlestring | nullThe store's own title for the app in that storefront's own language — "Tinder Dating App: Chat & Date" on the US App Store, "Tinder Dating App: Chat & Date‑App" on the German one (note the real, published German title literally ends in a non-breaking hyphen before "App" — reported exactly as Apple publishes it). null whenever found is false.
ratingnumber | nullThe store's own current average rating, out of 5, at the time of the read. On the App Store this Actor also cross-checks the rating against the page's own 1-through-5-star histogram sum and prefers the histogram's own total when one is present, since it reflects this exact parse rather than a potentially stale summary elsewhere on the same page.
ratingCountnumber | nullTotal number of ratings behind the rating figure.
ratingHistogramobject | nullApp Store only — {"1": n, "2": n, "3": n, "4": n, "5": n}, the count of ratings at each star level. Google Play's public page does not expose this breakdown, only the two aggregate numbers above, so this is always null on a googleplay row.
installsstring | nullGoogle Play only — the store's own bucketed install-count label ("500M+", "100M+", and so on). The App Store does not publish an install count at all, on any page this line reads, so this is always null on an appstore row.
versionstring | nullThe currently listed app version string.
lastUpdatedstring (ISO 8601) | nullThe date the store itself lists as the app's last update.
releaseNotesstring | nullThe "What's new in this version" text, in the storefront's own language, taken as-is including its own line breaks.
containsAdsboolean | nullGoogle Play only — the store's own "Contains ads" disclosure. The App Store's own feed does not carry an equivalent field, so this is always null on an appstore row.
iapPriceRangeobject | nullGoogle Play only — {min, max, currency} across every in-app item the listing sells, with no plan names attached. Always null on an appstore row, where the full named list lives in inAppPurchases[] instead.
inAppPurchasesarrayApp Store only — one entry per plan the page listed, {name, priceText, amount, currency, planFamily, durationDays, usd}. Always [] on a googleplay row.
inAppPurchases[].namestringThe plan's own name exactly as the storefront prints it — "Tinder Gold", "1 Boost", "3 Super-Likes". Never rewritten or normalized; planFamily is the normalized read, this field is the raw one.
inAppPurchases[].priceTextstringThe storefront's own formatted price string, exactly as printed — "$14.99", "13,99 €".
inAppPurchases[].amountnumber | nullThe numeric amount parsed out of priceText, locale-aware (comma vs. period as the decimal separator is decided by counting digits after the last separator, not by assuming one convention). null only when the currency itself could not be resolved with confidence — this Actor never reports an amount without knowing what currency it is in.
inAppPurchases[].currencystring | nullISO-4217 currency code resolved from the price string's own symbol/marker together with the storefront's own country (needed to disambiguate a bare $, which several currencies share).
inAppPurchases[].planFamilystringThis brand's normalized plan family — see the plan dictionary table right below this one. "other" when the name does not match anything in the dictionary; never guessed.
inAppPurchases[].durationDaysnumber | nullSet only when the plan's own name states a duration in words ("7 Days", "1 month") — Tinder's own IAP names on the App Store never do this for any plan this line has observed; every Tinder entry captured so far has durationDays: null for exactly that reason, not because the Actor failed to find one.
inAppPurchases[].usdnumber | nullThe amount converted to USD via yesterday's ECB daily reference rate, when convertToUsd is on and the ECB publishes a rate for that currency. null with a same-row fxNote explaining why otherwise (RUB, KZT, AED and several others are not in the ECB's daily feed at all).
planSummaryobjectOne entry per planFamily seen in this row's inAppPurchases[], each {minAmount, maxAmount, currency, minUsd, maxUsd} — the cheapest and most expensive price point for that family within this single storefront. {} on a googleplay row or any row where found is false.
fxobject | null{source: "ECB", date, rate} — the exact EUR-denominated rate this Actor used for this row's currency, or null when convertToUsd is off or the row's status means there was nothing to convert.
fxNotestring | nullSet only when convertToUsd was requested but the ECB has no rate for this row's currency — states which currency and why usd stayed null.
errorstringEmpty for not_available_in_country and invalid_country — the source (or this Actor's own input check) answered cleanly, it is genuinely "no", not a failure. A real, specific message for rate_limited and source_error.
sourceUrlstring | nullThe exact URL this row's data came from — https://apps.apple.com/{cc}/app/id547702041 or the equivalent Google Play URL. null only for invalid_country, where no request was ever sent.
changes[]arrayPopulated only with compareWithPreviousRun: true. Empty on a fresh watchId's first run; contains one baseline_reset entry if the previously saved snapshot for that watchId could not be read; otherwise one entry per detected change (new plan, removed plan, price move, rating move ≥0.05, version bump).

Plan dictionary — how planFamily is decided

planFamilyMatched from (case-insensitive substring, longest match wins)
Plus"Tinder Plus"
Gold"Tinder Gold"
Platinum"Tinder Platinum"
Select"Tinder Select"
Boost"Boost" (any name containing the word, EXCEPT one that also contains "Super" — that one is SuperBoost instead, since the longer match wins)
SuperBoost"Super Boost"
SuperLike"Super Like", "Super Likes", "Super-Likes" — every real spelling variant observed live, hyphenated or not, singular or plural
otheranything not matching the above — reported honestly rather than forced into the nearest-sounding family

Evidence and boundaries

What this Actor reads, exactly. Two public product pages, nothing else: https://apps.apple.com/{cc}/app/id547702041 and https://play.google.com/store/apps/details?id=com.tinder&hl=en&gl={cc}. Both are checked by fetching them, structurally parsing the returned HTML for the specific blocks this line's parser is built against (a JSON-LD aggregateRating block and an AnnotationItem structure carrying textPairs on the App Store; a similar structured block on Google Play), and validating the page's own shape before trusting anything it says — a canonical-id mismatch, a missing rating block, or an unrecognized page structure all fail closed with a source_error, never a best-effort guess dressed up as data.

robots.txt, checked, not assumed. apps.apple.com's robots file disallows /api/*, /v1/*, /WebObjects/*, /includes/* and any */search?* path; the plain product page path this Actor fetches is not among them. play.google.com's robots file disallows /store/getreviews, /store/search, /store/xhr and /store/apps/datasafety*; again, the plain product page path is not among them. This Actor never touches any of the disallowed paths on either domain — it does not search either store, does not read reviews through either store's dedicated review endpoint, and does not call either company's private API.

429 is a measured, engineered-around risk, not a guess. From this line's own test infrastructure's IP range, hitting Apple's App Store every 8 seconds produced 5 real 200 responses and 7 real 429s out of 12 consecutive requests — a genuine, reproduced rate limit, not a theoretical one. The same IP, paced at 30 seconds between requests with a 45-second retry after any 429, produced 5 real 200s out of 5. This Actor's own fetch layer caps concurrent requests toward Apple at 2 per run (Google Play carries no equivalent constraint in this line's testing) and retries a rate-limited request with backoff before giving up and reporting rate_limited — a real engineering response to a measured problem, not a documentation promise about a problem nobody checked for.

What the App Store's own feed does NOT publish, stated plainly rather than papered over. No plan ever carries a duration in this line's own observation of Tinder's IAP list — Apple's page states a price and a name, never "per month" or "per week" as a separate machine- readable field, so durationDays is null for every Tinder plan this Actor has ever captured, and will stay that way unless Apple's own feed changes. The App Store's product page likewise does not publish the app's age rating anywhere this line's parser reads, nor an install count (that is Google Play's own disclosure, not Apple's). None of these are gaps in this Actor's parsing; they are gaps in what the source itself chooses to make public on this specific page, and this README says so directly rather than leaving a buyer to discover it by trial and error.

What this Actor does NOT do, and will not be extended to do. It does not create an account, log in, or authenticate as a Tinder user in any way. It does not read, request or infer anything about any real Tinder user — no profiles, no photos, no names, no messages, no match data, no geolocation. It does not read App Store or Google Play customer reviews through either store's dedicated review feed or endpoint (both are disallowed by robots.txt and neither is fetched). It does not search either store — every app identifier this Actor ever uses is hard-coded into the brand's own configuration, never looked up by a search query. It calls no private API of Match Group's, Apple's or Google's. Every one of these is a deliberate, permanent boundary of this Actor's design, not a "not yet implemented" gap.

Decision routing

Use this Actor when you specifically want Tinder's own subscription prices, normalized into a stable planFamily you can compare across countries, with an app-title/rating/version read attached, and you are fine with the App Store and Google Play as the two sources (no Tinder API, because there is no public one that discloses pricing this way).

Use a general-purpose App Store or Google Play scraper instead — the kind of Actor already listed on Apify's Store as an "App Store scraper" or "Google Play scraper" without a brand name in its own title — when you want ANY app's page data, not specifically a dating app's subscription pricing normalized into a plan dictionary. Those Actors are broader and typically cheaper per row for a single raw page read; this Actor is narrower and deliberately adds the normalization, currency conversion and change-tracking layer on top, which is the whole reason it costs more per storefront than a bare page fetch would.

Use one of this Actor's own siblings instead of Tinder when the brand you actually care about is a different dating app: the same underlying engine, plan-dictionary approach and pricing model also ship as separate, brand-specific Actors for Twinby (adds RuStore, since Twinby is sold there and Tinder is not), Bumble, Hinge and Badoo — each with its own real plan dictionary tuned to that brand's own naming (Bumble's Premium/Premium+, Hinge's Hinge+/Membership/Roses, Badoo's Premium/Super Powers/Credits). If you need prices for several of these brands side by side, run each brand's own Actor with the same countries list and merge the datasets yourself, or watch for a future combined-brand version of this line.

Use this Actor's compareWithPreviousRun feature, not a fresh manual comparison, when the question is "did anything change since last time" rather than "what is the price right now" — the diff logic already exists, is billed the same way as a fresh read, and avoids the easy mistake of comparing rows that were captured under different convertToUsd settings or different watchIds by accident.

Do not use this Actor if what you actually need is Tinder USER data — profiles, swipes, matches, messages, or anything else that would require an account and would read information about real people rather than about the store listing itself. No configuration of this Actor will ever do that; it is a boundary, not a missing feature request.

Commercial playbooks

Weekly pricing-power tracking for an equity research desk. Schedule this Actor once a week against every storefront relevant to Match Group's disclosed revenue geography (the larger US/UK/DE/FR/JP/BR/AU set is a reasonable starting list), with compareWithPreviousRun on and a stable watchId like "mtch-coverage". Export the dataset to a spreadsheet or feed it straight into a model via the API. Over a quarter, this produces a real time series of Gold/Plus/Platinum pricing per country that did not exist as a maintained dataset before — every price move becomes a dated row in changes[], not something reconstructed from memory or a one-off manual check the week before an earnings call.

Competitive benchmarking before a Boost/Super Like price change. A product or growth team at a competing dating app reads this Actor's output on Tinder specifically, as the market leader's own price, against the exact countries they are about to launch or reprice in, pulls the current Gold/Boost/Super Like price points for that market, and uses them as one direct input into their own pricing committee's decision — a same-day read instead of a multi-hour manual App Store visit across a dozen country storefronts.

ASO agency monthly client report. An agency already tracking a client's own app ranking, rating trend and review velocity adds a "competitive pricing" section built entirely from this Actor's dataset, filtered to the two or three direct dating-app competitors most relevant to that client, refreshed on the same monthly cadence as the rest of the report, with zero extra manual research time per client per month.

Currency and purchasing-power research. A researcher studying price discrimination in digital subscriptions across countries uses Tinder Gold's price ladder (and the equivalent from this line's other brand Actors) as a clean, comparable input, since App Store and Google Play prices are set deliberately per country with no shipping or import-tax noise to strip out — pulling a fresh cross-country snapshot takes one run rather than sixty manual App Store visits with the storefront set to a different country each time.

Personal cost tracking while relocating or traveling. An individual keeping a Tinder Gold subscription active while their billing country changes runs this Actor with their old and new country in the same countries list and a personal watchId, and reads the price difference directly from planSummary in the resulting rows before deciding whether to re-subscribe in the new country or keep the old billing region.

Integration recipes

Schedule it (Apify Console). Open this Actor's page, go to the Schedules tab, and create a schedule with a cron expression — 0 8 * * 1 for "every Monday at 08:00 UTC" is a common choice for weekly price tracking. Attach the exact input you want repeated (the prefill above, or your own country/platform list with compareWithPreviousRun: true and a fixed watchId), and every scheduled run lands in the same Actor's dataset history, automatically diffed against the run before it.

Call it from the REST API.

curl -X POST "https://api.apify.com/v2/acts/zinin~tinder-app-intel/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"countries": ["us", "gb", "de"], "platforms": ["appstore", "googleplay"], "convertToUsd": true}'

The response includes a run id; poll GET /v2/actor-runs/{runId} for status, then read GET /v2/datasets/{defaultDatasetId}/items for the rows once the run finishes — or use the synchronous run-sync-get-dataset-items endpoint if you want the rows back in the same request and your country list is short enough to finish within that endpoint's timeout.

Call it from Node.js or Python via Apify's own SDK.

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('zinin/tinder-app-intel').call({
countries: ['us', 'gb'],
platforms: ['appstore', 'googleplay'],
convertToUsd: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

The Python client (apify-client on PyPI) mirrors the same call shape: client.actor('zinin/tinder-app-intel').call(run_input={...}).

Wire it to a webhook. From this Actor's page or via the API's POST /v2/webhooks endpoint, attach a webhook fired on ACTOR.RUN.SUCCEEDED (and, if you want to react to a partial run too, ACTOR.RUN.SUCCEEDED still fires when OUTPUT.partial is true — check that field in the payload rather than relying on the run's overall status alone) pointing at your own endpoint. Apify posts the run's summary, including the dataset id, so your endpoint can immediately pull the fresh rows rather than polling.

Call it as a tool from an LLM agent, via Apify's MCP server. Apify exposes published Actors as callable tools through its own Model Context Protocol server (https://mcp.apify.com, documented on Apify's own site); once this Actor is published, an MCP-aware agent (Claude, or any other MCP client) can call it by name with a structured input exactly like any other tool, without you writing custom integration code — the same countries/platforms/convertToUsd input shape works there as anywhere else.

Export straight to Google Sheets. From the Dataset tab, use Apify's built-in "Export data" action and choose the Google Sheets format, or connect this Actor's dataset to a Sheets-sync integration (Apify's own Google Sheets integration, or a Zapier/Make automation watching for ACTOR.RUN.SUCCEEDED) to keep a live spreadsheet updated on the same schedule as your scheduled runs — no code required for this path at all.

Plain CSV/Excel for a one-off analysis. The Dataset tab's Export button produces a CSV or Excel file of exactly the rows in that run, one row per country × platform pair, ready to open directly in a spreadsheet without any further transformation — the same shape as the JSON rows shown throughout this README, just flattened into columns.

Operating guide

Reading a partial run. Check OUTPUT.partial first, not the run's own top-level status — a run can finish successfully from the platform's point of view while some storefronts came back rate_limited or source_error. partial: true plus a non-empty rateLimitedStorefronts or sourceErrorStorefronts array tells you exactly which country:platform pairs to re-run, without re-running the whole list. A re-run of just the missing storefronts costs exactly what those storefronts would have cost the first time — nothing extra, and nothing double-charged for the storefronts that already succeeded.

When to retry a rate-limited storefront, and when not to bother. A single rate_limited row on an otherwise-successful run is usually transient — Apple's rate limiting is real but short-lived at the pacing this Actor already uses internally (see Evidence and boundaries). Waiting a few minutes and re-running just that storefront is normally enough. If the SAME storefront comes back rate_limited repeatedly across several attempts spread over an hour or more, that is worth treating as a real, ongoing block from that IP range rather than transient noise, and is exactly the kind of pattern this Actor's free, honest rate_limited status is designed to surface rather than hide behind a retry loop that never tells you.

Choosing a watchId strategy. One watchId per logical tracking list, not per run — if you track "MTCH investor coverage" weekly and "competitive Boost pricing" separately, give them two different watchIds so their histories never mix. Reusing the same watchId for two different countries/platforms lists on different schedules will not corrupt data (the diff is keyed per country/platform/watchId combination, not per whole run), but it does make the resulting changes[] history harder to reason about later, since two different audiences' expectations end up sharing one label.

maxStorefronts on a large country list. If you list more countries × platforms combos than maxStorefronts allows, the excess combinations are dropped before any request is made and reported in one free row (status: "truncated") that names exactly which storefronts were skipped, in the same dataset as the successful rows — not a separate log you have to go find. Raise maxStorefronts (up to 120) if you genuinely want a run this large in one go; otherwise, splitting a long country list across a few scheduled runs keeps each run's OUTPUT.deadlineHit comfortably false (this Actor's own soft wall-clock budget for one run is 280 seconds on the prefill-sized path, checked between storefronts rather than mid-fetch, so a combo already in flight is always allowed to finish).

Interpreting a usd: null price. This means exactly one thing: the ECB's daily reference rate feed does not include that currency, not that the price itself is unknown or unreliable. fxNote on the same row states which currency and repeats that fact in plain language. If you need a USD equivalent for one of these currencies anyway, treat amount/currency as the ground truth and apply whatever FX source your own use case already trusts — this Actor will not fabricate a number from a source it cannot vouch for.

FAQ

Why does Google Play never show named plans, only a price range? Because that is genuinely all Google Play's own public listing discloses — one aggregate min - max per item figure across every in-app item the app sells, never a per-plan breakdown. This is not a gap in this Actor's parsing; the App Store's listing is the one that names plans individually, and this Actor reports each store's real, different shape rather than inventing a merged view neither store actually publishes.

Do prices include currency conversion by default? Yes — convertToUsd defaults to true. Turn it off if you specifically want each storefront's own local price and currency with no FX applied at all.

What is the difference between not_available_in_country and invalid_country? not_available_in_country means the country code was real and this Actor genuinely asked the App Store or Google Play, and the store answered "this app is not sold here" (a real 404, in Tinder's case, for ru at the time this README was captured). invalid_country means the code itself was never a real ISO-3166 territory in the first place (zz), so no request was ever sent to either store at all. Both are free and both leave error empty, because in both cases the outcome is a clean "no" rather than a technical failure — but they are different facts and this Actor reports them as different statuses rather than collapsing them into one generic "not found".

Why is there no durationDays on any Tinder plan? Because Apple's own IAP feed for Tinder never states one — no plan's name says "per month" or "7 days" as a separate, parseable fact on the page this Actor reads. durationDays is populated whenever a storefront's own text states a duration (this happens on some of this line's other brand Actors, where a plan is literally named "7 Days Premium"); for Tinder specifically, the honest answer is that the source does not disclose it, so this Actor does not either.

Does this Actor read anything about real Tinder users? No, and it never will. It reads one public product page per country per platform — the same page anyone visiting apps.apple.com or play.google.com already sees, with no login. It does not create an account, does not authenticate, and has no code path that could read a profile, a photo, a message or any other personal data belonging to a real person. See Evidence and boundaries for the exact, permanent list of what this Actor does not do.

What happens if Apple rate-limits my run? The affected storefront comes back status: "rate_limited", found: false, a non-empty error naming the HTTP status, and is never charged. The run's free OUTPUT summary sets partial: true and lists the exact storefront in rateLimitedStorefronts, so you know precisely what to re-run rather than re-running the whole list. This Actor already paces its own requests toward Apple (at most 2 concurrent) specifically to keep this rare in normal use — see Evidence and boundaries for the measured numbers behind that choice.

Can I run this against every country in the world in one go? Up to 60 countries and up to 2 platforms per run (120 combinations at most, or fewer if maxStorefronts is set lower), enforced before any request is made. A run this large against Apple, at this Actor's own pacing, will take meaningfully longer than the default two-country example — see Operating guide for how the soft run-length budget and maxStorefronts truncation interact on a large list.

Found a wrong result, or need a country/plan-name edge case handled that this Actor missed? Open an issue on this Actor's own page. This line already fixes real parsing bugs found this way — several of the field-level details described in this README (the German title's non-breaking hyphen, the two different Super-Like spellings, a last-entry-dropped regex bug an earlier version of this parser had) were found and fixed exactly this way, against real captured pages, not assumed away.

Sources and rights

Every fact in this Actor's output comes from one of two public sources: Apple's own App Store product page at apps.apple.com/{cc}/app/id547702041, and Google's own Google Play product page at play.google.com/store/apps/details?id=com.tinder. Both are pages any visitor can open in a browser with no account; this Actor reads the same HTML a browser would receive, respects both domains' published robots.txt (see Evidence and boundaries for exactly which paths are and are not touched), and does not call any private, undocumented or authenticated API belonging to Apple, Google or Match Group.

Currency conversion, when requested, uses the European Central Bank's own published daily reference rate feed (ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml) — public data, no key or account required, and not this Actor's own estimate.

This Actor collects no personal data of any kind. It does not create an account with either store, does not authenticate, and has no code path that reads, infers or stores anything about a real Tinder user. "Tinder" and its associated plan names (Gold, Plus, Platinum, Boost, Super Like) are Match Group's own trademarks and terminology, reported here only because they are the storefront's own public labels for its own public prices — this Actor is an independent tool built against public store pages, and is not affiliated with, endorsed by, or operated on behalf of Match Group, Tinder, Apple or Google.

Found a wrong result, or need a case this README doesn't cover? Open an issue on this Actor's own page.


Built by zinin. Questions? Telegram @timzinin.