REST API Reference v2

KARVO ERP API

Build powerful integrations with a complete B2B ERP platform. 81 endpoints across 13 modules, from invoicing to AI-powered analytics.

81Endpoints
13Modules
60RPM Rate Limit
100%JSON

Quick Start

Everything you need to authenticate and make your first API call.

Authentication

Use WordPress Application Passwords or an API key in the X-SE-ERP-Key header. Keys support read-only or read-write scopes.

X-SE-ERP-Key: se_a1b2c3d4e5...

Base URL

All endpoints are under the WordPress REST API namespace. Replace the domain with your KARVO ERP instance URL.

https://app.karvoerp.com/wp-json/se-erp/v2/

Rate Limits

Default: 60 requests per minute per API key (configurable). Monitor usage via response headers.

X-RateLimit-Limit: 60 X-RateLimit-Remaining: 58 X-RateLimit-Reset: 1713052800

Endpoint Catalog

Full REST API reference organized by module. Click any module to expand.

Invoices

Full CRUD on invoice records with line items, search, and filtering

7
GET/invoicesList invoices with filters (date, customer, status)
POST/invoicesCreate invoice with optional line items
GET/invoices/{id}Get invoice with lines, shipment, and payments
PUT/invoices/{id}Update invoice status, balance, or metadata
DELETE/invoices/{id}Delete an invoice record
GET/invoices/{id}/linesList line items for an invoice
GET/invoices/search?q=Full-text search across invoice numbers and names
GET/customersList all customers with pagination
POST/customersCreate a new customer record
GET/customers/{id}Get customer details
PUT/customers/{id}Update customer data
DELETE/customers/{id}Remove a customer record
GET/customers/{id}/healthCustomer health score and churn risk
GET/customers/{id}/invoicesList invoices for a specific customer
GET/productsList products with search and SKU filter
POST/productsCreate a new product
GET/products/{id}Get product with all enriched metadata
PUT/products/{id}Update product fields
GET/products/sku/{sku}Lookup by SKU with alias resolution
GET/products/categoriesList all product categories
POST/customers/searchSearch customers by name, email, or code
GET/pricing/{sku}Resolve price for SKU via 4-tier waterfall
GET/pricing/rulesList all price rules
GET/pricing/negotiationsList B2B price negotiations
POST/pricing/negotiationsSubmit a new price negotiation request
PUT/pricing/negotiations/{id}Approve, reject, or counter a negotiation
GET/shipmentsList shipments with status and customer filters
POST/shipmentsCreate a new shipment from an invoice
GET/shipments/{id}Get full shipment details with tracking
PUT/shipments/{id}Update status, tracking number, or carrier
POST/shipments/{id}/advanceAdvance shipment to next status in workflow
GET/backordersList all backorders with filters
POST/backordersCreate a backorder entry
GET/backorders/{id}Get backorder details
PUT/backorders/{id}Update backorder status or expected date
POST/backorders/{id}/fulfillMark backorder as fulfilled
POST/backorders/{id}/cancelCancel a backorder
GET/backorders/by-customer/{code}Backorders for a specific customer
GET/backorders/by-sku/{sku}Backorders for a specific product SKU
GET/cleaning/contractsList cleaning contracts by status
POST/cleaning/contractsCreate a new cleaning contract
GET/cleaning/contracts/{id}Get contract with line items and service log
GET/claimsList claims with pagination
POST/claimsCreate a new claim
GET/claims/{id}Get full claim details
PUT/claims/{id}Update claim status or resolution
GET/billing/agingAR aging report (current, 30, 60, 90+ days)
POST/billing/paymentsRecord a payment against an invoice
GET/billing/creditsList credit notes
POST/billing/creditsIssue a credit note
GET/payroll/employeesList all employees
POST/payroll/employeesAdd a new employee
GET/payroll/employees/{id}Get employee details with tax info
PUT/payroll/employees/{id}Update employee pay rate, status, or deductions
GET/payroll/timesheetsList timesheet entries with date range filter
POST/payroll/timesheetsSubmit a timesheet entry (regular, overtime, holiday)
GET/payroll/runsList pay runs (weekly, biweekly, semi-monthly, monthly)
POST/payroll/runsProcess a new pay run for a period
GET/payroll/runs/{id}/stubsGet all pay stubs for a run
GET/payroll/runs/{id}/cpa005Download CPA-005 Desjardins payment file
GET/payroll/remittancesGovernment remittance summary (RRQ, AE, RQAP, taxes)
GET/payroll/employees/{id}/t4Generate T4/RL-1 year-end tax slip data
GET/ai/conversationsList user's AI chat conversations
POST/ai/conversationsStart a new AI conversation
GET/ai/conversations/{id}Get conversation with full message history
POST/ai/conversations/{id}/messageSend a natural language query and get results
GET/ai/saved-queriesList saved/bookmarked queries
POST/ai/saved-queriesSave a query for reuse
GET/analytics/revenueMonthly revenue stats for the past N months
GET/analytics/forecastRevenue forecast with confidence intervals
GET/warehousesList all warehouses
POST/warehousesCreate a new warehouse
GET/warehouses/stockStock overview across all warehouses
GET/warehouses/stock/{sku}Stock levels for a specific SKU
POST/warehouses/transfersCreate an inter-warehouse transfer
GET/webhooksList all webhook subscriptions
POST/webhooksCreate a webhook subscription
DELETE/webhooks/{id}Remove a webhook subscription
GET/whmisList all WHMIS/SDS records
GET/whmis/{sku}Get SDS data for a specific product SKU
GET/tenantsList all tenants
POST/tenantsProvision a new tenant
GET/tenants/{id}/usageTenant usage metrics (API calls, storage, users)
GET/pingHealth check (returns version + server time, no auth)
POST/stripe/webhookStripe webhook receiver (signature-verified)

Code Examples

Get started in seconds with your preferred language.

# List invoices for a customer
curl "https://app.karvoerp.com/wp-json/se-erp/v2/invoices?customer_code=ACME01" \
  -H "X-SE-ERP-Key: se_your_api_key_here"

# Create a new invoice with line items
curl -X POST "https://app.karvoerp.com/wp-json/se-erp/v2/invoices" \
  -H "X-SE-ERP-Key: se_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "invoice_no": "INV-2026-0042",
    "customer_code": "ACME01",
    "customer_name": "Acme Distribution Inc.",
    "subtotal": 1250.00,
    "tps": 62.50,
    "tvq": 124.69,
    "total": 1437.19,
    "lines": [
      {"sku": "CLN-5000", "description": "Cleaner 5L", "qty": 50, "unit_price": 25.00, "line_total": 1250.00}
    ]
  }'

# Advance a shipment to the next status
curl -X POST "https://app.karvoerp.com/wp-json/se-erp/v2/shipments/1234/advance" \
  -H "X-SE-ERP-Key: se_your_api_key_here"
import requests

BASE = "https://app.karvoerp.com/wp-json/se-erp/v2"
HEADERS = {"X-SE-ERP-Key": "se_your_api_key_here"}

# List recent invoices for a customer
resp = requests.get(
    f"{BASE}/invoices",
    headers=HEADERS,
    params={"customer_code": "ACME01", "per_page": 10}
)
data = resp.json()
print(f"Found {data['total']} invoices")

# Get pricing for a SKU with customer-specific waterfall
price = requests.get(
    f"{BASE}/pricing/CLN-5000",
    headers=HEADERS,
    params={"customer_code": "ACME01"}
).json()
print(f"Price: ${price['price']} (source: {price['source']})")

# AI Chat: ask a business question in natural language
ai = requests.post(
    f"{BASE}/ai/conversations/1/message",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"message": "Top 5 customers by revenue this quarter"}
).json()
print(ai["answer"])
const BASE = "https://app.karvoerp.com/wp-json/se-erp/v2";
const API_KEY = "se_your_api_key_here";

const karvo = async (path, opts = {}) => {
  const res = await fetch(`${BASE}${path}`, {
    ...opts,
    headers: {
      "X-SE-ERP-Key": API_KEY,
      "Content-Type": "application/json",
      ...opts.headers,
    },
  });
  return res.json();
};

// List invoices
const invoices = await karvo("/invoices?customer_code=ACME01");
console.log(`Found ${invoices.total} invoices`);

// Create a shipment
const shipment = await karvo("/shipments", {
  method: "POST",
  body: JSON.stringify({
    invoice_no: "INV-2026-0042",
    customer_code: "ACME01",
    method: "delivery_run",
  }),
});
console.log(`Shipment #${shipment.id} created`);

// Check revenue analytics
const revenue = await karvo("/analytics/revenue?months=6");
console.log(revenue);

Response Format

All responses are JSON. Paginated endpoints return a standard envelope.

Paginated Response

// GET /invoices?page=2&per_page=25 { "data": [/* array of records */], "total": 1247, "page": 2, "per_page": 25, "total_pages": 50 }
FieldTypeDescription
dataarrayArray of resource objects
totalintegerTotal matching records
pageintegerCurrent page number
per_pageintegerItems per page (default 25, max 100)
total_pagesintegerTotal pages available

Error Response

// 422 Validation Error { "error": "customer_code is required" } // 429 Rate Limited { "error": "Rate limit exceeded" }
StatusMeaningDescription
200OKRequest succeeded
201CreatedResource created successfully
401UnauthorizedInvalid or missing API key
403ForbiddenInsufficient scope or resource access denied
404Not FoundResource does not exist
422UnprocessableValidation error (missing or invalid fields)
429Too ManyRate limit exceeded, retry after reset