Gatekeeping

Verify access after payment with access checks

Use Licenzy runtime access checks to verify whether a subject currently has access after payment and entitlement updates.

Start free in test mode. Go live when you're ready.

Category: Integration Flow5 sections

POST /v1/access/check

This page is the canonical runtime contract for access verification: the smallest backend API surface your product calls when it needs a yes or no access decision.

After a Stripe payment, you still need to verify whether a user actually has access. Access should not be inferred from frontend state, browser redirects, or payment success alone. It must be checked against a reliable backend system, which in this flow is Licenzy.

The access check endpoint accepts only subject_ref. Licenzy derives the decision from the current entitlement state. Mode is inferred from the API key.

Access check requestConcrete integration example
HTTP
POST /v1/access/check
Authorization: Bearer lz_test_...
Content-Type: application/json

{
  "subject_ref": "user_123"
}
Access check responseConcrete integration example
JSON
{
  "subject_ref": "user_123",
  "allowed": true
}
Access denied responseConcrete integration example
JSON
{
  "subject_ref": "user_123",
  "allowed": false
}

allowed: false means Licenzy does not currently see usable entitlement state for that subject in the environment selected by the API key.

When to use access checks

This is required when your backend needs to decide whether a subject can proceed:

  • Protecting paid features or content.
  • Validating API access.
  • Enforcing subscription or credit-based access.
  • Checking access on every request.

Payment may start with checkout, but access checks should be performed server-side.

Common mistake: trusting payment status

Payment success does not guarantee that access is already active. Webhooks may not be processed yet, and frontend state can be stale or manipulated.

Access must always be verified through backend runtime endpoints. For the end-to-end sequence from payment initiation to access validation, see the full integration example.

When to use each read endpoint

Customer access summaryConcrete integration example
HTTP
GET /v1/customer/access/user_123
Authorization: Bearer lz_test_...

// Simplified example. Actual responses may include additional fields per entitlement.
{
  "subject_ref": "user_123",
  "has_access": true,
  "status": "active",
  "entitlements": [
    {
      "kind": "subscription",
      "status": "active",
      "available": true,
      "usage_remaining": 900,
      "availability_reason": "subscription_active",
      "expires_at": "2026-04-30T23:59:59Z"
    }
  ]
}
  • POST /v1/access/check returns the smallest access decision.
  • GET /v1/customer/access/:subject_ref returns access status plus entitlement summary.
  • GET /v1/entitlements/:subject_ref is the entitlement inspection endpoint.

/v1/access/check or /v1/customer/access/:subject_refshould be the source of truth for runtime access decisions.

Do not send extra fields
Do not send product_code or mode to the access-check endpoint. Those are not part of the confirmed runtime contract.