Trial SKUs that auto convert
07 Sept 2026
Trial SKUs that quietly become paid subscriptions
Nobody signs a contract. Someone in marketing wanted Power BI for a week, a project manager wanted to test Project Plan 3, a partner suggested trying Entra ID P2 "just to see". Thirty days later Microsoft does exactly what it said it would do on the sign-up page, and a line appears on an invoice that nobody in IT recognises.
This is not a billing bug. It is documented behaviour working as designed, in a place your monitoring almost certainly doesn't look. Six questions, in the order admins actually ask them.
How does a trial become a paid subscription with nobody approving it?
Because that is the deal. Microsoft's page on what happens when a subscription ends puts it in one sentence: "At the end of your trial period, we automatically start billing you for your subscription." The approval happened at sign-up, by whoever clicked.
The detail that turns a small surprise into a big one is the term. Adding a trial to a tenant renews "to an annual term subscription by default" unless recurring billing is turned off first. So the mistake isn't a month of Power BI you didn't need — it is twelve, and by the time it appears on the invoice you are inside the committed term rather than in front of it. That is the same one-way door the NCE annual commitment closes, reached by accident instead of by decision.
Two more numbers from the same sign-up flow are worth knowing. A trial added to an existing tenant comes with 25 free licences for the trial period — and the flow separately asks for "the number of licenses that you want to buy when the trial ends". Those are two different quantities, decided in the same three minutes, by someone who was thinking about the first one.
Who started it, and can I see their name?
Graph names them. Each companySubscription
carries ownerId — documented as "the object ID of the account
admin" — plus ownerType ("User") and
createdDateTime. Resolve that GUID against the directory and the
March click has a name on it.
The admin center shows the same thing in prose: Billing → Your products → Self-service trials lists the product, the purchaser name, the expiration date, the purchase price and the assigned users. It exists, it's one tab, and almost nobody opens it monthly — which is the entire reason this article has an audience.
Why doesn't /subscribedSkus tell me any of this?
Because it was never about subscriptions. The subscribedSku
resource is a seat-counting object: consumedUnits,
prepaidUnits, capabilityStatus,
servicePlans. Read the property list end to end and there is no
trial flag, no renewal date, no expiry, no purchaser. A trial SKU and a
three-year enterprise commitment are the same shape of row.
That matters because /subscribedSkus is what almost every
licence script and dashboard is built on, including the ones that find licence
waste. They are answering "how many seats are assigned", correctly, and
staying silent about "which of these bills me next month" because the object
they read cannot express it.
GET /directory/subscriptions returns the same tenant as a list of commercial subscriptions instead of seat pools — with isTrial, nextLifecycleDateTime, status, totalLicenses and ownerId on every row. Least privileged permission: Organization.Read.All. It is one unpaginated GET, and it is the difference between a licence inventory and a renewal calendar.
What is nextLifecycleDateTime actually counting down to?
Not "renewal", despite how everyone reads it. The documented meaning is narrower and more useful: the date the subscription "will move to the next state (as defined by the status property) if not renewed by the tenant". Same field, different destination depending on where the row is standing.
| Row looks like | What that date is |
|---|---|
isTrial: true, status: Enabled |
The day it starts costing money. This is the only row type where the date is a deadline for you, not a diary note. |
isTrial: false, status: Enabled |
The renewal date — and the one window where the seat count and the term are yours to change. |
status: Warning |
Past the end date, still fully working for users. The grace period, quiet by design. |
status: Suspended |
Users have lost the apps; admins can still get in and take the data out. A date here is a countdown to deletion. |
status: LockedOut / Deleted |
Terminal. Microsoft is explicit that buying the same subscription again does not bring the data back. |
Behind those statuses is a fixed clock: for most offers a subscription that ends sits Expired for 30 days — users fully working, nothing visibly wrong — then Disabled for 90, where users lose access and only admins can still reach the data, and then it is deleted. Three months of silence, then a cliff.
Can I just block self-service trials?
Partly, and the shape of "partly" is the point. Microsoft states it plainly:
self-service
purchases and trials "can't be completely turned off at the tenant level with a
single command". The AllowSelfServicePurchase policy is
per-product, so turning it off tenant-wide means turning off every product
individually — and by default all new products are set to allow
it. Microsoft ships a product, it is on.
Two more edges worth budgeting for: changes can take up to 72 hours to apply, and the trials themselves are not uniform. Some self-service trials require a payment method at sign-up and automatically convert; others require no payment method and don't auto-renew at all — but those are "only available to select customers with an existing subscription agreement". You cannot tell which kind you have by looking at the product name.
It already converted. What are my options?
Fewer than you'd like, and one of them is genuinely surprising: for a subscription a user bought or trialled themselves, you can't assign or unassign its licences at all. It isn't yours. The admin center gives you one button — Take control of this subscription — and from there two routes: move the users onto a subscription you already own (which cancels the original automatically), or cancel it outright and strip the licences.
Both are fine. Both are also a conversation with a colleague who thinks they bought a working tool, which is why the cheap version of this whole problem is a list you look at before day 30 rather than after.
The thing to actually build
Not a report. A filter: every subscription where isTrial is
true, sorted by nextLifecycleDateTime, checked more often than
your invoice arrives. It is one Graph call, one boolean and one date — and the
reason it doesn't exist in most tenants is that the object carrying those three
things is not the object anybody's licence tooling reads.
GraphPaaS collects
/directory/subscriptions per tenant on a schedule and keeps the
history, so a trial that appeared last Tuesday is a row with a date on it and a
name attached, weeks before it becomes a line on an invoice.
- companySubscription resource type — the
isTrialboolean, the exact definition ofnextLifecycleDateTimeas the move to the next state, the fullstatusenum, andownerIdas the account admin's object ID. - List subscriptions —
GET /directory/subscriptionsand its permissions:Organization.Read.Allleast privileged,Directory.Read.Allhigher. - subscribedSku resource type — the complete property list, with no trial flag, renewal date or purchaser anywhere in it.
- Try or buy a Microsoft 365 for business subscription — the 30-day trial, the 25 free licences, the separate "quantity to buy when the trial ends", and the default renewal to an annual term.
- What happens to my data and access when my subscription ends? — automatic billing at the end of a trial, and the Active → Expired (30 days) → Disabled (90 days) → Deleted clock.
- Manage self-service purchases and trials — no single tenant-wide off switch, new products default to allowed, up to 72 hours to apply, and that admins can't manage licences on a self-service subscription without taking it over.
Every trial in the tenant, with the date it stops being free — before the invoice tells you.
See your subscriptions →