Subscription Tracking
This guide describes how the SpendOne Platform, the AI-based platform for indirect corporate spend, gives finance and procurement teams full visibility over recurring SaaS and service spend. It covers AI-assisted detection from invoices and card transactions, owner assignment, contract metadata, renewal alerts, limit-increase flows and cancellation.
For admins. Subscriptions live under Spend → Subscriptions. The list view exposes filters for "my subscriptions", expiring cards and over-utilized limits (>=95%). Each subscription detail page surfaces contract terms (start, renewal, notice period), the linked corporate card, the responsible owner, attached documents (contracts, order forms, DPAs) and the rolling invoice history. Notification rules for renewal reminders and limit warnings are configured under Administration → Notifications; reminder cadence and assignees are governed by tenant-level settings. Cancellation is initiated from the subscription detail page and routes through the standard approval workflow.
For integrators. Subscriptions are exposed under /subscriptions/*. New subscriptions are typically created implicitly: when an invoice is processed by the document-extraction pipeline and flagged is_subscription = true, or when a corporate-card transaction is matched to a recurring merchant. Integrators can read the catalog, attach documents, update terms, request limit increases and cancel via the REST API. See the OpenAPI reference for response schemas.
AI auto-detection
Document extraction runs every ingested invoice through an LLM with explicit subscription-detection rules: is_subscription is set true only when the document mentions recurring billing, subscription terms, license periods, renewal, or equivalent German or English indicators ("monatlich", "jährlich", "Abo", "Laufzeit", "Vertragslaufzeit", "per month", "per year"). Detected subscriptions are persisted with extracted terms (period, renewal date, notice window) and linked back to the source invoice. A payment_plan = "recurring" flag is what drives the renewal alerts below.
Card-based subscriptions are detected when the transaction-events stream produces repeating charges from the same merchant against the same virtual card, with the card already tagged as a subscription card at issuance time.
Step 1: List and inspect
GET /subscriptions: paginated list with filters:my_subscriptions,expiring_cards,limit_warnings,search.GET /subscriptions/statistics: tenant-wide aggregates (active count, monthly/annual run-rate, expiring soon).GET /subscriptions/{code}: full detail including terms, owner, linked card and invoice rollup.
Step 2: Owner and contract metadata
The subscription owner is set when the subscription is created (from the requester on the source PO/invoice) and can be updated via the terms endpoint along with renewal date, notice period and contract value. Contract documents are stored as first-class attachments.
PUT /subscriptions/{code}/terms: update contract terms (period, renewal, notice, value).POST /subscriptions/{code}/documents: upload a contract or addendum (multipart).GET /subscriptions/{code}/documents: list attached documents.GET /subscriptions/{code}/documents/{document_id}: download a document.DELETE /subscriptions/{code}/documents/{document_id}: remove a document.
Step 3: Invoices and spend visibility
Every invoice booked against a subscription card or matched to a subscription contract appears in the per-subscription invoice list. Out-of-band invoices (e.g. PDF received by email) can be attached manually.
GET /subscriptions/{code}/invoices: invoice history for the subscription.POST /subscriptions/{code}/invoices: attach an invoice (multipart upload).
Step 4: Renewal alerts and reminders
Renewal alerts are produced by the reminders subsystem and dispatched as notifications. Triggers include:
- Approaching renewal date inside the notice window.
- Card expiry on the linked corporate card (
expiring_cardsfilter). - Budget utilization >= 95% on the linked card (
limit_warningsfilter).
Notifications are delivered through the configured channels (in-app, email) to the subscription owner and any additional watchers set on the subscription.
Step 5: Limit increases
When utilization is high but the subscription should continue, the owner can request an increase to the linked card's spend limit. The request enters the standard approval workflow.
POST /subscriptions/{code}/limit-increase-requests: submit a new request (amount, justification).GET /subscriptions/{code}/limit-increase-requests: list requests.GET /subscriptions/{code}/limit-increase-requests/{request_code}: single request status.GET /subscriptions/{code}/approval-tasks: pending approval tasks for the subscription, useful when polling for resolution.
Step 6: Card replacement
If the linked card expires or is compromised, the subscription stays intact and is rebound to a freshly issued card so recurring charges continue uninterrupted.
POST /subscriptions/{code}/replace-card: issues a replacement and rewires the subscription.
Step 7: Cancellation
Canceling and hiding are two different operations, and it is easy to call the wrong one.
POST /subscriptions/{code}/cancel: this is cancellation. It marks the subscription inactive and deactivates the linked credit card. Takes no body.DELETE /subscriptions/{code}: a soft delete that only removes the row from normal listings. It does not change the active state and does not touch the card.
Neither records a reason or an effective date. The platform does not contact the vendor either way; the owner must still send any required termination notice.
Operational notes
- Detected subscriptions inherit the cost center and owner from the source invoice or PO; correct them via
PUT /subscriptions/{code}/terms, and cost-center splits viaPUT /subscriptions/{code}/cost-center-splitsbefore the first renewal cycle. - The
limit_warningsandexpiring_cardsfilters mirror the alert triggers: use them to build dashboards that match what owners receive in notifications. DELETEis a visibility change, not a state change. UsePOST .../cancelwhen you mean to stop the subscription.