RIVIOO API · V1 · EARLY ACCESS

App Store & Google Play reviews, as a REST API

Fetch reviews for any iOS or Android app as clean JSON. Cache-first: recently requested apps return instantly; new apps are fetched live in seconds. Built on the same pipeline that powers rivioo.app exports.

Request access

Keys are issued personally during early access and usually arrive within a day.

Start here

Quickstart

First reviews in five minutes.

  1. Get a key.
    Request access and your key arrives by email within a day.
    Terminal
    export KEY=rk_live_your_key_here
  2. Find your app's id.
    Search is unmetered and never counts against your quota.
    Request
    curl "https://api.rivioo.app/v1/apps/search?q=spotify&store=android" \
      -H "Authorization: Bearer $KEY"
    Response · 200
    {
      "data": [
        {
          "app_id": {
            "android": "com.spotify.music"
          }
        }
      ]
    }
    Use app_id in the next step.
  3. Fetch reviews.
    Fresh data returns instantly as a 200 with your reviews. If we need to fetch live, you get a 202 instead. That's step 4.
    curl -X POST https://api.rivioo.app/v1/reviews/fetch \
      -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
      -d '{
        "store": "android",
        "app_id": "com.spotify.music",
        "limit": 500
      }'
  4. Got a 202? (Got a 200? You already have reviews — skip to step 5.)
    A 202 means a live fetch is running. Poll the meta.poll URL until status is completed (usually under a minute), then GET its reviews_url.
    Request
    curl "https://api.rivioo.app/v1/jobs/3f6f…" -H "Authorization: Bearer $KEY"
    Response · 200
    {
      "job": {
        "status": "completed",
        "reviews_url": "/v1/jobs/3f6f…/reviews"
      }
    }
  5. Page through the rest.
    Follow meta.next_cursor from each page until it's null. That's the whole API.
    Request
    curl "https://api.rivioo.app/v1/reviews?cursor=eyJ2IjoxLC…" -H "Authorization: Bearer $KEY"
    Reviews are only ever charged once. Re-fetching a page you already received is free.
Start here

Authentication

Pass your key as a bearer token on every request:

curl https://api.rivioo.app/v1/usage \
  -H "Authorization: Bearer rk_live_your_key_here"

Keys are shown once at issue time — only a hash is stored. If a key leaks, email us and we'll rotate it immediately.

Reference

Endpoints

Base URL
https://api.rivioo.app/v1

All paths below are relative to the base URL.  OpenAPI spec ↓  ·  Postman collection ↓

Fetch reviews for an app
POST /reviews/fetch

The core endpoint. If we have fresh data for the app, you get reviews immediately (HTTP 200). Otherwise a live fetch starts and you poll it (HTTP 202).

curl -X POST https://api.rivioo.app/v1/reviews/fetch \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{
    "store": "android",
    "app_id": "com.spotify.music",
    "country": "us",
    "limit": 500
  }'
FieldDescription
storeios or android (required)
app_idAndroid package name or iOS numeric track id (required)
country2-letter storefront code, default us
limitTotal reviews wanted, clamped to your plan's per-request max
freshness_daysHow old cached data may be before we refresh it (1–30, default 7)
allow_staletrue = serve older cached data instantly instead of refreshing

Cache hit (200): first page of reviews plus a next_cursor (same shape as /reviews below).

Response · 202 (cache miss)
{
  "job": {
    "id": "3f6f…",
    "status": "queued"
  },
  "meta": {
    "source": "scrape",
    "poll": "/v1/jobs/3f6f…",
    "estimated_seconds": 45
  }
}
Check a job's status
GET /jobs/{id}

Poll a fetch job. Status is queuedrunningcompleted (or failed).

Response · 200
{
  "job": {
    "id": "3f6f…",
    "status": "completed",
    "reviews_url": "/v1/jobs/3f6f…/reviews"
  }
}
Get a completed job's reviews
GET /jobs/{id}/reviews

First page of a completed job's reviews. Same shape and pagination as /reviews below.

Page through reviews
GET /reviews

Paginate with ?cursor=… — follow meta.next_cursor from any page until it's null. Pages default to 100 reviews (page_size up to 500). Each review:

Review object
{
  "id": "gp:AOqpTOH…",
  "store": "android",
  "app_id": "com.spotify.music",
  "country": "us",
  "lang": "en",
  "rating": 4,
  "title": null,
  "body": "Offline playlists are great on the subway…",
  "reviewer": "Jordan M.",
  "app_version": "9.0.28.630",
  "developer_reply": null,
  "developer_reply_at": null,
  "url": "https://play.google.com/store/apps/details?id=…",
  "posted_at": "2026-07-21T09:14:00.000Z"
}
Cursors expire after a short time. If one expires, re-request the first page. Reviews already delivered are never charged twice.
Check your usage Unmetered
GET /usage

Your plan, quota used/remaining, reset date, and today's refresh count.

Response · 200
{
  "plan": "pro",
  "quota": {
    "monthly_reviews": 75000,
    "used": 12480,
    "remaining": 62520,
    "resets_at": "2026-08-01T00:00:00.000Z"
  },
  "scrape_jobs_today": 14,
  "scrape_jobs_daily_cap": 60
}
Reference

Errors

Every error uses one envelope:

{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Monthly review quota (75,000) exhausted. Resets 2026-08-01T00:00:00Z.",
    "status": 429
  }
}
CodeStatusMeaning
UNAUTHORIZED401Missing, malformed, or unknown key
KEY_REVOKED / CLIENT_SUSPENDED403Account inactive — contact us
VALIDATION_ERROR400Bad parameter — the message says which
NOT_FOUND404No job with that id on your account
RATE_LIMITED429Over your per-minute request limit
QUOTA_EXCEEDED429Monthly review quota exhausted
SCRAPE_CAP_REACHED429Daily refresh allowance used — cached data still available
Reference

Rate limits & headers

Responses carry RateLimit-* headers (per-minute) and X-Quota-Limit / X-Quota-Remaining (monthly reviews). Quota counts reviews delivered to you (cached or fresh) per calendar month, UTC. Hard cap — no surprise overage charges. Unused quota doesn't roll over. Cached responses don't consume the daily refresh allowance.

Good to know

Versioning & stability

v1 is stable. Breaking changes ship as a new version with 90 days notice and a migration guide. We may add new fields to responses at any time, so build your parser to ignore unknown keys.

Good to know

Data coverage

Exactly what you get:

DimensionCoverage
StoresApple App Store and Google Play
StorefrontsEvery public country storefront, via the country parameter
LanguagesEach review carries a lang code. iOS storefronts return reviews in every language; Android fetches return English reviews per storefront in v1
History depthUp to the most recent 10,000 reviews per app per storefront
FreshnessLive fetches are current as of the request; cached data is at most freshness_days old (default 7)
FieldsRating, title, body, reviewer, app version, developer reply + timestamp, review URL, posted date
Pricing

Plans

Priced by reviews delivered per month. Hard cap — no surprise overage charges.

Indie
$9 /mo

Side projects & prototypes

  • Reviews / month 15,000
  • Max per request 2,500
  • Rate limit 30 req/min
  • Live refreshes / day 20
Request access
Scale
$99 /mo

Portfolios & market research

  • Reviews / month 300,000
  • Max per request 10,000
  • Rate limit 120 req/min
  • Live refreshes / day 200
Request access

Quota counts reviews delivered to you (cached or fresh) per calendar month, UTC. Unused quota doesn't roll over. Cached responses don't consume the daily refresh allowance.

Get a key

Request access and your key arrives by email, usually within a day. No card on file, cancel anytime.

Questions? admin@rivioo.app

Request API access

No card required · or email admin@rivioo.app directly

Request received

We'll review it and email your key to , usually within a day.