Skip to content
JAOT

Credits & Billing

The Credits and Billing endpoints let you check your credit balance, view transaction history, estimate costs, and manage Stripe-powered billing. Credits are the currency for running optimizations on JAOT.

GET /api/v2/credits/balance

Get the current credit balance for your organization.

Authentication: Requires API key or JWT token.

Response

FieldTypeDescription
credits_balanceintegerTotal credits available (purchased + earned)
credits_earnedintegerCredits earned from marketplace model sales (withdrawable)
currencystringOrganization's preferred currency
local_balancenumberBalance converted to preferred currency
local_earnednumberEarned credits converted to preferred currency
exchange_ratenumberCurrent exchange rate to preferred currency
credits_per_eurintegerCredits per euro (currently 10)

Examples

import httpx

API_URL = "https://api.jaot.io/api/v2"
headers = {"Authorization": "Bearer ok_live_your_key_here"}

response = httpx.get(f"{API_URL}/credits/balance", headers=headers)
balance = response.json()
print(f"Credits: {balance['credits_balance']}")
print(f"Earned: {balance['credits_earned']}")
print(f"Local balance: {balance['local_balance']} {balance['currency']}")

Response

{
  "credits_balance": 950,
  "credits_earned": 200,
  "currency": "EUR",
  "local_balance": 95.0,
  "local_earned": 20.0,
  "exchange_rate": 1.0,
  "credits_per_eur": 10
}

GET /api/v2/credits/transactions

Get credit transaction history for your organization.

Authentication: Requires API key or JWT token.

Query Parameters

ParameterTypeDefaultDescription
transaction_typestring--Filter by type: purchase, execution, sale_earning, withdrawal, refund, adjustment
limitinteger50Max results (1-100)
offsetinteger0Number of results to skip

Response

Returns an array of transaction objects.

FieldTypeDescription
idstringTransaction ID (e.g. "txn_a1b2c3d4")
transaction_typestringType of transaction
credits_amountintegerCredits change (negative = deduction, positive = addition)
balance_afterintegerCredit balance after this transaction
descriptionstringHuman-readable description
reference_typestringRelated entity type (e.g. "solve", "topup")
reference_idstringRelated entity ID
amount_eurnumberEuro equivalent amount
created_atstringISO 8601 timestamp

Examples

import httpx

response = httpx.get(
    "https://api.jaot.io/api/v2/credits/transactions",
    params={"limit": 10},
    headers={"Authorization": "Bearer ok_live_your_key_here"},
)
transactions = response.json()
for tx in transactions:
    print(f"{tx['created_at']}: {tx['credits_amount']:+d} credits - {tx['description']}")

Response

[
  {
    "id": "txn_a1b2c3d4",
    "transaction_type": "execution",
    "credits_amount": -3,
    "balance_after": 947,
    "description": "Solver execution",
    "reference_type": "solve",
    "reference_id": "exe_9a1b2c3d",
    "amount_eur": 0.048,
    "created_at": "2026-02-19T10:05:12Z"
  }
]

POST /api/v2/credits/calculator

Estimate credits for an optimization problem. This endpoint is public and does not require authentication.

Info: The credit calculator is public -- no authentication required. Use it to estimate costs before signing up or committing credits.

Request Body

FieldTypeRequiredDescription
num_variablesintegerYesTotal number of decision variables (0-100,000)
num_integer_varsintegerNoNumber of integer variables (default: 0)
num_binary_varsintegerNoNumber of binary variables (default: 0)
num_constraintsintegerNoNumber of constraints (0-100,000, default: 0)
time_limit_secondsnumberNoTime limit in seconds (1-3600, default: 60)

Response

FieldTypeDescription
credits_requiredintegerEstimated credits needed
breakdownobjectCost breakdown by component
breakdown.base_costnumberBase cost (always 1)
breakdown.variable_costnumberCost from number of variables
breakdown.integer_penaltynumberAdditional cost for integer variables
breakdown.binary_penaltynumberAdditional cost for binary variables
breakdown.constraint_costnumberCost from number of constraints
breakdown.time_limit_bonusnumberExtra cost for time limits above 60s
cost_eurnumberEstimated cost in EUR
cost_by_planobjectCost in EUR for each plan tier

Examples

import httpx

API_URL = "https://api.jaot.io/api/v2"

response = httpx.post(f"{API_URL}/credits/calculator", json={
    "num_variables": 100,
    "num_integer_vars": 50,
    "num_binary_vars": 20,
    "num_constraints": 80,
    "time_limit_seconds": 60,
})

estimate = response.json()
print(f"Estimated credits: {estimate['credits_required']}")
print(f"Breakdown: {estimate['breakdown']}")
print(f"Cost (Pro plan): EUR {estimate['cost_by_plan']['pro']}")

Response

{
  "credits_required": 33,
  "breakdown": {
    "base_cost": 1,
    "variable_cost": 10.0,
    "integer_penalty": 15.0,
    "binary_penalty": 4.0,
    "constraint_cost": 4.0,
    "time_limit_bonus": 0
  },
  "cost_eur": 0.528,
  "cost_by_plan": {
    "free": 0,
    "starter": 0.627,
    "pro": 0.528,
    "topup_500": 0.924,
    "topup_2000": 0.792,
    "topup_5000": 0.66,
    "topup_20000": 0.528
  }
}

For the full credit formula and pricing details, see Rate Limits & Credits.


POST /api/v2/billing/checkout/subscription

Create a Stripe Checkout session for a subscription plan.

Authentication: Requires API key or JWT token.

Request Body

FieldTypeRequiredDescription
planstringYesPlan name: "starter", "pro", or "business"
success_urlstringNoRedirect URL after successful payment
cancel_urlstringNoRedirect URL if user cancels

Response

FieldTypeDescription
checkout_urlstringStripe Checkout URL -- redirect the user here
session_idstringStripe session ID

Examples

import httpx

response = httpx.post(
    "https://api.jaot.io/api/v2/billing/checkout/subscription",
    headers={"Authorization": "Bearer ok_live_your_key_here"},
    json={"plan": "pro"},
)
checkout = response.json()
print(f"Redirect to: {checkout['checkout_url']}")

Response

{
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_live_...",
  "session_id": "cs_live_..."
}

POST /api/v2/billing/checkout/topup

Create a Stripe Checkout session for a credit top-up purchase.

Authentication: Requires API key or JWT token.

Request Body

FieldTypeRequiredDescription
creditsintegerYesCredit package: 500, 2000, 5000, or 20000
success_urlstringNoRedirect URL after payment
cancel_urlstringNoRedirect URL if cancelled

Available packages:

CreditsPricePer Credit
500EUR 14EUR 0.028
2,000EUR 48EUR 0.024
5,000EUR 100EUR 0.020
20,000EUR 320EUR 0.016

Examples

import httpx

response = httpx.post(
    "https://api.jaot.io/api/v2/billing/checkout/topup",
    headers={"Authorization": "Bearer ok_live_your_key_here"},
    json={"credits": 2000},
)
checkout = response.json()
print(f"Top-up checkout: {checkout['checkout_url']}")

GET /api/v2/billing/status

Get the current billing and subscription status for your organization.

Authentication: Requires API key or JWT token.

Response

FieldTypeDescription
stripe_configuredbooleanWhether Stripe is configured on the server
has_subscriptionbooleanWhether the org has an active subscription
subscriptionobjectSubscription details (null if none)
subscription.idstringStripe subscription ID
subscription.statusstringSubscription status
subscription.planstringPlan name
subscription.current_period_startstringCurrent billing period start
subscription.current_period_endstringCurrent billing period end

Examples

import httpx

response = httpx.get(
    "https://api.jaot.io/api/v2/billing/status",
    headers={"Authorization": "Bearer ok_live_your_key_here"},
)
status = response.json()
if status["has_subscription"]:
    print(f"Plan: {status['subscription']['plan']}")

POST /api/v2/billing/portal

Create a Stripe Billing Portal session for self-service subscription management, payment methods, and invoice history.

Authentication: Requires API key or JWT token.

Request Body

FieldTypeRequiredDescription
return_urlstringNoURL to redirect back to after portal session

Response

FieldTypeDescription
portal_urlstringStripe Billing Portal URL

Examples

import httpx

response = httpx.post(
    "https://api.jaot.io/api/v2/billing/portal",
    headers={
        "Authorization": "Bearer ok_live_your_key_here",
        "Content-Type": "application/json",
    },
    json={"return_url": "https://app.jaot.io/workspace/credits"},
)
portal = response.json()
print(f"Portal URL: {portal['portal_url']}")

Response

{
  "portal_url": "https://billing.stripe.com/p/session/..."
}

POST /api/v2/billing/webhook

Stripe webhook endpoint. This endpoint is public -- it does not require API key authentication. Instead, Stripe signs each request using the webhook secret.

Handles events: checkout.session.completed, invoice.paid, customer.subscription.updated, customer.subscription.deleted.

Configure the webhook URL in your Stripe Dashboard: https://your-domain.com/api/v2/billing/webhook


GET /api/v2/billing/invoices

List invoices for your organization.

Authentication: Requires API key or JWT token.

Query Parameters

ParameterTypeDefaultDescription
limitinteger50Max results (1-100)
offsetinteger0Number of results to skip

Examples

import httpx

response = httpx.get(
    "https://api.jaot.io/api/v2/billing/invoices",
    headers={"Authorization": "Bearer ok_live_your_key_here"},
)
invoices = response.json()
for inv in invoices["items"]:
    print(f"{inv['invoice_number']}: EUR {inv['total_eur']} ({inv['status']})")

Response

{
  "items": [
    {
      "id": "inv_a1b2c3d4e5f67890",
      "invoice_number": "INV-2026-00001",
      "invoice_type": "topup",
      "status": "paid",
      "issued_at": "2026-02-19T15:00:00",
      "paid_at": "2026-02-19T15:00:00",
      "org_name": "Acme Corp",
      "subtotal_eur": 48.0,
      "tax_rate": 0.0,
      "tax_amount_eur": 0.0,
      "total_eur": 48.0,
      "currency": "EUR",
      "total_local": 48.0,
      "credits_granted": 2000,
      "line_items": [
        {
          "description": "Credit Top-Up: 2,000 credits",
          "quantity": 2000,
          "unit_price_eur": 0.024,
          "total_eur": 48.0,
          "credits": 2000
        }
      ],
      "notes": "Credit top-up: 2,000 credits"
    }
  ],
  "total": 1
}

Errors

HTTP CodeErrorDescription
401unauthorizedMissing or invalid API key
503service_unavailableStripe is not configured on the server