Prosperanova
LoginBlogDocsDevelopersPricingSign up
icon-sun
icon-close
English
Español
Deutsch
Português
Italiano
Français
Русский
Nederlands
ไทย
ελληνικά
中文
Bahasa Indonesia
Türkçe
Polski
한국어
Magyar
Română
Hrvatski jezik
Tiếng Việt
Српски
العربية
Dansk
Svenska
Català
Українська
日本語
Čeština
Prosperanova
Features▼
customer support softwarelive chat for website
BlogDocsDevelopersPricingLoginSign up
icon-sun
icon-close
English
Español
Deutsch
Português
Italiano
Français
Русский
Nederlands
ไทย
ελληνικά
中文
Bahasa Indonesia
Türkçe
Polski
한국어
Magyar
Română
Hrvatski jezik
Tiếng Việt
Српски
العربية
Dansk
Svenska
Català
Українська
日本語
Čeština

Prosperanova for developers

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 keysQuick startScopesClaude & ChatGPTWebhooksREST API

API keys

Get a key and authenticate

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

Your first three calls

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

Least privilege by default

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.

  • customers:readList customers and read a single customer.
  • customers:writeCreate and update customers.
  • subscriptions:readList subscriptions and read a single subscription.
  • subscriptions:writeCreate, update and cancel subscriptions.
  • products:readList products and read a single product.
  • products:writeCreate and update products.
  • prices:readList prices and read a single price.
  • prices:writeCreate and update prices.
  • coupons:readList coupons and read a single coupon.
  • coupons:writeCreate and update coupons.
  • invoices:readRead the invoices the billing engine issued. Read-only: invoices are produced by billing runs, never written by an integrator.
  • paymentintents:readRead payment intents. Read-only: they are produced when a charge is attempted.

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

Connect your Prosperanova account with MCP

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.

  • show_billing_overviewA bounded project snapshot with customer and subscription counts, status totals, and recent subscriptions.
  • get_subscriptionOne subscription with its customer, product, price, billing period, and payment status.
  • billing toolsList projects, products, prices, customers, and subscriptions, or create a new project after write approval.

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

Signed 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.

  • customer.createdA customer was created.
  • customer.updatedA customer was edited.
  • subscription.createdA subscription was created and its first period billed.
  • subscription.updatedA subscription changed — a plan change, or a billing run that renewed it.
  • subscription.deletedA subscription was canceled.
  • product.createdA product was created.
  • product.updatedA product was edited.
  • price.createdA price was created.
  • price.updatedA price was edited.
  • coupon.createdA coupon was created.
  • coupon.updatedA coupon was edited.
  • invoice.createdAn invoice was issued.
  • invoice.updatedAn invoice changed, for example when it was paid.
  • paymentintent.succeededA charge went through.
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": { "...": "..." }
}

Verify the signature

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

Language

EnglishEspañolDeutschPortuguêsFrançaisItalianoไทยNederlandsελληνικάBahasa IndonesiaPolskiTürkçe

Resources

StatusBlogDocsPricingDevelopersAPI referencePrivacy Policy

Contact us

info@prosperanova.com

Copyright @ Prosperanova 2023 - 2026