Admin: Grant Free Months - EyevinnOSC/community GitHub Wiki

Admin: Grant Free Months

Free-month grants are an admin-level business development tool that extends a tenant's existing paid subscription at no charge. A grant is a trial extension applied directly to the tenant's active Stripe subscription; it is not a customer-facing coupon or discount code. During the grant period, invoices are EUR 0.00 with a "Free trial" description. At the end of the grant, Stripe resumes charging the listed plan price automatically. For general subscription and pricing information, see Pricing.

When to Grant

Free-month grants are appropriate in the following situations:

  • Conference attendees — extending access for participants of sponsored events or workshops where OSC is featured
  • Strategic onboarding — giving a new customer time to evaluate the platform before committing to a paid billing cycle
  • BD discretion — any other case where a business development team member judges that a goodwill extension is warranted

Free-month grants are a business development tool. They are not available to customers through self-service and cannot be requested from within the OSC dashboard.

Distributing discounts at scale? Use Voucher Codes instead of individual grants — vouchers allow customers to self-redeem and can be shared in campaigns, at events, or in emails without requiring admin action per redemption.

Step-by-Step Workflow

  1. Open the admin tenant page at app.osaas.io/admin/tenant/[id]/, replacing [id] with the target tenant's ID.
  2. Locate the Grant free months card on the page.
  3. Set the number of months (1 through 12 inclusive).
  4. Enter a reason for the grant. This is stored in the grants-history table on the same page and is visible to other admins.
  5. Click Confirm to apply the grant.

The grants-history table at the bottom of the tenant admin page records all past grants for the tenant, including the number of months, the reason, the date applied, and the admin who applied it.

Card-on-File Requirement

A grant will be rejected if the tenant does not have a payment method on file in Stripe. This is not a platform policy choice; it is a technical constraint. Stripe's trial-extension mechanism operates on an existing active subscription with an attached payment method. Without a payment method, there is no subscription to extend, and the API call fails.

If a grant is rejected for this reason, ask the tenant to add a credit card via Workspace Settings → Billing before retrying.

Anchor Pricing Rule

The grant does not alter the tenant's listed plan price. During the grant period:

  • Invoices are EUR 0.00 with a "Free trial" line item description
  • The listed price (EUR 15 / 69 / 199 depending on plan) remains unchanged in Stripe
  • At the end of the grant period, Stripe automatically resumes charging the listed price with no action required from the tenant or from admin

There is no prorated credit; the grant simply defers the next charge by the number of months granted.

Conference-Account Safety

Grants issued against a conference Stripe account are rejected at runtime. The platform contains a safety assertion that detects conference billing entities and blocks the API call. This prevents a grant from being accidentally applied to the wrong billing context (the conference organizer's account rather than an individual attendee's account). If a grant for a conference attendee is rejected with this error, verify that the target tenant is billed under their own individual Stripe account rather than a shared conference account.

Customer Experience

From the tenant's perspective:

  • The dashboard shows the grant period, including the end date
  • Stripe sends EUR 0.00 invoices with a "Free trial" description for each month of the grant
  • No action is required from the tenant during the grant period
  • When the grant period ends, Stripe charges the listed plan price automatically using the payment method on file

Tenants do not receive a separate notification that a grant has been applied unless the admin communicates it directly.

Voucher Codes

Voucher codes provide a self-service alternative to individual admin grants. A voucher is a reusable code that any tenant with a paid Stripe subscription can redeem to extend their trial period. Vouchers are useful for conferences, marketing campaigns, referral programs, and any scenario where you want to distribute free months without manually granting them one at a time.

Creating a Voucher (Admin)

Vouchers are created via the money-manager admin API. You need a service API key to call this endpoint.

curl -X POST https://money.svc.prod.osaas.io/admin/vouchers \
  -H "x-api-key: $OSC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "WELCOME3",
    "months": 3,
    "max_redemptions": 100,
    "expires_at": "2026-12-31T23:59:59Z",
    "first_time_only": true
  }'

Fields:

Field Required Description
code Yes Voucher code (uppercased automatically). Use short memorable strings.
months Yes Free months granted per redemption (1–12).
max_redemptions Yes Total number of times the code can be redeemed.
expires_at No ISO 8601 expiry date. After this date the code returns 410 voucher_expired.
first_time_only No If true, each tenant can only redeem this code once.
metadata No Arbitrary JSON for channel attribution tracking.

Redeeming a Voucher (Customer)

Customers redeem vouchers via their PAT-authenticated session. The redemption call is typically triggered by a UI action or by sharing the API call in campaign materials.

curl -X POST https://money.svc.prod.osaas.io/vouchers/redeem \
  -H "x-pat-jwt: Bearer $OSC_PAT" \
  -H "Content-Type: application/json" \
  -d '{ "code": "WELCOME3" }'

On success the response includes trialEnd (new trial end timestamp), subscriptionId, and grantId.

Redemption Rules

  • Card on file required: the tenant must have an active Stripe subscription with a payment method attached.
  • Invoice-billed tenants excluded: tenants on invoice billing cannot redeem vouchers.
  • Rate limit: each tenant can redeem at most one voucher per 30-day rolling window.
  • first_time_only check: if the voucher was created with first_time_only: true, a tenant who has already redeemed it receives 409 already_redeemed_by_tenant.
  • Max redemptions: atomic increment ensures the cap is respected under concurrent requests.

Error Responses

HTTP reason Meaning
404 voucher_not_found Code does not exist
409 max_redemptions_reached Voucher is fully redeemed
409 already_redeemed_by_tenant Tenant already used this first-time-only code
410 voucher_expired Code is past its expiry date
429 rate_limited Tenant redeemed a voucher within the last 30 days
400 no_subscription Tenant has no active Stripe subscription
400 invoice_billed_tenant Tenant is on invoice billing

Comp MRR Accounting

Comp MRR (revenue from tenants on admin-granted free months) is a chart-build-time computation used in the business metrics dashboard. It is not persisted to the stripe-weekly JSON snapshot. The calculation feeds into a gross MRR + comp adjustments + net MRR breakdown per CEO directive 2026-05-03.

Formula pending — see parent epic Eyevinn/osaas-app#3886 for the exact computation rule.