Run your billing from your own code: a REST API with scoped keys and per-key rate limits over customers, subscriptions, products, prices, coupons, invoices and payment intents, and signed webhooks whenever billing state changes.
API keys
The Prosperanova REST API lets your own backend do what the dashboard does with your billing: keep customers in sync, put them on a subscription, publish the products, prices and coupons you sell, and read the invoices and payment intents the billing engine produced.
Open your project in the Prosperanova dashboard and create an API key under API keys. The secret is shown once, when the key is created, and never again — store it somewhere safe. A key belongs to a single project, so a key can never reach another project of yours.
Authenticate every request with HTTP Basic auth carrying only the key secret, base64-encoded, in the Authorization header.
# The Authorization header is HTTP Basic auth carrying only the key secret,
# with no username and no colon.
Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)Every endpoint lives under https://api.prosperanova.com. Requests made with a key are rate limited per key; going over the limit returns 429.
Quick start
List the customers of your project, create one, then read the invoices issued for that project.
# List the customers of the project the key belongs to
curl "https://api.prosperanova.com/api/customers?projectId=YOUR_PROJECT_ID" \
-H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)"
# Create a customer. The customer.created webhook fires on success.
curl -X POST https://api.prosperanova.com/api/customers \
-H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)" \
-H "Content-Type: application/json" \
-d '{
"projectId": "YOUR_PROJECT_ID",
"email": "ada@example.com",
"name": "Ada Lovelace"
}'
# Read the invoices the billing engine has issued for that project
curl "https://api.prosperanova.com/api/invoices?projectId=YOUR_PROJECT_ID&limit=20" \
-H "Authorization: Basic $(printf %s YOUR_API_KEY_SECRET | base64)"Browse the full API reference — every endpoint with its parameters, request body, responses and required scope.
Scopes
Each key carries a list of scopes, so an integration that only needs to read your invoices never gets the ability to charge anyone. New keys start read-only; widen them explicitly in the dashboard. A request whose key is missing the scope an endpoint requires is refused with 403.
No scope reaches the payment credentials behind a project. The Stripe keys Prosperanova uses to move money live in their own collections, are never part of a project or a customer document, and are never returned by the API.
Claude & ChatGPT
Add the Prosperanova remote MCP server to Claude, ChatGPT, or another Streamable HTTP MCP host. Every person connects to the same production endpoint and signs in through Prosperanova OAuth; the signed-in account determines which organization and projects the host can access.
Server URL: https://mcp.prosperanova.com/mcp
In your MCP host, add a custom connector with that URL, choose Connect, and complete the Prosperanova authorization screen. The connector requests prosperanova:read for billing data and prosperanova:write for the create-project tool. Read tools do not change billing state; the host can ask for approval before the write tool runs.
Prosperanova rechecks organization and project ownership on every API call. Interactive views never receive payment-method identifiers, Stripe identifiers, arbitrary metadata, organization identifiers, or captured device data. Customer names and email addresses can appear because they are part of the billing records your account is already allowed to read.
To disconnect, remove Prosperanova from your MCP host and revoke the authorization from your Prosperanova account. Removing the connector stops the host from making new calls; revocation invalidates its tokens.
Webhooks
Add a webhook subscription to your project and Prosperanova POSTs the events you picked to your server as they happen — including the ones raised by the hourly billing run, not just the ones your own calls cause.
POST https://your-server.com/prosperanova-webhook
X-Prosperanova-Event: subscription.created
X-Prosperanova-Signature: t=1719000000,v1=<hmac-sha256 hex>
Content-Type: application/json
{
"event": "subscription.created",
"timestamp": 1719000000,
"data": { "...": "..." }
}Every delivery carries an X-Prosperanova-Signature header of the form t=timestamp,v1=signature, where the signature is an HMAC-SHA256 of timestamp.body keyed by the subscription secret shown to you once when the subscription was created. Recompute it over the raw body and compare before trusting the payload.
import crypto from 'node:crypto'
// body must be the RAW request body, byte for byte
function verify(header, body, secret) {
const [t, v1] = (header || '').split(',').map(part => part.split('=')[1])
if (!t || !v1) return false
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${body}`)
.digest('hex')
// timingSafeEqual throws on a length mismatch, so a malformed signature
// has to be rejected before the comparison rather than by it.
if (v1.length !== expected.length) return false
return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
}Delivery is one best-effort attempt with a five second timeout and no retries, so respond 2xx quickly and do the work asynchronously. An endpoint that fails twenty times in a row is disabled automatically and has to be re-enabled in the dashboard.
Start building