Enterprise contracts
Platform-admin surface for provisioning, amending, renewing and terminating bespoke Enterprise contracts — negotiated seats, storage, price and term.
Enterprise Contracts is where a signed agreement becomes a working subscription. A prospect who came through Sales inquiries and agreed terms — "250 seats at a negotiated per-seat price, 40 GB per seat, a one-year term" — is set up here. The page is admin-only; the API behind it is gated to the platform admin role.
Why this is not App configuration#
App configuration edits the catalog: the plans every customer sees. Its whole contract is the opposite of what a bespoke deal needs.
| App configuration | Enterprise contracts | |
|---|---|---|
| Audience | Every customer | Exactly one organization |
| Structure | Code-owned and read-only for catalog plans | Overridden per contract — that is the point |
| Pricing | One price list per currency | One negotiated number |
| Lifecycle | Permanent | A term, with an end date |
| Visibility | The public pricing page | Never listed |
Bending the catalog editor into a contract editor would mean removing the guard that stops an admin accidentally changing what every customer is sold. They are two jobs and two screens.
What a contract is, underneath#
Every contract runs on the single ENTERPRISE pack, and expresses its negotiated terms as overrides on that customer's own subscription. There is no pack per customer. That matters in practice: quotas resolve through exactly the same code as every other plan, so a seat count or a storage figure set here behaves identically to one that came from the catalog.
Provisioning also creates the customer's organization if they do not already have one. This is not a detail — seat billing, seat caps and pooled storage all resolve through the organization, and a contract without one bills a single seat while appearing to work.
Provisioning a contract#
Provision contract opens the form. It needs three things.
The customer. Type the owner's email address; the account is looked up and shown back to you before you can submit. The person must already have a PulsVault account. Give the organization its legal name as it appears on the contract — left blank, the name is derived from the email domain, which is what the customer then sees on every screen.
The negotiated terms.
| Term | Notes |
|---|---|
| Seat floor | What the customer pays for whether or not they fill it |
| Seat cap | Blank means uncapped. Storage is entitled per seat, so an uncapped contract has no ceiling on its storage cost — you will be warned |
| Storage per seat | Required. It cannot be left empty: on a contract, empty would mean unlimited |
| Vault cap | Optional |
| Price per seat, Currency, Billing period | The negotiated number, in a currency the catalog prices |
| Term start / Term end | Both required — an agreement without a term is not a contract |
| Notice period | Days of notice before the term ends. This is what drives the renewal warning on the list, so each contract is judged by its own agreement rather than one platform-wide number |
| Contract reference | The signed document's reference |
| Agreed audit retention | Recorded on the contract, not applied — see below |
The approval. Every change names who authorised it, free text, because the person who signs off a commitment often holds no PulsVault account. Add the approval reference (a signed-order id, a ticket) and a note saying why. This is written to the contract's history and to the billing audit trail.
What gets refused#
The form does not enforce commercial rules — the server does, and it explains itself. You will get a message naming the problem when:
- the per-seat price is below the internal floor for that seat count (the message names the floor);
- the seat floor is below the Enterprise plan's own minimum;
- the seat cap is below the seat floor;
- the term ends before it starts;
- per-seat storage is missing;
- the currency has no catalog price to price the contract against. Price that currency in App configuration first. A currency with no reference price has no floor to check, and a contract sold with no floor is one nobody can notice was underpriced.
Terms that are unusual but legitimate — quotas below the Business plan's, an uncapped seat count — are warned about, not refused, and the warning stays visible on the contract. Trading one term against another is a decision sales is entitled to make.
The term history#
A contract is never edited in place. Every change appends an entry to its term history, and each entry records the complete terms as they stood, who approved it and when. Opening a contract shows that history newest-first, with each entry naming the terms it changed.
| Action | What it does |
|---|---|
| Amend | A mid-term change — seat expansion is the common one. The term start cannot move |
| Renew | A new term. This is the only change that moves the term start, and it revives a contract whose term has already ended |
| Terminate | Ends the contract with the wind-down the customer negotiated |
Amend and renew both send the complete terms, pre-filled from what is currently in force. That is deliberate: if a change sent only the fields you touched, "remove the seat cap" and "I did not mention the seat cap" would be the same request.
Billing: activation, then the same seats as every plan#
A contract is billed through Stripe at its negotiated per-seat price — the same rails as Team and Business. Provisioning records the terms but charges nothing and admits nobody: the customer's billing admin pays the first period — the committed seats, or the current headcount if larger — by opening Billing → Overview and selecting Activate contract. Until then the contract's detail shows Awaiting activation and the organization cannot invite anyone.
Once active:
- Seats are bought and removed by the customer exactly as on Team and Business, at the contract's price and up to its seat cap. An amendment that raises the seat floor charges the added seats now, prorated — and if that payment is declined, the amendment is refused and nothing is recorded.
- A price change in an amendment or renewal is charged prorated from the day it is recorded, so record a change on its effective date — a future-dated change to an active contract is refused.
- Term end: billing stops on the term end whether or not the contract auto-renews, because that is when access stops too. Record the renewal before the term ends and billing continues on the new term; a renewal recorded after billing stopped asks the customer to activate again.
- Terminate stops billing the same day. The negotiated wind-down is access, not billing.
- Paid twice by mistake: if the customer completes two activation checkouts, the second Stripe subscription is cancelled at once and flagged in the audit trail with the invoice to refund.
Collection is card or SEPA Direct Debit through the hosted checkout. A customer who can only pay by bank transfer is not billed here; record their seats through Amend instead.
Finding a contract#
Search by the three things you are likely to know: the contract reference, the owner's email, or the organization's name. A contract with no organization yet is still found — the list is an inventory, so nothing is hidden from it.
Renewals#
The list is ordered by when each term ends, and a banner counts what needs attention on the page: contracts inside their own notice period, and contracts whose term has already passed. Use the filter to narrow to a window — 30 days, 90 days, six months, a year. Ended contracts stay in the list, because a lapsed contract is what a renewal conversation starts from.
You are also told when nobody is looking at this page. Every morning, each contract that has reached its own negotiated notice period raises a notification to every platform admin, and again at seven days and one day. A contract negotiated with ninety days' notice warns at ninety; one with thirty warns at thirty.
Nothing renews a contract automatically. The auto-renewal flag records what the paper says; extending the term is always an admin recording a renewal. That is why the reminder goes to admins — and why the customer is told only when the contract is not set to renew, because that is the case where their access actually ends and the message is worth sending.
A contract whose term ends without a renewal being recorded lapses like any other subscription: the customer moves into the read-only window. The notice period exists so that does not come as a surprise.
Terminating#
Termination asks for a reason and a wind-down — the days of read-only access the customer agreed to, so they can export their data. It defaults to the standard window. Setting it to 0 cuts access off immediately, which is what a termination for breach needs.
A terminated contract cannot be amended or renewed. Selling the customer another term means provisioning a new contract.
Audit retention: recorded, not enforced#
The agreed audit retention field records a number and nothing else, and the screen says so. The Enterprise plan already retains audit records indefinitely, so a negotiated window can only ever narrow what is kept — and narrowing audit retention is a setting the customer's own administrator controls, on their retention screen, where they can change it again. Recording the figure keeps the promise on the contract; applying it from here would be setting a customer's preference for them, and it would not stay set.
Audit trail#
Provisioning, amending, renewing and terminating are all recorded on the customer's billing audit trail with compliance retention. Changing what a customer is charged is a financial event, and the record names the approver.