API Documentation
review-iq v2 — REST API reference.
Authentication
All /v2/* and
/account/* endpoints
require an API key passed in the X-API-Key header.
Keys have the prefix riq_live_ followed by 32 hex characters.
X-API-Key: riq_live_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
Getting your API key
Sign in via Supabase Auth (Google or email). On first login, call
POST /auth/provision
with your Supabase JWT to provision an org and receive your key. The key is shown exactly once — save it immediately.
curl -X POST https://your-instance.run.app/auth/provision \
-H "Authorization: Bearer <supabase-jwt>"
# Response (key shown once — copy it now):
# { "api_key": "riq_live_...", "org_id": "...", "key_prefix": "riq_live_a1b2" }
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /demo/extract | None | Keyless demo (rate-limited) |
| POST | /v2/extract | API key | Single review extraction |
| POST | /v2/extract/batch | API key | Batch reviews (fire-and-forget) |
| POST | /v2/ingest/csv | API key | CSV bulk upload |
| GET | /v2/ingest/{job_id} | API key | Ingest job status |
| GET | /v2/ingest/{job_id}/result | API key | Download results (JSON or CSV) |
| GET | /v2/reviews | API key | List stored extractions |
| GET | /v2/insights | API key | Aggregated insights |
| POST | /auth/provision | Supabase JWT | First-login org + key setup |
| GET | /account | Supabase JWT | Key prefix + usage |
| POST | /account/regenerate-key | Supabase JWT | Revoke + reissue key |
Extraction response fields
All fields except product and
extraction_meta may be
null when
the information is absent or uninferable from the source review.
| Field | Type | Description |
|---|---|---|
| product | string | Product or service name extracted from review. Defaults to "unknown product". |
| stars | int | null | Explicit numeric star rating (1–5) stated by the reviewer. Null if not stated. |
| stars_inferred | int | null | Star rating inferred from sentiment and language when not explicit. |
| pros | string[] | List of positive aspects mentioned in the review. |
| cons | string[] | List of negative aspects or complaints. |
| buy_again | bool | null | Whether the reviewer indicates intent or willingness to repurchase. |
| sentiment | enum | null | Overall sentiment: positive | negative | neutral | mixed. |
| urgency | enum | Urgency level for customer-care triage: low | medium | high. Defaults to low. |
| topics | string[] | Product attribute topics discussed (e.g. "battery", "sound quality"). |
| competitor_mentions | string[] | Competitor brands or products mentioned by name. |
| feature_requests | string[] | Explicit feature requests or improvement suggestions from the reviewer. |
| language | string | Detected language code: en, hi, or hi-en. |
| review_length_chars | int | null | Character count of the original (pre-sanitization) review text. |
| confidence | float | null | LLM self-reported confidence score (0.0–1.0). May be null if model does not report it. |
| extraction_meta | object | null |
Provenance metadata:
model,
prompt_version,
schema_version,
extracted_at,
latency_ms,
input_hash.
|
Example response
{
"product": "BoAt Bassheads",
"stars": null,
"stars_inferred": 3,
"pros": ["sound quality"],
"cons": ["battery life", "overpriced for 2000 rupees"],
"buy_again": false,
"sentiment": "mixed",
"urgency": "low",
"topics": ["battery", "sound quality", "price"],
"competitor_mentions": [],
"feature_requests": [],
"language": "hi-en",
"review_length_chars": 104,
"confidence": 0.91,
"extraction_meta": {
"model": "llama-3.3-70b-versatile",
"prompt_version": "v2.0",
"schema_version": "1.0.0",
"extracted_at": "2025-01-15T10:23:45.123456",
"latency_ms": 842,
"input_hash": "sha256:a1b2c3..."
}
}
CSV Upload
Use POST /v2/ingest/csv to
upload a CSV file for bulk asynchronous extraction. Results are stored per-org and downloadable
via GET /v2/ingest/{job_id}/result.
Column requirements
- Must include a text column named one of:
review_text,review,comment, ortext - Optional:
productcolumn for product tagging - All other columns are passed through as-is
Limits
- Maximum rows: 500
- Maximum file size: 5 MB
- Content-Type:
multipart/form-data - Encoding: UTF-8
Example CSV
review_text,product,date
"Great earphones, sound is excellent","BoAt Bassheads","2024-01-15"
"Battery dies too fast for the price","BoAt Bassheads","2024-01-16"
Upload request + response
# Upload
curl -X POST https://your-instance.run.app/v2/ingest/csv \
-H "X-API-Key: riq_live_your_key" \
-F "file=@reviews.csv"
# Response — poll job_id for status
{"job_id": "b3f1a2d4-...", "total": 2, "status": "pending"}
# Poll status
curl https://your-instance.run.app/v2/ingest/b3f1a2d4-.../ \
-H "X-API-Key: riq_live_your_key"
# Download results when status == "done"
curl https://your-instance.run.app/v2/ingest/b3f1a2d4-.../result \
-H "X-API-Key: riq_live_your_key"
Rate Limits & Quotas
| Tier / Endpoint | Limit | Notes |
|---|---|---|
| Free tier (all extractions) | 100 / month | 429 returned when quota exceeded |
Demo endpoint (/demo/extract) |
30 req / min per IP | No API key required; no results stored |
| All other endpoints | 30 req / min (default) | App-wide slowapi limit; configurable per deployment |
HTTP 429 Too Many Requests
with a Retry-After header
indicating seconds until the window resets.
Language Support
Language is auto-detected from the review text — no parameter needed.
The detected code is returned in the language field of the response.
| Code | Language | Script | Accuracy |
|---|---|---|---|
| en | English | Latin | 87.9% |
| hi | Hindi | Devanagari | 87.8% |
| hi-en | Hinglish | Roman-script code-mix | 81.2% |