Skip to content

Integration  ·  Revenue operations

How to build subscription and entitlement provisioning

A customer signs on Friday and waits until Wednesday for the seats they bought. Here is how provisioning that keeps up actually works, the prompts that build it, and what running it demands.

Built with Tray Headless

  1. System Salesforce
  2. Step Derive entitlement
  3. Step Provision on start date
  4. Step Reconcile nightly
  5. System Product
Also Gmail NetSuite

Entitlement is derived from the contract rather than set by hand, and a nightly reconciliation catches any drift between what was sold and what is live.

The short answer

What is subscription and entitlement provisioning?

Subscription provisioning is four parts: entitlement derived from the contract instead of typed by somebody, activation on the contract start date instead of at signature, mid-term changes treated as amendments to the same subscription, and a reconciliation that catches drift between what was sold and what is live. Where this usually goes wrong is drift. Entitlement edited directly in the product to unblock somebody is invisible to billing, and the customer keeps that access for years.

What matters here

  • Derive entitlement from the contract. A number typed into the product by a support agent is a number nobody will ever reconcile.
  • Activate on the contract start date, not at signature. Those differ and billing follows the contract.
  • Handle mid-term changes as amendments to the same subscription, never as a second one.
  • Reconcile nightly. Entitlement edited in the product to unblock somebody is revenue leaking silently.
  • Never downgrade automatically on non-payment without a human. Suspension is a commercial decision.

Who this is for

You run revenue operations or product operations at a subscription company. Contracts are signed and access is granted by hand, and nobody is quite sure the two still agree.

How it works in practice

Everything that sits between a contract being signed and a customer having what they bought.

  1. 1

    Entitlement is derived from the closed contract

    Products, seats, limits and term, computed rather than typed.

  2. 2

    Provisioning is scheduled for the contract start date

    Which is often not the signature date, and billing follows the contract.

  3. 3

    Admin access goes to the named contact

    With an invitation, so somebody can actually get in on day one.

  4. 4

    Mid-term changes amend the same subscription

    Co-terminated, prorated, and never a second subscription for one customer.

  5. 5

    A nightly reconciliation compares sold against live

    Any difference is drift, and drift in either direction is a problem.

  6. 6

    Expiry warns, not cuts

    Renewal in progress means access continues; a decision to suspend is made by a person.

What provisioning is made of

Four, and the last is where the money quietly leaks.

Derived entitlement

Seats, features and limits computed from the contract line items. A typed number is one nobody can reconcile later.

Start-date activation

Scheduled to the contract start instead of fired at signature, because billing follows the contract and access should too.

Amendments in place

Seat and plan changes applied to the live subscription, prorated to the existing term end, so the product never holds two entitlements for one customer.

Drift reconciliation

A nightly comparison of entitlement against what the product actually grants. Manual edits are invisible until you look.

The Tray Headless prompts

Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.

Once per project, run /tray-workflows:set-workspace to pick the workspace these build in. Point it at a sandbox first.

  1. 1

    Start here: map contract lines to entitlement

    Everything downstream is this mapping.

    Headless skills build-workflow

    Use build-workflow. The systems in play are Salesforce and our
    product's admin API, or whatever we run in those seats.
    
    I need contract line items with products, quantities and term dates, and
    from the product the entitlement model: plans, seats, feature flags and
    usage limits.
    
    Then build the mapping from product code to entitlement as a table
    finance and product both understand. Every SKU we sell has to resolve to
    a concrete entitlement, and any SKU that does not is a sale nobody can
    fulfil.
  2. 2

    Derive entitlement, and activate on the start date

    Signature date and start date are different, and billing follows one of them.

    Headless skills build-workflow tray-patterns

    Use build-workflow. On closed won, derive the entitlement from the
    contract lines: plan, seat count, feature flags, usage limits, term start
    and end.
    
    Schedule activation for the contract start date rather than firing at
    signature. Those are frequently weeks apart, billing follows the
    contract, and granting access early gives away product you have not
    billed for.
    
    Provision the admin user from the named technical contact and send them
    an invitation. A subscription that is live but which nobody can log into
    is not provisioned, and it generates a support ticket on day one.
    
    Write the subscription id back to the opportunity so the two are linked
    permanently.
  3. 3

    Treat mid-term changes as amendments

    A second subscription for one customer breaks the renewal figure.

    Handle changes against the existing subscription, never by creating a
    new one:
    
      Seat increase: apply immediately, prorate to the existing term end
      Seat decrease: apply at renewal unless the contract allows otherwise,
      and never silently remove a named user
      Plan upgrade: apply immediately with proration
      Plan downgrade: apply at renewal, and flag for revenue recognition
      Term extension: co-terminate everything to the new end date
    
    Every amendment links to the parent contract. A mid-term upgrade filed as
    a new subscription produces two records for one customer, and the renewal
    number is wrong from that point onward.
  4. 4

    Reconcile nightly, in both directions

    Manual edits in the product are invisible until you look.

    Headless skills tray-gotchas tray-patterns

    Use tray-gotchas, then reconcile nightly between contract and product:
    
      Seats provisioned above what was sold, which is revenue leaking
      Seats below what was sold, which is a customer not getting what they
      paid for
      Features enabled with no contract line behind them
      Active subscriptions with no contract at all
      Contracts past their end date with access still live
    
    Report both directions. The over-provisioned list is usually longer and
    it is almost always somebody enabling something to unblock a customer,
    which is the right instinct and the wrong permanent state.
    
    Do not correct automatically. Report it and let a person decide, because
    removing access a customer is actively using is a conversation.
  5. 5

    Warn at expiry, never cut automatically

    Suspension is a commercial decision, not a scheduled job.

    At term end, warn instead of cut:
    
      30 days out, tell the account owner and customer success
      On the end date, if a renewal is in progress, continue access and flag
      it. Cutting off a customer mid-renewal loses the renewal.
      If there is no renewal and no engagement, suspend instead of delete,
      and require a person to confirm.
    
    Never automatically downgrade or suspend on non-payment. Route it to
    credit control and the account owner, and let a human decide.
    
    Then report: time from signature to working access, provisioning
    failures, drift in both directions, and expiries handled without a
    decision, which should be zero.
  6. 6

    Check it end to end, then hand the mapping over

    Because the catalogue changes and the mapping has to keep up.

    Run the per-step schema checks and the whole-workflow audit before this
    touches production.
    
    Then open the same workflow in Tray Build so revenue operations and
    product can maintain the SKU to entitlement mapping in the visual canvas.
    A new plan should be sellable and fulfillable the same week.

What it connects to

The contract says what was sold, the product grants it, and billing has to agree with both.

Salesforce

Read the closed contract and its line items, and write the subscription id and provisioning status back.

Reads and writes

NetSuite

Read the billing subscription and term, so entitlement and invoicing agree instead of drifting apart.

Reads

Okta

Provision the internal staff who administer entitlements. Customer identity belongs in the customer identity provider, not in the workforce directory.

Reads and writes

Gmail

Send the welcome and the invitation, because a live subscription nobody can log into is not provisioned.

Writes

Slack

Tell the account team when provisioning completes, and raise drift to whoever can decide about it.

Writes

Snowflake

Land entitlement history, so drift over time and time to access are measurable.

Writes

Same build, other stacks

The design does not change if you run something else in one of these seats. The same prompts build it against Microsoft Dynamics 365, SAP S/4HANA, Google BigQuery, Microsoft Teams, Azure Active Directory or Microsoft Outlook.

Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.

Running it in production

This grants paid access to your product. Drift in either direction costs money or goodwill.

The platform runs it, not a laptop under a desk

Scheduled activation on future start dates and the nightly reconciliation run on the same engine, whether or not anybody is watching.

Entitlement is always traceable to a contract line

Which line granted which seats and features. That is what makes the drift report actionable, not a list of mysteries.

Credentials live in the workspace, never in the repo

The product admin credential can grant paid access to anybody. It lives in your workspace, scoped and separately rotatable.

Revenue and product own the mapping

SKU to entitlement opens in Tray Build, so a new plan is sellable and fulfillable in the same week it is created.

Nothing is revoked automatically

Drift is reported and expiry is warned. Removing access a customer is using is a commercial conversation, not a scheduled job.

Questions people ask

Why activate on the start date rather than at signature?

Because those are frequently weeks apart and billing follows the contract. Granting access early gives away product you have not billed for, and doing it late generates a support ticket on day one.

Why handle changes as amendments?

Because the product would then grant access twice for one customer, and the older subscription usually keeps its entitlement long after the upgrade replaced it.

What is entitlement drift?

The gap between what was sold and what the product actually grants. It usually comes from somebody enabling a feature to unblock a customer, which is the right instinct and the wrong permanent state.

Should access be cut automatically at term end?

No. Warn at thirty days, continue access if a renewal is in progress, and require a person to confirm any suspension. Cutting a customer off mid-renewal loses the renewal.

Should non-payment trigger a downgrade?

Not automatically. Route it to credit control and the account owner. Suspension is a commercial decision with consequences a scheduled job cannot weigh.

Vibe-coding app guides

Vibe-code an entire app with Helix

This moves the data between systems. It does not give anybody a screen to work in. Build that app in Claude Code, Codex or Cursor, then deploy and run it governed on Tray Helix. Same kind of guide, same kind of prompts.

How to build a renewal tracker (opens helix.tray.ai in a new tab)

Last reviewed September 2026.