Fictura
Entitlements
GET/api/v1/entitlements/{user_id}

Retrieve entitlement

Ask Fictura whether a user is currently entitled, instead of maintaining your own billing table. Derived from Stripe's and the stores' own webhooks; fails closed.

Authorization

Send your SDK app key in the x-api-key header. The key selects your app, and the lookup can only see that app's users.

Path parameters

user_id
string · required

Any identifier you've given Fictura for the user — your account id (the one that rode the checkout URL), the RevenueCat app user id, or the device id; the lookup matches all three. An unknown user answers status: "none" with a 200, so one code path handles everyone. The check is read-only — it never creates a user.

Response fields

is_active
boolean

Whether the user should see paid features right now. Trials and grace periods count as active.

status
enum

One of active, trialing, grace_period, expired, none, unknown. unknown means a granting event arrived with no expiry to reason about — deliberately not treated as active.

product_id
string · nullable

The plan — a Stripe price id for web purchases, a store product id otherwise.

store
string · nullable

Where the money moved: STRIPE, RC_BILLING, APP_STORE, PLAY_STORE.

period_type
string · nullable

NORMAL, TRIAL, or INTRO.

will_renew
boolean

False once the user has cancelled but before the period ends — the window a win-back has to land in.

expires_at
string · ISO 8601 · nullable

End of the paid period. Null when the user has never been entitled — and in the unknown case, where a granting event carried no expiry.

environment
string · nullable

PRODUCTION or SANDBOX. The verdict follows the user's most recent granting event's environment — a sandbox test purchase answers is_active: true with environment: "SANDBOX". Check this field before granting anything paid in production.

cURL
curl https://api.fictura.co/api/v1/entitlements/8f14e45f \
  -H "x-api-key: gk_..."
200 — Active subscriber
{
  "ok": true,
  "user_id": "8f14e45f-…",
  "is_active": true,
  "status": "active",
  "product_id": "price_1TmKgS…",
  "store": "STRIPE",
  "period_type": "NORMAL",
  "will_renew": true,
  "expires_at": "2026-09-10T18:22:41.000Z",
  "environment": "PRODUCTION"
}
200 — Unknown user
{
  "ok": true,
  "user_id": "someone-new",
  "is_active": false,
  "status": "none",
  "product_id": null,
  "store": null,
  "period_type": null,
  "will_renew": false,
  "expires_at": null,
  "environment": null
}

Client checks are hints

Growth.isSubscribed() on the client is a rendering hint — a modified client can lie to itself. Anything that costs you money should check here, server-side.

Semantics worth knowing: cancellation only flips will_renew — access runs to expires_at, and only an expiration event ends it; a failed payment yields grace_period, still active, while the card retries; the verdict is recomputed on every billing webhook and the clock is re-checked on every read.

On this page