Use when building billing systems on Solvimon, managing subscriptions, configuring usage-based or per-seat pricing, metering usage events, generating invoices, issuing credit notes, or managing...
Solvimon is an API-first billing platform for usage-based, per-seat, recurring, and hybrid pricing. It covers the full billing workflow: usage metering, product catalog, pricing plans, customers, subscriptions, invoicing, and credit notes. Agents use Solvimon to configure pricing, manage customers and subscriptions, ingest usage events, and handle invoices programmatically.
Every action available in Desk (the web UI) is also available via the REST API. Nothing is UI-only.
Key endpoints and interfaces:
https://test.api.solvimon.com/v1https://[dedicated-url].solvimon.com/v1 (each account gets a dedicated subdomain)X-API-KEY header (API keys issued per environment)Four API domains: Configuration (catalog, plans, customers, subscriptions, meters), Identity (users, API keys, roles), Transaction (invoices, credit notes, payments), Event (usage ingestion).
Reach for this skill when:
curl https://test.api.solvimon.com/v1/customers \
-H "X-API-KEY: <apiKey>" \
-H "Content-Type: application/json"
persist: true for rolling calculations that carry state forward across periods).| Task | Endpoint | Method |
|---|---|---|
| Create customer | /v1/customers |
POST |
| Activate customer | /v1/customers/{idOrReference}/activate |
POST |
| Create meter | /v1/meters |
POST |
| Create product | /v1/products |
POST |
| Create product item | /v1/product-items |
POST |
| Create pricing plan | /v1/pricing-plans |
POST |
| Create plan version | /v1/pricing-plan-versions |
POST |
| Create subscription (+ first schedule) | /v1/pricing-plan-subscriptions/init |
POST |
| Cancel subscription | /v1/pricing-plan-subscriptions/{id}/cancel |
POST |
| Ingest usage event | /v1/ingest/meter-data |
POST |
| List invoices | /v1/invoices |
GET |
| Create credit note | /v1/invoices/{id}/credit |
POST |
See the "API endpoint reference" section below for the full endpoint reference, pagination, and conventions.
| Charge type | When to use |
|---|---|
| Recurring | Fixed periodic fee (flat or per-unit), the standard subscription charge |
| Usage-based | Charge on actual consumption (API calls, GB, transactions) via a meter |
| Per-seat | Seat or account-based licensing; seat count adjustable per subscription |
| One-off | Standalone one-time purchase (setup fee, license), can be billed in advance |
| Top-up | Prepaid volume where unused units carry forward to the next cycle |
| Add-ons | Optional extra items added to an existing subscription |
| On-demand charges | One-off items charged on a separate invoice on request, with optional preview |
| Method | Behavior |
|---|---|
| Flat | Same unit price for all volume |
| Progressive tiered | Each tier priced at its own rate (graduated) |
| Top-tiered (volume) | Total volume determines one rate applied to all units |
| Stair-step | Total volume maps to a fixed price step |
| Percentage-based | Meter value is a monetary amount; charge a percentage, with optional min (floor) and max (cap) |
NOW, NEXT_BILLING_PERIOD, AFTER_INITIAL_TERM, DATE (with cancel_at), and UNDO to revert a scheduled cancellation.POST /v1/meter-values, POST /v1/meters, POST /v1/meter-value-calculations (e.g. calculation_type: "SUM"). Activate the meter.POST /v1/product-categories, POST /v1/products, POST /v1/product-items (usage items use model_type: "USAGE_BASED" and link a meter_value_calculation_id). Activate product and item.POST /v1/pricing-plans, then POST /v1/pricing-plan-versions, then POST /v1/pricings for each item. Activate the version.POST /v1/customers (starts in DRAFT), then POST /v1/customers/{idOrReference}/activate.POST /v1/pricing-plan-subscriptions/init creates the subscription and its first schedule in one call. Key fields: billing_time, billing_entity_reference, billing_currency. Activate it.POST /v1/ingest/meter-data with one event per billable action. See the "Event ingestion" section below.INVOICE.STATUS_TO_FINAL webhook event fires on finalization. Auto-charge runs if a payment method is attached.reference is the idempotency key: deduplication is asynchronous. Duplicates are accepted with a 2xx (201) but flagged DUPLICATE, and only the first is processed. Do not rely on the HTTP status to detect duplicates.POST /v1/reprocess); no need to re-send events.POST /v1/invoices/{id}/credit, or /credit_and_copy to credit and reissue an editable copy).on_hold and paid, separate from status.{resourceIdOrReference}, so you can use your own reference values instead of Solvimon IDs.Before treating a billing setup as done:
billing_currency and billing entityGET /v1/events shows them, and none are flagged DUPLICATE unexpectedlyreference values are unique per billable actionINVOICE.STATUS_TO_FINAL or payment notificationshttps://test.api.solvimon.com/v1 with a sandbox API keyAll endpoints are relative to the base URL (https://test.api.solvimon.com/v1 in sandbox). Authenticate every request with the X-API-KEY header.
{idOrReference} accept either the Solvimon resource ID (e.g. cust_zwDeN40tsF98JTBsea1j) or the custom reference you set on the resource.POST .../{idOrReference}/activate, /deprecate, and /archive action endpoints.POST .../search with a filter body, in addition to GET list endpoints.{
"data": [ ... ],
"limit": 10,
"page": 1,
"total_number_of_pages": 4,
"links": { "first": "...", "previous": null, "current": "...", "next": "..." }
}
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/customers |
Create a customer |
| GET | /v1/customers |
List customers |
| PUT | /v1/customers |
Upsert a customer by reference |
| POST | /v1/customers/search |
Search customers |
| GET / PATCH / DELETE | /v1/customers/{idOrReference} |
Get, update, or delete a customer |
| POST | /v1/customers/{idOrReference}/activate |
Activate a draft customer |
| POST | /v1/customers/{idOrReference}/deprecate |
Deprecate a customer |
| POST | /v1/customers/{idOrReference}/archive |
Archive a customer |
| GET | /v1/customers/{idOrReference}/entitlements |
Get a customer's entitlements |
| POST | /v1/customers/{idOrReference}/wallets/balance |
Get wallet balances |
| POST | /v1/customers/validate-tax-id |
Validate a tax ID |
Products, product items, and product categories all follow the same pattern (shown for products):
| Method | Path | Purpose |
|---|---|---|
| POST / GET / PUT | /v1/products |
Create, list, upsert |
| POST | /v1/products/search |
Search |
| GET / PATCH / DELETE | /v1/products/{idOrReference} |
Get, update, delete |
| POST | /v1/products/{idOrReference}/activate etc. |
Lifecycle actions |
Replace products with product-items or product-categories for the other two. Usage-based product items set model_type: "USAGE_BASED" and link a meter_value_calculation_id.
| Method | Path | Purpose |
|---|---|---|
| POST / GET / PUT | /v1/pricing-plans |
Create, list, upsert plans |
| POST | /v1/pricing-plans/search |
Search plans |
| GET / PATCH / DELETE | /v1/pricing-plans/{idOrReference} |
Get, update, delete a plan |
| POST / GET / PUT / PATCH / DELETE | /v1/pricing-plan-versions[/{id}] |
Manage plan versions |
| POST | /v1/pricings |
Create pricing entries for a version's items |
| POST / GET / ... | /v1/pricing-plan-schedules |
Manage subscription schedules |
| POST | /v1/pricing-plan-schedules/{id}/copy |
Copy a schedule |
| POST | /v1/pricing-plan-schedules/{id}/migrate |
Migrate a schedule to another plan version |
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/pricing-plan-subscriptions/init |
Create subscription + first schedule in one call (recommended) |
| POST / GET / PUT | /v1/pricing-plan-subscriptions |
Create, list, upsert |
| POST | /v1/pricing-plan-subscriptions/search |
Search subscriptions |
| GET / PATCH / DELETE | /v1/pricing-plan-subscriptions/{id} |
Get, update, delete |
| POST | /v1/pricing-plan-subscriptions/{id}/cancel |
Cancel (types: NOW, NEXT_BILLING_PERIOD, AFTER_INITIAL_TERM, DATE, UNDO) |
| POST | /v1/pricing-plan-subscriptions/{id}/void |
Void a wrongly created subscription |
| POST | /v1/pricing-plan-subscriptions/{id}/copy |
Copy a subscription |
| POST | /v1/pricing-plan-subscriptions/{id}/update-payment-method |
Update payment method |
| POST | /v1/pricing-plan-subscriptions/{id}/archive |
Archive |
| Method | Path | Purpose |
|---|---|---|
| POST / GET | /v1/meters |
Create, list meters |
| GET / PATCH / DELETE | /v1/meters/{idOrReference} |
Get, update, delete |
| POST / GET / ... | /v1/meter-properties |
Manage meter properties (event dimensions) |
| POST / GET / ... | /v1/meter-values |
Manage meter values (the measured quantity) |
| POST / GET / ... | /v1/meter-value-calculations |
Manage calculations (SUM, MAX, MIN, UNIQUE, AVERAGE, rolling variants) |
| GET | /v1/meters/{idOrReference}/meter-data-file |
Get the ingestion header file for CSV uploads |
| Method | Path | Purpose |
|---|---|---|
| POST / GET / PUT | /v1/features |
Create, list, upsert features |
| GET / PATCH / DELETE | /v1/features/{id} |
Get, update, delete |
| GET | /v1/customers/{idOrReference}/entitlements |
Customer entitlements |
| GET | /v1/platforms/{id}/entitlements |
Platform entitlements |
The Configuration API also covers coupons, wallets and wallet types, credit types, billing entities, and webhook endpoint management, following the same CRUD + search + lifecycle patterns.
There is no separate credit-note resource: a credit note is an invoice with type: "CREDIT" (or "ONE_OFF_CREDIT"), created by crediting an existing invoice.
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/invoices |
Create a one-off invoice or one-off credit note |
| GET | /v1/invoices |
List invoices |
| POST | /v1/invoices/search |
Search invoices |
| POST | /v1/invoices/preview |
Preview an invoice before creating it |
| GET / PATCH | /v1/invoices/{id} |
Get or update an invoice |
| POST | /v1/invoices/{id}/credit |
Create a credit note for an invoice (empty body = full credit; periods for partial; credit_details_source: CURRENT or ORIGINAL) |
| POST | /v1/invoices/{id}/credit_and_copy |
Credit the invoice and create an editable copy for reissue |
| POST | /v1/invoices/{id}/refund |
Refund a credit note |
| POST | /v1/invoices/{id}/add-line |
Add a line to an invoice |
| POST / PUT / DELETE | /v1/invoices/{id}/lines[/{lineId}] |
Manage invoice lines |
| POST | /v1/invoices/{id}/pay |
Trigger payment |
| POST | /v1/invoices/{id}/send_by_email |
Email the invoice |
| POST | /v1/invoices/{id}/export_to_erp |
Export to a connected ERP |
| POST | /v1/invoices/{id}/refresh |
Refresh an open invoice |
| GET | /v1/invoices/{id}/pdf |
Download PDF |
| GET | /v1/invoices/{id}/ubl21 |
Download UBL 2.1 e-invoice |
| GET | /v1/invoices/{id}/payments |
List payments on the invoice |
| POST | /v1/invoices/charge-on-demand-pricing-items |
Charge on-demand pricing items |
The Transaction API also covers payments, payment requests and schedules, wallet grants, report generation, customer portal URLs, and bulk actions.
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/ingest/meter-data |
Ingest a single usage event |
| POST | /v1/ingest/meter-datas |
Ingest a batch of usage events |
| POST | /v1/events/calculate |
Calculate the cost of an event without ingesting |
| GET | /v1/events |
List ingested events |
| GET | /v1/events/{id} |
Get an event |
| GET | /v1/events/{id}/event_trace |
Trace how an event was processed |
| POST | /v1/events/delete |
Mark events deleted |
| POST | /v1/reprocess |
Reprocess stored raw events after fixing meter config |
POST /v1/events/ingest and /v1/events/ingest-list are aliases of the ingest/meter-data endpoints. See the "Event ingestion" section below for the request schema.
Manages users, teams, roles, API keys, OAuth clients, authentication providers, and audit records. Most integrations only need it for API key management (/v1/api-keys) and audit trails (/v1/audit-records).
Meters, products, product items, pricing plans, and plan versions share one lifecycle:
| Status | Meaning |
|---|---|
DRAFT |
Editable and deletable; cannot be assigned or used for billing |
ACTIVE |
Live and immutable; create a new version to change it |
DEPRECATED |
Cannot be assigned to new customers; keeps working for existing ones |
ARCHIVED |
Soft-deleted and hidden; recoverable |
Customers follow the same lifecycle plus a CLOSED status. Transitions are driven by the /activate, /deprecate, and /archive action endpoints.
| Status | Meaning |
|---|---|
DRAFT |
Created but not activated; does not bill |
ACTIVE |
Running contract; most terms locked, invoicing live |
CANCELLED |
Legitimately ended; issued invoices remain valid |
VOID |
Retracted as wrongly created; Draft and Open invoices voided with it |
ARCHIVED |
Terminal, hidden |
Notes:
DRAFT and must be explicitly activated.type values: NOW (optionally cancel_dunning_actions: true), NEXT_BILLING_PERIOD, AFTER_INITIAL_TERM, DATE (with cancel_at), UNDO (revert a scheduled cancellation that has not taken effect).type values: BILLING (normal), QUOTE, TEMPLATE.| Status | Meaning |
|---|---|
| Future | Billing period has not started yet; no charges accrued |
| Open | Billing period in progress; invoice updates as usage arrives |
| Draft | Period concluded (transition about 2 hours after period end); adjustable during the grace period (8 hours by default) |
| Final | Invoice number assigned; irreversible and unchangeable; corrections only via credit note |
| Empty | Period produced no chargeable items; like Final but without an invoice number |
| Void | Invalidated; only Open or Draft invoices can be voided; retained for audit |
| Archived | Terminal, hidden |
Notes:
on_hold and paid, not status values. Holding keeps an invoice in Draft; releasing the hold schedules finalization in 8 hours.type values: STANDARD, CREDIT, ONE_OFF, ONE_OFF_CREDIT. Credit notes carry a CR prefix in their invoice number and follow the normal invoice lifecycle starting in Draft.| Enum | Values |
|---|---|
Pricing item config type |
FLAT, TIERED (progressive), TOP_TIERED (volume), STAIR_STEP, FIXED, FLAT_TOP_UP, TIERED_TOP_UP, STAIR_STEP_TOP_UP, PASS_THROUGH, NONE. Percentage-based charging is not a type; it is configured via a percentage on the pricing item config. |
Meter calculation calculation_type |
SUM, MAX, MIN, UNIQUE, AVERAGE. Rolling calculations (state carried forward across periods, e.g. for delta-style events such as seat changes) are not a separate type; set persist: true on the calculation. |
Pricing plan type |
STANDARD, CUSTOM |
Feature type |
SWITCH, NUMBER, ENUM, AMOUNT, STRING |
Customer type |
ORGANIZATION, INDIVIDUAL |
IDs follow the pattern prefix_ plus roughly 20 base62 characters, e.g. cust_zwDeN40tsF98JTBsea1j.
| Prefix | Resource |
|---|---|
cust_ |
Customer |
prod_ |
Product |
proi_ |
Product item |
pric_ |
Pricing |
prii_ |
Pricing item |
pico_ |
Pricing item config |
ppve_ |
Pricing plan version |
ppsc_ |
Pricing plan schedule |
ppsu_ |
Pricing plan subscription |
metr_ |
Meter |
metp_ |
Meter property |
metv_ |
Meter value |
mvca_ |
Meter value calculation |
feat_ |
Feature |
invo_ |
Invoice |
bile_ |
Billing entity |
cont_ |
Contact |
quot_ |
Quote |
user_ |
User (Identity API) |
Most Configuration endpoints accept either the Solvimon ID or your own reference in the path, so you rarely need to store Solvimon IDs if you set references consistently.
Usage events are the raw input for usage-based billing. Send one event per billable action; Solvimon aggregates them per billing period using the meter's calculation. Never pre-aggregate on your side.
POST /v1/ingest/meter-data # single event
POST /v1/ingest/meter-datas # batch of events
(POST /v1/events/ingest and /v1/events/ingest-list are aliases.)
Only reference is required. Everything else identifies what was used, by whom, and how much:
| Field | Purpose |
|---|---|
reference |
Required. Your unique ID for this event; drives idempotency |
customer_reference / customer_id |
Which customer the usage belongs to |
meter_reference / meter_id |
Which meter the event feeds |
pricing_plan_subscription_reference / _id |
Optional explicit subscription targeting |
timestamp |
When the usage occurred (ISO 8601); determines the billing period |
meter_properties[] |
Dimensions/context used for filtering and grouping (e.g. region, model) |
meter_values[] |
The measured quantities (a number and/or monetary amount) |
curl -X POST https://test.api.solvimon.com/v1/ingest/meter-data \
-H "X-API-KEY: <apiKey>" \
-H "Content-Type: application/json" \
-d '{
"reference": "evt-2026-07-06-000123",
"customer_id": "cust_zwDeN40tsF98JTBsea1j",
"meter_id": "metr_owDe9k0tsIY5LkBAel1E",
"timestamp": "2026-07-06T15:22:37Z",
"meter_properties": [
{ "id": "metp_owDe9k0tsIY5LkBAel1E", "value": "DE" }
],
"meter_values": [
{
"id": "metv_owDe9k0tsIY5LkBAel1E",
"number": "1",
"amount": { "quantity": "1500.00", "currency": "EUR" }
}
]
}'
You can address everything by your own references instead of Solvimon IDs. With meter_validation=DYNAMIC as a query parameter, unknown meters can even be created on the fly:
curl -X POST "https://test.api.solvimon.com/v1/ingest/meter-data?meter_validation=DYNAMIC" \
-H "X-API-KEY: <apiKey>" \
-H "Content-Type: application/json" \
-d '{
"reference": "evt-2026-07-06-000124",
"customer_reference": "acme-corp",
"meter_reference": "api-calls",
"timestamp": "2026-07-06T15:24:02Z",
"meter_values": [ { "reference": "calls", "number": "1" } ]
}'
An event is matched by its customer (via customer_reference or customer_id) to that customer's subscription whose product item links the meter's value calculation. You normally do not need to pass the subscription explicitly; use the subscription fields only to disambiguate when a customer has multiple subscriptions on the same meter.
reference is the idempotency key. Make it unique per billable action.201 Created) but flagged DUPLICATE, and only the first event is processed. Do not rely on the HTTP status to detect duplicates.reference and updated payload semantics per the event ingestion docs, or mark it deleted via POST /v1/events/delete.X-REQUEST-ID response header from error responses for support escalation.POST /v1/reprocess instead of re-sending events.POST /v1/events/calculate to preview the cost of an event without ingesting it.GET /v1/events/{id}/event_trace when an event does not show up in usage.Key documentation pages: