Skip to content

Billing

beginner

Plans, subscriptions, invoices, upgrades, downgrades, and payment management endpoints.

List plans

GET/v1/billing/plans

List all available plans with features and pricing.

200Response
{
  "plans": [
    {
      "id": "free",
      "name": "Free",
      "price_monthly": 0,
      "price_annual": 0,
      "patterns_limit": 1000,
      "members_limit": 1,
      "rate_limit": 10,
      "features": [
        "all_pathways",
        "causal_reasoning",
        "consolidation",
        "explainability",
        "webhooks"
      ]
    },
    {
      "id": "starter",
      "name": "Starter",
      "price_monthly": 2900,
      "price_annual": 27840,
      "patterns_limit": 10000,
      "members_limit": 3,
      "rate_limit": 50,
      "features": [
        "all_pathways",
        "causal_reasoning",
        "consolidation",
        "explainability",
        "webhooks"
      ]
    },
    {
      "id": "professional",
      "name": "Professional",
      "price_monthly": 9900,
      "price_annual": 95040,
      "patterns_limit": 100000,
      "members_limit": -1,
      "rate_limit": 200,
      "features": [
        "all_pathways",
        "causal_reasoning",
        "consolidation",
        "explainability",
        "webhooks",
        "priority_support"
      ]
    },
    {
      "id": "business",
      "name": "Business",
      "price_monthly": 29900,
      "price_annual": 287040,
      "patterns_limit": 500000,
      "members_limit": -1,
      "rate_limit": 500,
      "features": [
        "all_pathways",
        "causal_reasoning",
        "consolidation",
        "explainability",
        "webhooks",
        "priority_support",
        "sla"
      ]
    }
  ]
}
import os
from engramma_cloud import EngrammaClient

client = EngrammaClient(api_key=os.environ["ENGRAMMA_API_KEY"])

plans = client.billing.plans()
for plan in plans:
    price = f"${plan.price_monthly / 100}/mo" if plan.price_monthly else "Free"
    print(f"{plan.name}: {price} — {plan.patterns_limit} patterns")
Info

Prices are in cents. A members_limit of -1 means unlimited.


Create checkout session

POST/v1/billing/checkout

Create a checkout session to subscribe to a paid plan. Returns a URL to redirect the user to.

org_idstringrequired

Organization to subscribe.

plan_idstringrequired

Plan to subscribe to: starter, professional, or business.

billing_cyclestringDefault: monthly

Billing cycle: monthly or annual (20% discount).

success_urlstringrequired

URL to redirect to after successful payment.

cancel_urlstringrequired

URL to redirect to if payment is cancelled.

201Response
{
  "session_id": "cs_abc123",
  "checkout_url": "https://checkout.engramma-memory.com/cs_abc123",
  "expires_at": "2026-01-15T11:00:00Z"
}

Customer portal

POST/v1/billing/portal

Create a customer portal session for managing payment methods and viewing invoices.

org_idstringrequired

Organization ID.

return_urlstringrequired

URL to redirect to when the user leaves the portal.

201Response
{
  "portal_url": "https://billing.engramma-memory.com/portal/ps_abc123",
  "expires_at": "2026-01-15T11:00:00Z"
}

Upgrade plan

POST/v1/billing/{org_id}/upgrade

Upgrade to a higher plan. Takes effect immediately. Prorated charge for the remaining period.

plan_idstringrequired

Target plan: must be higher than current plan.

200Response
{
  "previous_plan": "starter",
  "new_plan": "professional",
  "effective_at": "2026-01-15T10:00:00Z",
  "prorated_amount": 4700,
  "new_limits": {
    "patterns": 100000,
    "rate_limit": 200,
    "members": -1
  }
}

Downgrade plan

POST/v1/billing/{org_id}/downgrade

Downgrade to a lower plan. Takes effect at the end of the current billing period.

plan_idstringrequired

Target plan: must be lower than current plan.

200Response
{
  "previous_plan": "professional",
  "new_plan": "starter",
  "effective_at": "2026-02-15T00:00:00Z",
  "warning": "Your current pattern count (45,000) exceeds the Starter limit (10,000). You won't be able to store new memories until you reduce pattern count."
}
Warning

If your current usage exceeds the new plan's limits, you won't lose data but new stores will be blocked until you consolidate or delete patterns.


Get subscription

GET/v1/billing/{org_id}/subscription

Get current subscription details.

200Response
{
  "org_id": "org_abc123",
  "plan": "professional",
  "status": "active",
  "billing_cycle": "monthly",
  "current_period": {
    "start": "2026-01-15T00:00:00Z",
    "end": "2026-02-15T00:00:00Z"
  },
  "payment_method": {
    "type": "card",
    "last4": "4242",
    "brand": "visa",
    "exp_month": 12,
    "exp_year": 2026
  },
  "next_invoice_amount": 9900
}

List invoices

GET/v1/billing/{org_id}/invoices

List all invoices for the organization.

pageintegerDefault: 1

Page number.

per_pageintegerDefault: 20

Items per page.

200Response
{
  "data": [
    {
      "id": "inv_abc123",
      "amount": 9900,
      "currency": "usd",
      "status": "paid",
      "plan": "professional",
      "period_start": "2026-01-15T00:00:00Z",
      "period_end": "2026-02-15T00:00:00Z",
      "paid_at": "2026-01-15T00:01:00Z",
      "pdf_url": "https://billing.engramma-memory.com/invoices/inv_abc123.pdf"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 3,
    "total_pages": 1
  }
}

Upcoming invoice

GET/v1/billing/{org_id}/invoices/upcoming

Preview the next invoice before it's charged.

200Response
{
  "amount": 9900,
  "currency": "usd",
  "period_start": "2026-02-15T00:00:00Z",
  "period_end": "2026-03-15T00:00:00Z",
  "charge_date": "2026-02-15T00:00:00Z",
  "line_items": [
    {
      "description": "Professional plan — monthly",
      "amount": 9900
    }
  ]
}

Retry failed payment

POST/v1/billing/{org_id}/invoices/{invoice_id}/retry

Retry a failed invoice payment.

200Response
{
  "invoice_id": "inv_abc123",
  "status": "paid",
  "paid_at": "2026-01-15T10:30:00Z"
}

Cancel subscription

POST/v1/billing/{org_id}/cancel

Cancel the subscription. Takes effect at the end of the current period.

reasonstring

Optional cancellation reason for feedback.

200Response
{
  "status": "cancelling",
  "effective_at": "2026-02-15T00:00:00Z",
  "data_retention_days": 30,
  "message": "Your subscription will end on 2026-02-15. Data retained for 30 days after."
}

Reactivate subscription

POST/v1/billing/{org_id}/reactivate

Reactivate a cancelled subscription before it expires.

200Response
{
  "status": "active",
  "plan": "professional",
  "message": "Subscription reactivated successfully"
}

Next steps