Skip to content

Packages: Create and Manage Plans ​

Overview ​

A package is a plan. It answers three questions at once for every company assigned to it:

  1. What does it cost? — monthly and yearly price.
  2. How much may they use? — API requests, tokens, users, documents, storage, API keys.
  3. What may they do? — the capability flags (features) that switch product areas on and off, such as PII sanitization, SSO, Cost Intelligence or structured document parsing.

A subscription (CompanyPackage) is the link between one company and one package for a billing period. Packages are the catalogue; subscriptions are who bought what.

ConceptWhat it holdsWhere you manage it
PackagePrice, limits, capabilitiesAdmin → Packages → Packages tab
SubscriptionCompany, package, billing period, amount, period usage countersAdmin → Packages → Subscriptions tab

Access and permissions ​

ActionRequired role
View, create, edit, delete packagesSUPER_ADMIN
Assign or change a company's subscriptionSUPER_ADMIN
View the resulting billing figuresSUPER_ADMIN, ACCOUNTANT

Every create, update and delete is written to the audit log with the acting user, the package and the changed values.

Creating a package ​

UI path: /admin/packages → Packages tab → New package

1. Identity ​

FieldNotes
NameMust be unique across the platform. Attempting to reuse a name returns 409. This is the label customers see, so name it commercially ("Team", "Enterprise"), not internally ("tier-3-v2").
DescriptionOne line explaining who the plan is for. Shown on the plan-selection screens.
Account typeINDIVIDUAL (single user), TEAM (2-10 users), ENTERPRISE (10+). Drives default framing and some product copy.

2. Price ​

FieldNotes
Price per monthThe list price. Leave at 0 for an internal, trial or partner package.
Price per yearThe annual price, if you sell one. Set it to the discounted annual total, not twelve times the monthly figure.

Prices are held in the platform's billing currency (USD). A company's lead currency (baseCurrency, USD or EUR) affects how figures are displayed to that company and in accounting reports; it does not convert what is charged. See Accounting.

3. Limits ​

FieldEffect when exceeded
API requests per monthGateway calls are refused once the period allowance is used.
API tokens per monthToken allowance for the period. Leave empty for no token cap.
Max usersBlocks further invitations.
Max documents / Max document sizeBlocks upload.
Response storage (GB) / Max response countBounds retained gateway responses.
Max Gateway API keysCaps active keys per company. Defaults to 10.

Leave a numeric limit empty to mean unlimited. Setting it to 0 means none — those are very different, and 0 is the one that will generate support tickets.

4. Capabilities (features) ​

Capabilities are boolean and numeric flags stored as JSON on the package. The important ones:

KeyUnlocks
allowPiiSanitizationShield PII detection and tokenization
allowVeritas (+ maxVeritas*)Veritas document hardening, with its own per-month and per-job caps
allowTextHygieneThe Shield "Clean Text" tool
allowGeoFencingConfiguring geo-fencing rules on projects and prompts
allowSsoEnterprise SSO connectors, domain verification, SCIM
allowCostIntelligenceThe Sherlock cost module
allowOpsAnalytics, allowAuditQueries, allowDataResearch, allowQualityAnalytics, allowSecurityAnalytics, allowRoutingAnalyticsThe individual analytics add-ons
allowArchitectProject Architect
allowMcpTools, allowWebhooks, allowExport, allowTeamCollaboration, allowGuruChatThe corresponding product areas
allowStructuredDocumentParsing (+ maxDocumentParsePages)Layout-aware PDF parsing rather than plain text extraction
promptProtectionProtective prompt wrapping at the gateway
displayFeaturesA list of strings shown on pricing screens — marketing copy, not a gate

Two rules worth internalising before you edit a feature flag:

  • Most gates fail closed. A capability that is absent is denied, not granted. This is deliberate: a package created without a flag must lose capability, never gain it.
  • Selling a tool is not the same as selling whether a policy is honoured. allowGeoFencing and allowTextHygiene gate the configuration tools. Rules a company has already configured — a geo-fence, a Unicode-hygiene block — keep being enforced at the gateway even on a plan that no longer includes the tool. A compliance control must not silently stop applying because of a billing state.

5. Flags ​

FlagMeaning
ActiveInactive packages cannot be newly assigned; existing subscriptions keep running.
DefaultThe package new signups land on. Exactly one package should carry this.
BYOK requiredCompanies on this package must supply their own provider API keys.

6. Stripe linkage (optional) ​

Stripe product ID, Stripe price (monthly) and Stripe price (yearly) connect the package to Stripe so self-serve checkout and the customer portal work. Leave them empty for packages you invoice manually — the package still functions, it simply has no self-serve path.

Editing a package ​

UI path: /admin/packages → Packages tab → the package → Edit

Changes apply to every company already on the package, immediately, including any mid-period company. Before saving:

  • Lowering a limit can put existing companies instantly over quota. Check who is on the package first, using the Subscriptions tab.
  • Removing a capability takes the feature away at the next request. Where a downgrade would break a running configuration, the platform shows a downgrade notice on the customer's billing page — but you should still tell them.
  • Raising a price does not re-invoice anyone retroactively. It applies from the next billing period.

Deleting a package ​

UI path: /admin/packages → Packages tab → the package → Delete

Deletion is protective:

  • If no company has ever subscribed, the package is deleted outright.
  • If any subscription exists, the package is deactivated instead of deleted, and the response says how many subscriptions kept it alive. Historical subscriptions and the invoices derived from them stay intact — which is exactly what you want, because deleting a package under a past invoice would orphan the line item that explains the charge.

Assigning a package to a company ​

UI path: /admin/packages → Subscriptions tab → Assign subscription

Choose the company, the package, the billing period (MONTHLY or YEARLY) and the amount. The amount is deliberately editable and separate from the package's list price — that is how you record a negotiated price without creating a bespoke package for every customer.

The subscription then tracks, for the current period: usedApiRequests, usedApiTokens, usedInputTokens, usedOutputTokens, nextBillingDate, and — for Stripe-backed subscriptions — stripeSubscriptionStatus, currentPeriodStart/End and cancelAtPeriodEnd.

Changing a company's package ​

Assign the new package on the Subscriptions tab. Then check three things:

  1. Usage counters. They belong to the subscription period, not to the company. Confirm the figures on /accountant look right for the period you are about to invoice.
  2. Capability loss. Compare the two packages' features. Anything the new package does not grant stops working.
  3. Provider bundles. If the packages have different provider bundles, re-run the bundle sync for the package (/admin/package-provider-bundles) so routing sees the right provider set.
SettingWhereWhat it does
Package limits/admin/package-limitsFine-grained limit overrides
Provider bundles/admin/package-provider-bundlesWhich providers a package may route to
Promo codes/admin/promo-codesDiscounts and bonus allowances, optionally targeted at one package
Payment status/admin/payment-managementGrace periods and suspension, independent of the package
Bulk move companies to the free package/accountant/customers → Import ActionsA platform accountant/SUPER_ADMIN can bulk-apply DOWNGRADE_TO_FREE from a CSV of unpaid companies — see Accounting: bulk unpaid-action import

API reference ​

bash
# List packages
curl -s https://app.veriprompt.tech/api/admin/packages \
  -H "Cookie: <admin session>"
bash
# Create a package
curl -s -X POST https://app.veriprompt.tech/api/admin/packages \
  -H "Content-Type: application/json" \
  -H "Cookie: <admin session>" \
  -d '{
        "name": "Team",
        "description": "For teams of 2-10 building on the gateway",
        "accountType": "TEAM",
        "pricePerMonth": 149,
        "pricePerYear": 1490,
        "apiRequestsPerMonth": 250000,
        "apiTokensPerMonth": 20000000,
        "maxUsers": 10,
        "maxApiKeys": 25,
        "isActive": true,
        "features": {
          "allowPiiSanitization": true,
          "allowMcpTools": true,
          "allowExport": true,
          "maxProjects": 25
        }
      }'

PUT /api/admin/packages updates (body carries id); DELETE /api/admin/packages?id=<id> deletes or deactivates as described above.

Troubleshooting ​

SymptomCauseFix
409 A package with this name already existsNames are unique platform-wide, including inactive packagesRename, or reactivate the existing package
A customer reports a feature "disappeared" after a plan changeThe new package's features omits the flag; absent means deniedAdd the flag to the package, or move the company back
Delete returned "Package deactivated" instead of deletingSubscriptions reference itExpected. Reassign those companies first if you truly need the row gone
A limit change did not take effectGateway context is cached per companyPackage deletion invalidates gateway contexts automatically; for edits, allow the cache to turn over or reassign the subscription
Feature is on in the package but still deniedThe gate may read the company's merged features, and a seeding path can set features on create but not on updateRe-save the package; the npm run test:seed-parity guard exists specifically for this drift

Learn more ​