Developer Documentation

ClassifiedBilling API

REST + MCP
OAuth 2.0
JSON responses
HTTPS only

The ClassifiedBilling API lets you read and manage invoices, customers, and workspaces programmatically. It works as a standard REST API, as an MCP server for Claude AI, and is compatible with any AI platform or custom application that supports HTTP tool calling.

This documentation covers everything — from getting your first API key to calling every available tool, handling errors, and integrating with Claude's connector directory.

Using Claude? If you're connecting ClassifiedBilling to Claude AI specifically, jump straight to the MCP section.

Quick Start

Get up and running in under 5 minutes.

  1. Create an account
    Sign up at app.classifiedbilling.com. Any plan works — all plans include API access.
  2. Generate an API key
    Go to Settings → API Keys in the left sidebar. Click New Key, give it a name, and copy your key — it starts with cb_live_ and is shown only once.
  3. Make your first request
    Call the MCP server with your key in the Authorization header.
  4. Handle the response
    All responses are JSON. Successful responses include a result field. Errors include an error field.
"syn-cmt">// Your first API call — list all workspaces
const response = await fetch('https:"syn-cmt">//app.classifiedbilling.com/api/mcp-server', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cb_live_YOUR_KEY_HERE',
    'Content-Type':  'application/json',
  },
  body: JSON.stringify({
    tool:  'list_workspaces',
    input: {}
  })
});

const data = await response.json();
console.log(data.result.workspaces);
# Same request with curl
curl -X POST https:"syn-cmt">//app.classifiedbilling.com/api/mcp-server \
  -H "Authorization: Bearer cb_live_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"tool":"list_workspaces","input":{}}'

Authentication

All API requests require a Bearer token in the Authorization header. ClassifiedBilling supports two types of tokens:

API Keys (recommended for custom apps)

API keys start with cb_live_ and are generated from your Settings page. They are long-lived and scoped to the user who created them.

Authorization: Bearer cb_live_xK9mTz2pQrLvWnYs8dFgHj3a4BcDeF

OAuth Access Tokens (for Claude and third-party apps)

OAuth tokens are issued after a user completes the authorization flow. They expire after 90 days and are used by Claude and other AI platforms.

Authorization: Bearer a3f8c9d2e1b4f7a6c5d8e2f1a9b3c6d4e7f2a5b8c1d4e7f3a6b9c2d5e8f1
Security: Never expose your API key in client-side JavaScript that is publicly accessible. Always make API calls from your backend server or a secure environment.
Key storage: We store only a SHA-256 hash of your key — never the raw value. If you lose your key you must generate a new one. There is no way to recover a lost key.

Base URL

All API requests go to the same single endpoint. The tool field in the request body specifies which operation to perform.

https:"syn-cmt">//app.classifiedbilling.com/api/mcp-server

Request format

All requests are POST with a JSON body containing two fields:

FieldTypeDescription
toolrequiredstringThe name of the tool to call e.g. list_invoices
inputoptionalobjectParameters for the tool. Pass {} for tools with no inputs.

Response format

All successful responses return a result object. All error responses return an error string.

"syn-cmt">// Success response
{
  "result": {
    "workspaces": [...],
    "total": 3
  }
}

"syn-cmt">// Error response
{
  "error": "Workspace not found or access denied."
}

Error Handling

ClassifiedBilling uses standard HTTP status codes. Always check both the status code and the error field in the response body.

200 OKRequest succeeded. Response contains a result field.
400 Bad RequestMissing or invalid input fields. Check the error message for details.
401 UnauthorizedMissing, invalid, expired, or revoked API key or token.
403 ForbiddenValid token but no permission to access this resource.
404 Not FoundTool name not found, or requested resource does not exist.
500 Server ErrorUnexpected server error. Try again. Contact support if it persists.
"syn-cmt">// Recommended error handling pattern
const res = await fetch('https:"syn-cmt">//app.classifiedbilling.com/api/mcp-server', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ tool: 'list_invoices', input: { workspace_id: '...' } })
});

if (!res.ok) {
  const { error } = await res.json();
  throw new Error(`API error ${res.status}: ${error}`);
}

const { result } = await res.json();
"syn-cmt">// use result...

Rate Limits

API requests are limited per user to prevent abuse. Current limits:

PlanRequests / minuteRequests / day
Starter301,000
Standard605,000
Advance12020,000

When you exceed a rate limit you will receive a 429 Too Many Requests response. Wait before retrying.

MCP Overview

ClassifiedBilling implements the Model Context Protocol (MCP) — an open standard for connecting AI models to external tools and data. This means Claude (and any other MCP-compatible AI) can call your billing data directly in conversation.

list_workspaces
● Read only
List all workspaces belonging to the user
get_workspace_summary
● Read only
Get counts and invoice breakdown for a workspace
list_customers
● Read only
List and search customers in a workspace
create_customer
◆ Write
Create a new customer in a workspace
list_invoices
● Read only
List invoices, optionally filtered by status
get_overdue_invoices
● Read only
Get all unpaid invoices past their due date
mark_invoice_paid
◆ Write
Mark an invoice as paid with optional payment method
get_revenue_summary
● Read only
Total paid vs outstanding revenue for a workspace

Connecting Claude

To connect ClassifiedBilling to Claude AI:

  1. Generate an API key
    Go to Settings → API Keys and create a new key. Name it something like "Claude AI".
  2. Open Claude's connector page
    In Claude.ai, go to Customize → Connectors and find ClassifiedBilling in the directory.
  3. Click Connect and paste your key
    You will be redirected to app.classifiedbilling.com/mcp-connect. Paste your cb_live_... key and click Approve.
  4. Start using it
    Ask Claude: "Show my overdue invoices" or "How much revenue did I collect this month?"

List Workspaces

Returns all workspaces owned by the authenticated user. Call this first — you need a workspace_id for most other tools.

POST/api/mcp-servertool: list_workspaces

Input

No input fields required. Pass an empty object.

{
  "tool":  "list_workspaces",
  "input": {}
}

Response

{
  "result": {
    "workspaces": [
      {
        "id":               "clx1a2b3c4d5e6f7g8h9",
        "title":            "SaaS Clerk",
        "description":      "My main billing workspace",
        "workspaceUrlSlug": "saas-clerk",
        "businessDetails": {
          "businessName":  "SaaS Clerk Ltd",
          "businessEmail": "hello@saasclerk.com"
        }
      }
    ]
  }
}

Workspace Summary

Returns customer count, invoice count, service item count, team member count, and a breakdown of invoices by payment status.

POST/api/mcp-servertool: get_workspace_summary
{
  "tool":  "get_workspace_summary",
  "input": { "workspace_id": "clx1a2b3c4d5e6f7g8h9" }
}

Response

{
  "result": {
    "id":      "clx1a2b3c4d5e6f7g8h9",
    "title":   "SaaS Clerk",
    "business": "SaaS Clerk Ltd",
    "counts": {
      "customers":    12,
      "invoices":     38,
      "serviceItems": 6,
      "teamMembers":  2
    },
    "invoices_by_status": [
      { "status": "Paid", "count": 30 },
      { "status": "Due",  "count": 8  }
    ]
  }
}

List Customers

Returns customers in a workspace. Optionally filter by name or email using the search parameter. Returns up to 50 results.

POST/api/mcp-servertool: list_customers

Input parameters

FieldTypeDescription
workspace_idrequiredstringID of the workspace to list customers from
searchoptionalstringFilter by company name or email (case insensitive)
{
  "tool": "list_customers",
  "input": {
    "workspace_id": "clx1a2b3c4d5e6f7g8h9",
    "search":       "acme"  "syn-cmt">// optional
  }
}

Response

{
  "result": {
    "customers": [
      {
        "id":                        "cust_abc123",
        "companyName":               "Acme Corp",
        "companyEmail":              "billing@acme.com",
        "companyCurrency":           "USD",
        "companyCountry":            "United States",
        "companyContactFirstName":   "John",
        "companyContactLastName":    "Smith",
        "companyContactPersonEmail": "john@acme.com"
      }
    ],
    "total": 1
  }
}

Create Customer

Creates a new customer in a workspace. All address and contact fields are required.

POST/api/mcp-servertool: create_customer

Input parameters

FieldTypeDescription
workspace_idrequiredstringTarget workspace ID
company_namerequiredstringCompany or client name
company_emailrequiredstringCompany email address
currencyrequiredstringCurrency code e.g. USD, EUR, GBP
contact_first_namerequiredstringContact person first name
contact_last_namerequiredstringContact person last name
contact_emailrequiredstringContact person email
addressrequiredstringStreet address
cityrequiredstringCity
staterequiredstringState or region
ziprequiredstringZip or postal code
countryrequiredstringCountry name
{
  "tool": "create_customer",
  "input": {
    "workspace_id":       "clx1a2b3c4d5e6f7g8h9",
    "company_name":       "Acme Corp",
    "company_email":      "billing@acme.com",
    "currency":           "USD",
    "contact_first_name": "John",
    "contact_last_name":  "Smith",
    "contact_email":      "john@acme.com",
    "address":            "123 Main Street",
    "city":               "New York",
    "state":              "NY",
    "zip":                "10001",
    "country":            "United States"
  }
}

List Invoices

Returns invoices for a workspace. Filter by payment status and control how many results to return.

POST/api/mcp-servertool: list_invoices

Input parameters

FieldTypeDescription
workspace_idrequiredstringWorkspace ID
statusoptionalstringDue, Paid, or all. Defaults to all.
limitoptionalnumberMax results to return. Default 20, max 100.
{
  "tool": "list_invoices",
  "input": {
    "workspace_id": "clx1a2b3c4d5e6f7g8h9",
    "status":       "Due",
    "limit":        10
  }
}

Response

{
  "result": {
    "invoices": [
      {
        "id":       "inv_xyz789",
        "number":   "INV-0042",
        "client":   "Acme Corp",
        "amount":   2500.00,
        "currency": "USD",
        "status":   "Due",
        "issued":   "2025-02-01T00:00:00.000Z",
        "due":      "2025-03-01T00:00:00.000Z"
      }
    ],
    "total": 1
  }
}

Get Overdue Invoices

Returns all unpaid invoices where the due date has already passed. Results are ordered by oldest due date first — the most urgent first.

POST/api/mcp-servertool: get_overdue_invoices
{
  "tool":  "get_overdue_invoices",
  "input": { "workspace_id": "clx1a2b3c4d5e6f7g8h9" }
}

Response includes

A list of overdue invoices plus a total_overdue_amount sum.

{
  "result": {
    "overdue_invoices": [
      {
        "id":       "inv_xyz789",
        "number":   "INV-0042",
        "client":   "Acme Corp",
        "due_date": "2025-03-01T00:00:00.000Z",
        "amount":   2500.00,
        "currency": "USD"
      }
    ],
    "total_overdue_amount": 7850.00,
    "count": 3
  }
}

Mark Invoice as Paid

Updates an invoice's status to Paid and records the payment date and method.

POST/api/mcp-servertool: mark_invoice_paid

Input parameters

FieldTypeDescription
workspace_idrequiredstringWorkspace ID
invoice_idrequiredstringID of the invoice to mark as paid
payment_methodoptionalstringHow it was paid e.g. Bank Transfer, Stripe, Cash
{
  "tool": "mark_invoice_paid",
  "input": {
    "workspace_id":   "clx1a2b3c4d5e6f7g8h9",
    "invoice_id":     "inv_xyz789",
    "payment_method": "Bank Transfer"
  }
}

Revenue Summary

Returns total paid revenue, total outstanding, and invoice counts for a workspace. Useful for dashboard-style overviews.

POST/api/mcp-servertool: get_revenue_summary
{
  "tool":  "get_revenue_summary",
  "input": { "workspace_id": "clx1a2b3c4d5e6f7g8h9" }
}

Response

{
  "result": {
    "total_paid":        18500.00,
    "total_outstanding": 7850.00,
    "paid_invoices":     12,
    "unpaid_invoices":   4,
    "total_invoices":    16
  }
}

OAuth 2.0 Flow

For third-party platforms (like Claude) that need to act on behalf of a user, ClassifiedBilling implements the OAuth 2.0 Authorization Code flow with PKCE.

Building a custom integration? If you control both your app and your users, use API keys instead — they are simpler. OAuth is for platforms where your users log in to ClassifiedBilling via your product.

Flow overview

Your app  →  redirect user to /mcp-connect?redirect_uri=...&state=...&code_challenge=...
User      →  pastes their ClassifiedBilling API key and clicks Approve
CB server →  redirects back to redirect_uri?code=...&state=...
Your app  →  POST /api/mcp-token with code + code_verifier
CB server →  returns { access_token, token_type, expires_in }
Your app  →  use access_token as Bearer token on all future API calls

Authorization endpoint

GET https:"syn-cmt">//app.classifiedbilling.com/mcp-connect
  ?redirect_uri=https:"syn-cmt">//yourapp.com/callback
  &state=RANDOM_STATE_STRING
  &code_challenge=BASE64URL_SHA256_OF_VERIFIER
  &client_id=your_app_name
FieldTypeDescription
redirect_urirequiredstringWhere to redirect after the user approves
staterequiredstringRandom string you generate — returned unchanged to verify the response
code_challengerequiredstringBase64url encoded SHA-256 of your code_verifier
client_idoptionalstringYour app identifier

Token endpoint

POST https:"syn-cmt">//app.classifiedbilling.com/api/mcp-token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=CODE_FROM_CALLBACK
&redirect_uri=https:"syn-cmt">//yourapp.com/callback
&code_verifier=YOUR_ORIGINAL_VERIFIER

Returns:

{
  "access_token": "a3f8c9d2e1b4...",
  "token_type":   "Bearer",
  "expires_in":   7776000  "syn-cmt">// 90 days in seconds
}