NorelioDeveloper documentation

Access check

Ask from your server whether a buyer's subscription access is paid and until when: request, response, grace period and error codes.

Your server asks Norelio whether subscription access for a given buyer email and product is paid, and until when. The request is made from your server with the partner's API key: never embed the key in a page a browser can read.

Request

http
GET https://app.norelio.eu/api/public/access-check?email={email}&productId={productId}
GET https://app.norelio.eu/api/public/access-check?clientReference={reference}&productId={productId}
Authorization: Bearer {api key}
ParameterWhereDescription
emailquery, one of the twoThe buyer's email to check. Either it or clientReference is required.
clientReferencequery, one of the twoYour account reference for the buyer, passed at checkout (the client reference). Either it or email is required; with both, either may match.
productIdquery, requiredYour product id.
Authorizationheader, requiredThe access-check key issued in the cabinet (API and webhooks, API key tab), sent from your server.
Example by email
curl -s "https://app.norelio.eu/api/public/access-check?email=buyer%40example.com&productId=prod_1a2b3c" \
  -H "Authorization: Bearer $NORELIO_API_KEY"

{"hasAccess":true,"validUntil":"2026-04-14T09:26:53.000Z","clientReference":"acc_10294"}
Example by client reference
curl -s "https://app.norelio.eu/api/public/access-check?clientReference=acc_10294&productId=prod_1a2b3c" \
  -H "Authorization: Bearer $NORELIO_API_KEY"

{"hasAccess":true,"validUntil":"2026-04-14T09:26:53.000Z","clientReference":"acc_10294"}

Instead of the email you can pass your own account reference for the buyer: the clientReference query parameter, the same value you passed at checkout (see the client reference section). One of the two is required; with both, either may match: when the email has no access, the emails of this product's orders carrying that reference are checked. The response has a third field, clientReference: the reference of this email's latest order for this product (for a subscription renewal, of the order the subscription started with), or null. Existing calls with an email alone keep working unchanged.

Response

The response always has three fields: hasAccess (boolean), validUntil (ISO 8601 date-time or null) and clientReference (string or null). You can ask only about the partner's own products and buyers: the partner is identified by the key, not by a request parameter — there is no such parameter.

FieldTypeDescription
hasAccessbooleanWhether access is open for this email/product pair right now: the paid period is still running, or less than 120 minutes have passed since its end (validUntil) — the grace for a renewal, which arrives within about an hour after the period ends. Access closed by the seller, a full refund or a lost dispute is closed at once, without grace.
validUntilstring (date-time) or nullEnd of the paid period, without grace; for access closed by the seller, a full refund or a lost dispute, the moment of closing; null for a non-subscription or non-existent access.
clientReferencestring or nullThe account reference of the access found: the reference of this email's latest order for this product (for a subscription renewal, of the order the subscription started with); null when there is none or there is no access.
Access is paid
{
  "hasAccess": true,
  "validUntil": "2026-04-14T09:26:53.000Z",
  "clientReference": "acc_10294"
}
No access
{
  "hasAccess": false,
  "validUntil": null,
  "clientReference": null
}

{"hasAccess":false,"validUntil":null,"clientReference":null} is the one answer for everything that is not a paid access: the buyer never paid, the product is not a subscription, or there is no such product. The response does not distinguish these cases. Access that existed and then closed answers hasAccess: false with a past date in validUntil.

Grace period and closed access

A recurring subscription charge arrives within about an hour after the end of the paid period. So that the buyer does not lose access for that time, the access check keeps a grace of 2 hours: hasAccess stays true for 2 hours after validUntil, while validUntil remains the date until which access is paid, without grace. If the renewal arrives, validUntil moves to the new period; if it does not, 2 hours after validUntil the answer becomes hasAccess: false.

If you store the date yourself — for example from the accessValidUntil field of the notifications — and decide by it on your side, keep the same grace: access is open for 2 hours after that date. Otherwise a buyer whose renewal is about to arrive loses access for that time. The exception is access closed deliberately (next paragraph): it has no grace.

Access closed by the partner in the cabinet (the "close access" action in the subscribers list) closes at once, without grace: from that moment the answer is hasAccess: false, and validUntil is the moment of closing. When the whole payment went back to the buyer — a full refund or a lost dispute — access is shortened by the full period paid by that payment, counted from the current validUntil, whichever payment set it. If the new date has already passed while access is still open, it closes the same way, at once and without grace, and validUntil is the moment of closing; this also happens with an earlier payment when less than its period is paid ahead. If the new date is still ahead, access is open until it plus 2 hours. Access that is already closed at that moment stays closed.

A partial refund deliberately does not close access: validUntil moves earlier in proportion to the refunded amount, and the 2 hours grace after the new date applies as usual. If the new date passed more than 2 hours ago, access is closed at once by the same rule.

Closed access is reopened by the next payment — a subscription renewal or a new purchase — and by the partner's "extend by a period" action in the cabinet; after that the grace applies again. Access closed by a full refund or a lost dispute returns to its previous date and the usual grace when that refund did not go through after all or the dispute was reversed in the seller's favour, provided nothing happened to the access after it was closed.

The most reliable approach is therefore to ask the access check every time the buyer comes: it already accounts for the grace, closing and refunds. If you still store the date yourself, remember that subscription events are not the only ones that change it: refund and dispute notifications (order.refunded_full, order.refunded_partial, order.dispute_resolved) carry no new date, and a cancelled refund or a dispute reversed in the seller's favour sends no notification at all. Compare the stored date with the access check after refund and dispute notifications and before refusing a returning buyer. An answer of hasAccess: false while the 2 hours after validUntil have not passed yet means access was closed deliberately: do not reopen it by that date.

In short: the paid period plus 2 hours of grace, except for access closed deliberately — by the partner, by a full refund or by a lost dispute — which closes at once. Ask the access check every time the user comes; it already knows.

Errors

StatusWhen
400the productId query parameter is missing, or neither email nor clientReference is given
401the key is missing or does not match
429too many requests in a row; the Retry-After header says in how many seconds to retry

The response is never cached on our side: it concerns one buyer of one partner. Do not cache it on yours. Requests are rate-limited per client address and per key; a 429 answer names the number of seconds to wait in Retry-After.