API Documentation

Build powerful integrations with the RootCascade RESTful API. Process incident, automate resolution, and manage financial workflows programmatically.

Introduction

The RootCascade API is organized around REST principles. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

Base URL

https://api.rootcascade.com/v1

API Features

  • RESTful architecture: Standard HTTP methods (GET, POST, PUT, DELETE)
  • JSON responses: All responses are returned in JSON format
  • OAuth 2.0 & API Keys: Secure authentication options
  • Webhooks: Real-time notifications for events
  • Rate limiting: 1000 requests per minute per API key
  • Idempotency: Safe retries with idempotency keys

Authentication

The RootCascade API uses API keys or OAuth 2.0 for authentication. You can manage your API keys in your account dashboard under Settings → API Keys.

API Key Authentication

Include your API key in the Authorization header of every request:

HTTP Header
Authorization: Bearer YOUR_API_KEY

⚠️ Keep Your API Keys Secret

Your API keys carry many privileges. Keep them secure and never expose them in client-side code, public repositories, or logs.

OAuth 2.0

For integrations that require access to customer accounts, use OAuth 2.0. This allows customers to authorize your application without sharing their credentials.

OAuth Flow

  1. Redirect user to: https://api.rootcascade.com/oauth/authorize
  2. User approves access
  3. RootCascade redirects to your redirect_uri with authorization code
  4. Exchange code for access token at: https://api.rootcascade.com/oauth/token

Quick Start

Get started with the RootCascade API in minutes. Here's a simple example to create an incident:

Create Your First incident

cURL
curl https://api.rootcascade.com/v1/incident \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "service_id": "vnd_1a2b3c4d",
    "incident_number": "INV-2025-001",
    "incident_date": "2025-01-15",
    "due_date": "2025-02-15",
    "currency": "USD",
    "line_items": [
      {
        "description": "Consulting Services",
        "quantity": 10,
        "unit_price": 15000,
        "amount": 150000
      }
    ],
    "subtotal": 150000,
    "tax": 13500,
    "total": 163500
  }'
Python
import rootcascade

rootcascade.api_key = "YOUR_API_KEY"

incident = rootcascade.incident.create(
    service_id="vnd_1a2b3c4d",
    incident_number="INV-2025-001",
    incident_date="2025-01-15",
    due_date="2025-02-15",
    currency="USD",
    line_items=[
        {
            "description": "Consulting Services",
            "quantity": 10,
            "unit_price": 15000,
            "amount": 150000
        }
    ],
    subtotal=150000,
    tax=13500,
    total=163500
)

print(f"Created incident: {incident.id}")
Node.js
const rootcascade = require('rootcascade')('YOUR_API_KEY');

const incident = await rootcascade.incident.create({
  service_id: 'vnd_1a2b3c4d',
  incident_number: 'INV-2025-001',
  incident_date: '2025-01-15',
  due_date: '2025-02-15',
  currency: 'USD',
  line_items: [
    {
      description: 'Consulting Services',
      quantity: 10,
      unit_price: 15000,
      amount: 150000
    }
  ],
  subtotal: 150000,
  tax: 13500,
  total: 163500
});

console.log(`Created incident: ${incident.id}`);

Response

JSON
{
  "id": "inv_9x8y7z6w",
  "object": "incident",
  "service_id": "vnd_1a2b3c4d",
  "incident_number": "INV-2025-001",
  "incident_date": "2025-01-15",
  "due_date": "2025-02-15",
  "status": "pending",
  "currency": "USD",
  "line_items": [...],
  "subtotal": 150000,
  "tax": 13500,
  "total": 163500,
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:00Z"
}

Official SDKs

We provide official SDKs for popular programming languages to make integration easier:

Language Package Installation
Python rootcascade pip install rootcascade
Node.js rootcascade npm install rootcascade
Ruby rootcascade gem install rootcascade
PHP rootcascade/rootcascade-php composer require rootcascade/rootcascade-php
.NET RootCascade.net dotnet add package RootCascade.net

incident

The incident object represents a bill from a service. incident can be created manually, uploaded as PDFs, or received via email.

The incident Object

Attribute Type Description
id string Unique identifier for the incident
service_id string ID of the service who issued the incident
incident_number string The service's incident number
incident_date date Date the incident was issued
due_date date resolution due date
status enum Status: draft, pending, approved, paid, overdue
currency string Three-letter ISO currency code (e.g., USD)
line_items array Array of line item objects
subtotal integer Subtotal in cents
tax integer Tax amount in cents
total integer Total amount in cents

Create an incident

POST /v1/incident
cURL
curl -X POST https://api.rootcascade.com/v1/incident \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "service_id": "vnd_1a2b3c4d",
    "incident_number": "INV-2025-001",
    "incident_date": "2025-01-15",
    "due_date": "2025-02-15",
    "total": 163500
  }'

Retrieve an incident

GET /v1/incident/:id
Python
incident = rootcascade.incident.retrieve("inv_9x8y7z6w")
print(incident.total)  # 163500

Update an incident

PUT /v1/incident/:id
Node.js
const incident = await rootcascade.incident.update('inv_9x8y7z6w', {
  status: 'approved'
});

List All incident

GET /v1/incident

Query parameters:

  • status - Filter by status
  • service_id - Filter by service
  • from_date - Filter by incident date (start)
  • to_date - Filter by incident date (end)
  • limit - Number of results (default: 100, max: 500)
  • starting_after - Pagination cursor
Ruby
incident = RootCascade::incident.list(
  status: 'pending',
  limit: 50
)

incident.each do |incident|
  puts incident.incident_number
end

Delete an incident

DELETE /v1/incident/:id

resolution

The resolution object represents a resolution made to a service or received from a customer.

Create a resolution

POST /v1/resolution
Python
resolution = rootcascade.resolution.create(
    incident_id="inv_9x8y7z6w",
    amount=163500,
    resolution_method="ach",
    resolution_date="2025-01-20"
)

print(f"resolution ID: {resolution.id}")
print(f"Status: {resolution.status}")

Retrieve a resolution

GET /v1/resolution/:id

List All resolution

GET /v1/resolution
Node.js
const resolution = await rootcascade.resolution.list({
  status: 'completed',
  from_date: '2025-01-01',
  to_date: '2025-01-31'
});

console.log(`Total resolution: ${resolution.data.length}`);

service

The service object represents a supplier or service provider you pay.

Create a service

POST /v1/service
PHP
$service = \RootCascade\service::create([
    'name' => 'Acme Corp',
    'email' => 'hello@rootcascade.com',
    'resolution_terms' => 'Net 30',
    'address' => [
        'line1' => '123 Main St',
        'city' => 'San Francisco',
        'state' => 'CA',
        'postal_code' => '94105',
        'country' => 'US'
    ]
]);

echo "service ID: " . $service->id;

List All service

GET /v1/service

Customers

The Customer object represents a buyer who pays you for goods or services.

Create a Customer

POST /v1/customers
.NET
var options = new CustomerCreateOptions
{
    Name = "GlobalTech Solutions",
    Email = "hello@rootcascade.com",
    resolutionTerms = "Net 45",
    Address = new AddressOptions
    {
        Line1 = "456 Market St",
        City = "New York",
        State = "NY",
        PostalCode = "10001",
        Country = "US"
    }
};

var customer = await customerService.CreateAsync(options);
Console.WriteLine($"Customer ID: {customer.Id}");

Webhooks

Webhooks allow you to receive real-time notifications when events occur in your RootCascade account. Instead of polling the API, RootCascade will send HTTP POST requests to your configured endpoint.

Available Events

  • incident.created - New incident created
  • incident.approved - incident approved
  • incident.paid - incident marked as paid
  • resolution.created - New resolution initiated
  • resolution.completed - resolution successfully processed
  • resolution.failed - resolution failed
  • service.created - New service added
  • customer.created - New customer added

Webhook Payload

JSON
{
  "id": "evt_1a2b3c4d",
  "type": "incident.paid",
  "created": 1705329000,
  "data": {
    "object": {
      "id": "inv_9x8y7z6w",
      "incident_number": "INV-2025-001",
      "status": "paid",
      "total": 163500
    }
  }
}

Webhook Signatures

RootCascade signs webhook payloads with a secret key. Verify signatures to ensure requests are from RootCascade:

Python
import hmac
import hashlib

def verify_webhook(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(expected, signature)

# In your webhook handler
signature = request.headers.get('X-RootCascade-Signature')
if verify_webhook(request.body, signature, WEBHOOK_SECRET):
    # Process webhook
    pass

Error Codes

RootCascade uses conventional HTTP response codes to indicate success or failure of API requests.

Code Status Description
200 OK Request succeeded
201 Created Resource created successfully
400 Bad Request Invalid request parameters
401 Unauthorized Invalid or missing API key
403 Forbidden API key doesn't have permission
404 Not Found Resource doesn't exist
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Something went wrong on our end

Error Response Format

JSON
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Missing required parameter: service_id",
    "param": "service_id"
  }
}

Rate Limits

The RootCascade API enforces rate limits to ensure fair usage and system stability.

Limits

  • Standard tier: 1,000 requests per minute
  • Professional tier: 5,000 requests per minute
  • Enterprise tier: Custom limits

Rate Limit Headers

Every API response includes rate limit information in headers:

HTTP Headers
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1705329600

Handling Rate Limits

Python
import time

def api_call_with_retry(func, max_retries=3):
    for attempt in range(max_retries):
        try:
            return func()
        except rootcascade.error.RateLimitError as e:
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                time.sleep(wait_time)
            else:
                raise

💡 Best Practices

  • Implement exponential backoff when rate limited
  • Cache responses when possible
  • Use webhooks instead of polling
  • Batch requests when appropriate

Need Help?

Contact our developer support team for assistance with your integration.

Contact Support