TransaktDocs
Concepts

Entitlement evaluation

How Transakt answers "may this tenant, or this user, use the product?".

There are two questions, answered by two endpoints of the product API.

The tenant question

GET /api/v1/entitlements/{tenantId}?product={slug} (add &plan={slug} for a plan-scoped answer) answers for the whole tenant, from its active subscriptions to the product in your workspace, never another partner's:

  • status: the tenant's state for the product; None when it never bought it.
  • accessLevel: Full while active, the product's suspended access level (ReadOnly by default) while suspended, otherwise None. Treat unknown future values as the most restrictive.
  • plans (every active plan) and plan (set when exactly one applies, or the plan you asked about).
  • edition: the highest-ranked edition among those plans; null when status is None.
  • capabilities: the feature switches of the active plans, combined (on if any is on).
  • quantity (seat limit; null means unlimited), validUntil, isTrial, trialEndsAt, cancelledAt and sources.
  • licenceModel: TenantWide, PerUserSeats, MicrosoftManaged or Mixed.
  • licenceOutcome: Licensed (active and tenant-wide), NotLicensed (no active subscription) or NotApplicable (active, but decided per user: ask the user question).
  • version: the highest subscription version considered, the same number webhook events carry.

The user question

GET /api/v1/entitlements/{tenantId}/eligibility?product={slug}&userObjectId={oid}, or POST to the same path with email in the body, answers for one person:

licenceOutcomeReasonsWhat to do
LicensedTenantWideEntitlement, SeatAssigned, MicrosoftLicensedGrant access.
NotLicensedTenantNotEntitled, PlanMismatch, NoSeatAssigned, MicrosoftNotLicensed, NoMicrosoftPlanDeny access and show why.
UnconfirmedMicrosoftNoLicencesReported, MicrosoftUnavailable, MicrosoftNotConfiguredNot a verdict. Apply your own grace policy and ask again later. Treat unknown future outcomes the same way.
ConsentRequiredDelegatedConsentMissingMicrosoft-managed licences can only be read for a delegated user: repeat the call with the user's token (scope Entitlement.Read) alongside your credential. A tenant administrator may need to consent once.

isEligible is true exactly when the outcome is Licensed. Per-user plans also return seats (quantity, assigned, isAssigned); Microsoft-managed plans return microsoftLicence.

Acting for a signed-in user

Your application may send the user's delegated token (audience the Transakt API, scope Entitlement.Read) together with its API key, or alone when your Entra application is a verified credential of the API client. The token's tenant must match {tenantId} (otherwise 403 entitlement.user_tenant_mismatch), and without userObjectId the question is about that user.

Caching

Answers carry an ETag and Cache-Control: private, no-cache: keep a copy and revalidate it with If-None-Match. Unconfirmed and ConsentRequired answers are no-store. Better still, keep your copy fresh from webhook events: every subscription and seat event carries the tenant's entitlement as of the change.

On this page