Getting Started
Panterra is an AI-native unified API platform spanning 13 verticals and 42 providers. Integrate once and connect to accounting software, CRMs, payment processors, e-commerce platforms, HRIS tools, ticketing systems, and more — all through a single, consistent REST API.
Every response uses a normalized schema so your application logic stays the same regardless of which provider your customer uses. Panterra also provides built-in anomaly detection, an AI query engine, a real-time sync layer, and an MCP server for AI agent access.
Quick start
- Sign up at the Panterra Dashboard and create an organization.
- Generate an API key from the dashboard. Keys start with
pt_. - Embed the Connect Widget in your app so your users can authorize their software systems.
- Make your first API call using the connection ID returned by the widget.
Base URL
https://api.panterra.io/v1
All endpoints are prefixed with /v1. Vertical data endpoints additionally
require a x-connection-id header identifying which connected account to query.
URL structure
Panterra organizes endpoints by vertical. Every vertical follows the same pattern:
/v1/{vertical}/{entity}
/v1/{vertical}/{entity}/:id
/v1/accounting/invoices
/v1/crm/contacts
/v1/payments/transactions
/v1/ecommerce/orders
/v1/hris/employees
Your first API call
const res = await fetch('https://api.panterra.io/v1/accounting/invoices', {
headers: {
'X-API-Key': 'pt_your_api_key',
'x-connection-id': 'your_connection_id',
},
});
const { data } = await res.json();
console.log(data); // Array of normalized invoice objects
pt_your_api_key with a real API key from your dashboard,
and your_connection_id with the ID returned after a user completes the Connect Widget flow.
Authentication
Panterra supports two authentication methods. You can use either one depending on your integration approach.
API Key authentication
The simplest method. Include your API key in the X-API-Key header on every request.
API keys are scoped to your organization and can be created from the dashboard or via the API.
X-API-Key: pt_your_api_key
JWT authentication
For session-based flows, sign in with email and password to receive a JSON Web Token.
Pass it in the Authorization header.
Authorization: Bearer <token>
Sign up
Creates a new user and organization. Returns the user object, organization, and a JWT token.
{
"email": "dev@acme.com",
"password": "a-strong-password",
"name": "Jane Doe",
"orgName": "Acme Corp"
}
{
"user": { "id": "usr_...", "email": "dev@acme.com", "name": "Jane Doe" },
"organization": { "id": "org_...", "name": "Acme Corp" },
"token": "eyJhbGciOiJIUzI1NiIs..."
}
Log in
Authenticates an existing user. Returns the same shape as sign up.
{
"email": "dev@acme.com",
"password": "a-strong-password"
}
Create API key
Requires authentication (JWT or existing API key). Creates a new API key for your organization. The full key value is returned only once in the response—store it securely.
Get current user
Returns the authenticated user and their organization details.
x-connection-id header in addition to your authentication
credentials. This header tells Panterra which connected system to query.
Connections
A connection represents the authorized link between your Panterra organization
and one of your customer's software systems. Each connection stores OAuth tokens, provider
metadata, and the vertical it belongs to. You reference connections by their ID in the
x-connection-id header for all data requests.
Supported providers
Panterra supports 42 providers across 13 verticals.
| Vertical | Providers | Auth |
|---|---|---|
| Accounting | QuickBooks, Xero, FreshBooks, Wave, Sage, NetSuite | OAuth 2.0 |
| CRM | Salesforce, HubSpot, Pipedrive | OAuth 2.0 |
| Payments | Stripe, Square, PayPal | OAuth 2.0 / API Key |
| E-commerce | Shopify, WooCommerce, BigCommerce | OAuth 2.0 |
| HRIS | BambooHR, Gusto, Rippling | OAuth 2.0 |
| Ticketing | Jira, Asana, Linear | OAuth 2.0 |
| Messaging | Slack, Microsoft Teams, Discord | OAuth 2.0 |
| Support | Zendesk, Intercom, Freshdesk | OAuth 2.0 / API Key |
| File Storage | Google Drive, Dropbox, Box | OAuth 2.0 |
| Analytics | Google Analytics, Mixpanel, Amplitude | OAuth 2.0 / API Key |
| Gmail, Outlook, SendGrid | OAuth 2.0 | |
| Scheduling | Calendly, Cal.com, Google Calendar | OAuth 2.0 |
| ATS | Greenhouse, Lever, Workday | OAuth 2.0 |
OAuth flow
To initiate a connection, redirect your user (or open a popup) to the provider's connect URL:
Replace {vertical} with the vertical slug (e.g. accounting, crm)
and {provider} with the provider slug (e.g. quickbooks, hubspot).
Panterra handles the full OAuth dance and redirects back to your configured callback URL with
the new connection ID. The Connect Widget wraps this flow in a drop-in UI.
List connections
Returns all active connections for your organization.
{
"data": [
{
"id": "conn_abc123",
"provider": "quickbooks",
"vertical": "accounting",
"status": "active",
"companyName": "Acme Corp",
"createdAt": "2026-01-15T08:30:00Z"
},
{
"id": "conn_def456",
"provider": "hubspot",
"vertical": "crm",
"status": "active",
"companyName": "Acme Corp",
"createdAt": "2026-02-10T14:00:00Z"
}
]
}
Delete a connection
Revokes the OAuth tokens and removes the connection. Cached data for this connection is purged. This action cannot be undone.
Connect Widget
The Connect Widget is a drop-in JavaScript component that handles the entire OAuth flow in a branded modal overlay. Your users pick their vertical and provider, authorize access in a popup window, and you receive the connection ID in a callback.
Installation
Add the script tag to your page:
<script src="https://panterra.io/connect.js"></script>
Usage
Panterra.connect({
apiKey: 'pt_your_api_key',
verticals: ['accounting', 'crm'], // optional: limit visible verticals
providers: ['quickbooks', 'hubspot'], // optional: limit visible providers
onSuccess: (connection) => {
console.log('Connected:', connection.id, connection.provider, connection.vertical);
// Store connection.id for future API calls
},
onError: (error) => {
console.error('Connection failed:', error.message);
},
onClose: () => {
console.log('Widget closed');
},
});
Options
| Option | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Your Panterra API key (starts with pt_). |
verticals | string[] | No | Limit which verticals are shown. Defaults to all. |
providers | string[] | No | Limit which providers are shown. Defaults to all supported providers. |
onSuccess | function | Yes | Called with the connection object on successful authorization. |
onError | function | No | Called with an error object if authorization fails. |
onClose | function | No | Called when the user closes the widget without completing. |
What happens behind the scenes
- The widget opens a modal overlay with the Panterra-branded vertical and provider picker.
- When the user selects a provider, a popup window navigates to the OAuth authorization URL.
- After the user authorizes, the popup closes and the modal receives the new connection details.
- Your
onSuccesscallback fires with the connection object containingid,provider, andvertical.
Provider Capabilities
Not every provider supports every entity type in its vertical. Panterra's capability system lets you discover what each provider supports before making API calls.
List all providers
Returns every supported provider grouped by vertical, including entity counts and auth types.
{
"data": [
{
"slug": "quickbooks",
"name": "QuickBooks Online",
"vertical": "accounting",
"authType": "oauth2",
"supportedEntities": ["invoices", "contacts", "payments", "items", "accounts", "bills", "expenses", "credit_notes", "bank_transactions", "purchase_orders", "journal_entries"]
},
{
"slug": "hubspot",
"name": "HubSpot",
"vertical": "crm",
"authType": "oauth2",
"supportedEntities": ["contacts", "companies", "deals", "activities", "pipelines", "notes"]
}
]
}
Get provider capabilities
Returns detailed per-entity capability information for a specific provider.
{
"provider": "quickbooks",
"vertical": "accounting",
"capabilities": {
"invoices": { "list": true, "get": true, "create": true, "update": true, "delete": false },
"contacts": { "list": true, "get": true, "create": true, "update": true, "delete": false },
"payments": { "list": true, "get": true, "create": true, "update": false, "delete": false },
"journal_entries": { "list": true, "get": true, "create": true, "update": false, "delete": false }
}
}
Handling unsupported entities
If you call an endpoint for an entity that the connected provider does not support, Panterra
returns a 501 Not Implemented response with a clear error message.
{
"statusCode": 501,
"error": "Not Implemented",
"message": "The provider 'wave' does not support 'purchase_orders'. Use GET /v1/providers/wave/capabilities to see supported entities."
}
Accounting
The accounting vertical provides a normalized interface to financial data from QuickBooks, Xero, FreshBooks, Wave, Sage, and NetSuite. Create, read, and update invoices, contacts, payments, and more through a single API.
Invoices
Query parameters
| Parameter | Type | Description |
|---|---|---|
cursor | string | Pagination cursor from a previous response. |
limit | number | Results per page (default 50, max 200). |
updated_since | ISO 8601 | Only return invoices updated after this timestamp. |
fresh | boolean | Bypass cache and fetch directly from the provider. |
detect_anomalies | boolean | Run inline anomaly detection on results. |
const res = await fetch('https://api.panterra.io/v1/accounting/invoices?limit=20', {
headers: {
'X-API-Key': apiKey,
'x-connection-id': connectionId,
},
});
const { data, cursor } = await res.json();
{
"contactId": "ct_abc123",
"dueDate": "2026-04-15",
"lineItems": [
{
"description": "Consulting services",
"quantity": 10,
"unitAmount": 150.00,
"accountId": "acc_revenue_01"
}
],
"memo": "March consulting engagement"
}
Invoice object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized invoice ID. |
remoteId | string | Original ID in the provider's system. |
invoiceNumber | string | Human-readable invoice number. |
contactId | string | Associated contact ID. |
contactName | string | Name of the associated contact. |
status | string | Normalized status: DRAFT, SENT, AUTHORIZED, PAID, PARTIAL, VOIDED, OVERDUE. |
issueDate | ISO 8601 | Date the invoice was issued. |
dueDate | ISO 8601 | Payment due date. |
currency | string | Three-letter currency code (e.g. USD). |
totalAmount | number | Total amount of the invoice. |
amountDue | number | Remaining balance due. |
amountPaid | number | Amount already paid. |
lineItems | array | Array of line item objects. |
memo | string | Internal memo or note. |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Contacts
const res = await fetch('https://api.panterra.io/v1/accounting/contacts', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Contact object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized contact ID. |
remoteId | string | Original ID in the provider's system. |
name | string | Full contact name. |
email | string | Primary email address. |
phone | string | Primary phone number. |
type | string | CUSTOMER, VENDOR, or BOTH. |
isActive | boolean | Whether the contact is active. |
balance | number | Outstanding balance (if available). |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Payments
{
"contactId": "ct_abc123",
"date": "2026-03-15",
"amount": 1500.00,
"currency": "USD",
"accountId": "acc_checking_01",
"allocations": [
{ "invoiceId": "inv_xyz789", "amount": 1500.00 }
],
"reference": "CHK-4521"
}
Payment object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized payment ID. |
remoteId | string | Original ID in the provider's system. |
contactId | string | ID of the payer/payee contact. |
date | ISO 8601 | Date the payment was made. |
amount | number | Total payment amount. |
currency | string | Three-letter currency code. |
accountId | string | Bank or financial account. |
reference | string | Check number, transaction reference, etc. |
allocations | array | Array of invoice allocation objects. |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Additional accounting endpoints
The following entities follow the same list/get/create/update pattern.
Items
Accounts (Chart of Accounts)
Bills
Expenses
Credit Notes
Bank Transactions
Purchase Orders
Journal Entries
CRM
The CRM vertical provides unified access to customer relationship data across Salesforce, HubSpot, and Pipedrive. Manage contacts, companies, deals, activities, and pipelines through a single interface.
Contacts
const res = await fetch('https://api.panterra.io/v1/crm/contacts', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
CRM Contact object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized contact ID. |
remoteId | string | Original ID in the provider's system. |
firstName | string | First name. |
lastName | string | Last name. |
email | string | Primary email address. |
phone | string | Primary phone number. |
companyId | string | Associated company ID. |
title | string | Job title. |
lifecycleStage | string | Lead, MQL, SQL, customer, etc. |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Deals
{
"id": "deal_abc123",
"remoteId": "9012345",
"name": "Acme Corp Enterprise",
"amount": 85000.00,
"currency": "USD",
"stage": "Proposal Sent",
"pipelineId": "pipe_main",
"contactId": "ct_xyz789",
"companyId": "comp_acme",
"probability": 60,
"expectedCloseDate": "2026-04-30",
"createdAt": "2026-02-01T10:00:00Z",
"updatedAt": "2026-03-15T14:30:00Z"
}
Additional CRM endpoints
Companies
Activities
Pipelines
Notes
Leads
Payments
The payments vertical provides unified access to payment processing data from Stripe, Square, and PayPal. Read transactions, manage customers, process refunds, and track payouts.
Transactions
const res = await fetch('https://api.panterra.io/v1/payments/transactions', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Transaction object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized transaction ID. |
remoteId | string | Original ID in the provider's system. |
amount | number | Transaction amount. |
currency | string | Three-letter currency code. |
status | string | SUCCEEDED, PENDING, FAILED, REFUNDED. |
customerId | string | Associated customer ID. |
paymentMethodType | string | CARD, BANK_TRANSFER, WALLET, etc. |
description | string | Transaction description. |
createdAt | ISO 8601 | Transaction timestamp. |
Customers
Customer object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized customer ID. |
remoteId | string | Original ID in the provider's system. |
name | string | Customer name. |
email | string | Email address. |
defaultPaymentMethod | string | Default payment method ID. |
createdAt | ISO 8601 | Record creation timestamp. |
Additional payments endpoints
Refunds
Payouts
Subscriptions
Payment Methods
Disputes
Balance
E-commerce
The e-commerce vertical connects to online stores and marketplaces via Shopify, WooCommerce, and BigCommerce. Manage products, orders, customers, collections, fulfillments, inventory, and discounts.
Products
const res = await fetch('https://api.panterra.io/v1/ecommerce/products', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Product object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized product ID. |
remoteId | string | Original ID in the provider's system. |
title | string | Product title. |
description | string | Product description (HTML or plain text). |
vendor | string | Product vendor or manufacturer. |
productType | string | Product type or category. |
status | string | ACTIVE, DRAFT, ARCHIVED. |
variants | array | Array of variant objects with price, SKU, inventory. |
images | array | Array of image URLs. |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Orders
{
"id": "ord_abc123",
"remoteId": "1001",
"orderNumber": "#1001",
"status": "FULFILLED",
"financialStatus": "PAID",
"customer": { "id": "cust_xyz", "email": "jane@acme.com" },
"totalAmount": 299.00,
"currency": "USD",
"lineItems": [
{ "productId": "prod_abc", "title": "Widget Pro", "quantity": 2, "price": 149.50 }
],
"shippingAddress": { "city": "Austin", "state": "TX", "country": "US" },
"createdAt": "2026-03-15T10:30:00Z"
}
Additional e-commerce endpoints
Customers
Collections
Fulfillments
Inventory
Discounts
HRIS
The HRIS vertical provides unified access to human resources data from BambooHR, Gusto, and Rippling. Manage employee records, departments, time off, compensation, payroll, benefits, and office locations.
Employees
const res = await fetch('https://api.panterra.io/v1/hris/employees', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Employee object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized employee ID. |
remoteId | string | Original ID in the provider's system. |
firstName | string | First name. |
lastName | string | Last name. |
email | string | Work email address. |
title | string | Job title. |
departmentId | string | Associated department ID. |
managerId | string | Manager's employee ID. |
status | string | ACTIVE, TERMINATED, ON_LEAVE. |
startDate | ISO 8601 | Employment start date. |
terminationDate | ISO 8601 | Termination date (if applicable). |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Additional HRIS endpoints
Departments
Time Off
Compensation
Payroll
Benefits
Locations
Ticketing
The ticketing vertical connects to project management and issue tracking systems including Jira, Asana, and Linear. Manage projects, tickets, comments, sprints, and attachments.
Tickets
const res = await fetch('https://api.panterra.io/v1/ticketing/tickets', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Ticket object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized ticket ID. |
remoteId | string | Original ID in the provider's system. |
title | string | Ticket title or summary. |
description | string | Ticket description or body. |
status | string | OPEN, IN_PROGRESS, DONE, CANCELLED. |
priority | string | URGENT, HIGH, MEDIUM, LOW, NONE. |
projectId | string | Associated project ID. |
assigneeId | string | Assigned user ID. |
sprintId | string | Associated sprint ID (if applicable). |
tags | string[] | Array of tags or labels. |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Additional ticketing endpoints
Projects
Comments
Users
Sprints
Attachments
Messaging
The messaging vertical connects to team communication platforms including Slack, Microsoft Teams, and Discord. Read channels, messages, and user information.
Channels
const res = await fetch('https://api.panterra.io/v1/messaging/channels', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Channel object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized channel ID. |
remoteId | string | Original ID in the provider's system. |
name | string | Channel name. |
description | string | Channel topic or description. |
type | string | PUBLIC, PRIVATE, DIRECT. |
memberCount | number | Number of members. |
createdAt | ISO 8601 | Channel creation timestamp. |
Messages
Users
Support
The support vertical connects to customer support platforms including Zendesk, Intercom, and Freshdesk. Manage support tickets, contacts, conversations, and knowledge base articles.
Tickets
const res = await fetch('https://api.panterra.io/v1/support/tickets', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Support Ticket object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized ticket ID. |
remoteId | string | Original ID in the provider's system. |
subject | string | Ticket subject line. |
description | string | Ticket body or initial message. |
status | string | NEW, OPEN, PENDING, SOLVED, CLOSED. |
priority | string | URGENT, HIGH, NORMAL, LOW. |
contactId | string | Customer/requester ID. |
assigneeId | string | Assigned agent ID. |
tags | string[] | Array of tags. |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Additional support endpoints
Contacts
Conversations
Articles (Knowledge Base)
File Storage
The file storage vertical connects to cloud storage platforms including Google Drive, Dropbox, and Box. Browse, read, and manage files and folders.
Files
const res = await fetch('https://api.panterra.io/v1/filestorage/files?folderId=folder_root', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
File object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized file ID. |
remoteId | string | Original ID in the provider's system. |
name | string | File name. |
mimeType | string | MIME type of the file. |
size | number | File size in bytes. |
folderId | string | Parent folder ID. |
downloadUrl | string | Temporary download URL. |
createdAt | ISO 8601 | File creation timestamp. |
updatedAt | ISO 8601 | Last modification timestamp. |
Folders
Analytics
The analytics vertical connects to product analytics and web analytics platforms including Google Analytics, Mixpanel, and Amplitude. Pull reports and event data.
Reports
const res = await fetch('https://api.panterra.io/v1/analytics/reports?startDate=2026-03-01&endDate=2026-03-18', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Events
The email vertical connects to email platforms including Gmail, Outlook, and SendGrid. Read and send messages, manage threads, and work with contact lists.
Messages
const res = await fetch('https://api.panterra.io/v1/email/messages?limit=20', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Email Message object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized message ID. |
remoteId | string | Original ID in the provider's system. |
subject | string | Email subject line. |
from | object | Sender (email, name). |
to | array | Array of recipient objects. |
cc | array | CC recipients. |
body | string | Email body (HTML or plain text). |
threadId | string | Parent thread ID. |
isRead | boolean | Whether the message has been read. |
sentAt | ISO 8601 | Send timestamp. |
Threads
Contact Lists
Scheduling
The scheduling vertical connects to appointment and calendar tools including Calendly, Cal.com, and Google Calendar. Manage event types, bookings, and availability windows.
Event Types
const res = await fetch('https://api.panterra.io/v1/scheduling/event-types', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Event Type object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized event type ID. |
remoteId | string | Original ID in the provider's system. |
name | string | Event type name (e.g. "30-min Discovery Call"). |
description | string | Event type description. |
duration | number | Duration in minutes. |
isActive | boolean | Whether the event type is bookable. |
bookingUrl | string | Public booking URL. |
createdAt | ISO 8601 | Record creation timestamp. |
Bookings
Availability
ATS
The ATS (Applicant Tracking System) vertical connects to recruiting platforms including Greenhouse, Lever, and Workday. Manage candidates, jobs, applications, and interviews.
Candidates
const res = await fetch('https://api.panterra.io/v1/ats/candidates', {
headers: { 'X-API-Key': apiKey, 'x-connection-id': connectionId },
});
const { data } = await res.json();
Candidate object fields
| Field | Type | Description |
|---|---|---|
id | string | Panterra-normalized candidate ID. |
remoteId | string | Original ID in the provider's system. |
firstName | string | First name. |
lastName | string | Last name. |
email | string | Email address. |
phone | string | Phone number. |
currentCompany | string | Current employer. |
currentTitle | string | Current job title. |
resumeUrl | string | URL to resume file. |
tags | string[] | Tags or labels. |
createdAt | ISO 8601 | Record creation timestamp. |
updatedAt | ISO 8601 | Last update timestamp. |
Jobs
{
"id": "job_abc123",
"remoteId": "4567",
"title": "Senior Backend Engineer",
"departmentId": "dept_eng",
"status": "OPEN",
"hiringManagerId": "emp_jane",
"location": "Remote",
"employmentType": "FULL_TIME",
"postedAt": "2026-02-15T09:00:00Z",
"createdAt": "2026-02-10T08:00:00Z"
}
Additional ATS endpoints
Applications
Interviews
Anomaly Detection
Panterra provides a three-layer anomaly detection system that automatically identifies suspicious patterns in accounting data. Each layer adds increasing intelligence:
- Deterministic layer — Rule-based checks for known red flags (duplicate invoices, missing fields, negative amounts, round-number patterns).
- Statistical layer — Z-score and IQR-based outlier detection on amounts, frequencies, and timing patterns.
- LLM layer — AI-powered contextual analysis that identifies subtle anomalies a rules engine would miss.
Run a scan
Query parameters
| Parameter | Type | Description |
|---|---|---|
layers | string | Comma-separated list: deterministic, statistical, llm. Defaults to all three. |
entity_types | string | Comma-separated: invoice, payment. Defaults to all. |
{
"anomalies": [
{
"id": "anom_001",
"type": "DUPLICATE_INVOICE",
"severity": "critical",
"entityType": "invoice",
"entityId": "inv_abc123",
"description": "Invoice #1042 appears to be a duplicate of #1041",
"layer": "deterministic",
"status": "open",
"detectedAt": "2026-03-17T12:00:00Z"
}
],
"summary": {
"total": 12,
"critical": 2,
"warning": 7,
"info": 3
}
}
List anomalies
Query parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: open, resolved, dismissed. |
severity | string | Filter by severity: critical, warning, info. |
Resolve an anomaly
Marks the anomaly as resolved. Use this after the underlying issue has been corrected.
Dismiss an anomaly
Marks the anomaly as dismissed (false positive or intentional).
Inline detection
You can enable anomaly detection on any accounting list endpoint by adding ?detect_anomalies=true
as a query parameter. This runs the deterministic layer against the returned results
and includes any findings in the response.
GET /v1/accounting/invoices?detect_anomalies=true
Anomaly types
| Type | Severity | Description |
|---|---|---|
DUPLICATE_INVOICE | critical | Two invoices with matching amounts, dates, and contacts. |
LINE_ITEM_MISMATCH | warning | Line item totals do not sum to the invoice total. |
OUTLIER_AMOUNT | warning | Amount is a statistical outlier for this contact or category. |
UNUSUAL_TIMING | info | Transaction occurred outside normal business patterns. |
ROUND_NUMBER | info | Suspiciously round amount that may indicate estimation. |
MISSING_REFERENCE | warning | Payment lacks an invoice allocation or reference. |
DUPLICATE_PAYMENT | critical | Potential duplicate payment to the same contact. |
NEGATIVE_AMOUNT | warning | Unexpected negative amount on a receivable or payable. |
STALE_DRAFT | info | Invoice has been in DRAFT status for an unusually long time. |
CONTEXTUAL | varies | LLM-detected anomaly based on broader context analysis. |
AI Queries
The AI query endpoint lets you ask natural-language questions about your connected data. Panterra uses an LLM agent with access to your data across all connected verticals to generate answers, pulling real figures from your business systems.
Ask a question
Requires both authentication and the x-connection-id header.
{
"question": "What are my top 5 overdue invoices?"
}
{
"question": "What are my top 5 overdue invoices?",
"answer": "Here are your top 5 overdue invoices by amount:\n\n1. INV-1089 — $12,500.00 (Acme Corp, 45 days overdue)\n2. INV-1076 — $8,200.00 (Global Supplies, 30 days overdue)\n...",
"toolsUsed": ["list_invoices", "list_contacts"]
}
Example questions
- "What are my top 5 overdue invoices?"
- "Show me revenue this month"
- "Which customers have outstanding balances over $10,000?"
- "Compare this quarter's expenses to last quarter"
- "Are there any duplicate invoices?"
- "Summarize payments received this week"
- "How many open deals are in the pipeline?"
- "What is our employee headcount by department?"
ANTHROPIC_API_KEY configured
on the Panterra server. Self-hosted deployments must provide their own key.
Sync Engine
Panterra maintains a local cache of your data for fast reads. Instead of hitting the provider's API on every request (which can take 300-500ms), cached reads return in approximately 10ms. The sync engine keeps this cache fresh through multiple strategies.
How sync works
- Background sync — Every 5 minutes, Panterra pulls incremental updates from the provider for each active connection.
- Webhook-triggered — When a provider supports outbound webhooks, changes are synced in near real-time.
- Write-through — When you create or update data through Panterra, the write goes directly to the provider and the cache is updated immediately.
- On-demand — Add
?fresh=trueto any read endpoint to bypass the cache and fetch directly from the provider.
View sync status
Returns the sync state for each entity type per connection.
{
"connectionId": "conn_abc123",
"vertical": "accounting",
"entities": {
"invoices": {
"lastSyncAt": "2026-03-17T11:55:00Z",
"status": "synced",
"recordCount": 1247
},
"contacts": {
"lastSyncAt": "2026-03-17T11:55:00Z",
"status": "synced",
"recordCount": 342
},
"payments": {
"lastSyncAt": "2026-03-17T11:55:00Z",
"status": "syncing",
"recordCount": 891
}
}
}
Trigger a manual sync
Requires the x-connection-id header. Starts an immediate sync for all entity
types on the specified connection. Returns 202 Accepted as the sync runs
asynchronously.
?fresh=true query parameter for one-off fresh reads.
Reserve manual sync triggers for situations where you need the entire cache refreshed,
such as after a bulk import in the provider's system.
Webhooks
Subscribe to real-time notifications when data changes in connected systems. Panterra sends HTTP POST requests to your endpoint with event payloads.
Create a webhook subscription
{
"url": "https://your-app.com/webhooks/panterra",
"events": ["accounting.invoice.*", "crm.deal.updated", "payments.transaction.created"]
}
{
"id": "wh_abc123",
"url": "https://your-app.com/webhooks/panterra",
"events": ["accounting.invoice.*", "crm.deal.updated", "payments.transaction.created"],
"secret": "whsec_a1b2c3d4e5f6...",
"active": true,
"createdAt": "2026-03-17T12:00:00Z"
}
secret is shown only once in the create response.
Store it securely — you will need it to verify webhook signatures.
List webhook subscriptions
View delivery history
Returns a list of recent delivery attempts with status codes and timestamps.
Delete a webhook
Event patterns
Events follow the pattern {vertical}.{entity}.{action}.
| Pattern | Description |
|---|---|
accounting.invoice.created | New invoice detected. |
accounting.invoice.updated | Invoice was modified. |
accounting.invoice.deleted | Invoice was deleted. |
accounting.invoice.* | All invoice events. |
accounting.contact.* | All accounting contact events. |
accounting.payment.* | All payment events. |
accounting.anomaly.detected | New anomaly found during sync. |
crm.contact.* | All CRM contact events. |
crm.deal.* | All deal events. |
payments.transaction.* | All payment transaction events. |
ecommerce.order.* | All e-commerce order events. |
hris.employee.* | All employee events. |
ticketing.ticket.* | All ticketing events. |
{vertical}.* | All events for a given vertical. |
* | Subscribe to all events. |
Signature verification
Every webhook delivery includes an X-Panterra-Signature header containing an
HMAC-SHA256 signature of the request body using your webhook secret. Always verify this
signature before processing the payload.
import { createHmac } from 'crypto';
function verifyWebhook(body: string, signature: string, secret: string): boolean {
const expected = createHmac('sha256', secret)
.update(body)
.digest('hex');
return signature === expected;
}
Retry policy
If your endpoint returns a non-2xx status code or fails to respond within 10 seconds, Panterra retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 30 seconds |
| 2nd retry | 2 minutes |
| 3rd retry | 8 minutes |
| 4th retry | 32 minutes |
| 5th retry | 2 hours |
After 5 failed retries the delivery is marked as failed. Check the delivery history endpoint to diagnose issues.
MCP Server
Panterra includes a Model Context Protocol (MCP) server, enabling AI assistants like Claude to interact directly with your business data across all verticals. The server exposes tools that an LLM can call to read and write data.
Transport options
Panterra supports two MCP transport modes:
Stdio (local)
Run the MCP server as a local process that communicates over stdin/stdout. Ideal for Claude Desktop and other local AI tools.
PANTERRA_API_KEY=pt_xxx node dist/mcp/start-mcp.js
HTTP (remote)
Send MCP protocol messages over HTTP for remote or server-side integrations.
Include your API key via the x-api-key header.
Available tools
| Tool | Description |
|---|---|
list_connections | List all connected systems across verticals. |
list_invoices | List invoices with optional filters. |
get_invoice | Get a single invoice by ID. |
create_invoice | Create a new invoice. |
list_contacts | List contacts (accounting or CRM). |
get_contact | Get a single contact by ID. |
create_contact | Create a new contact. |
list_payments | List payments with optional filters. |
get_payment | Get a single payment by ID. |
create_payment | Create a new payment. |
list_items | List items/products. |
list_accounts | List chart of accounts. |
list_deals | List CRM deals. |
list_orders | List e-commerce orders. |
list_employees | List HRIS employees. |
list_tickets | List ticketing tickets. |
scan_anomalies | Run anomaly detection scan. |
get_sync_status | View sync status per entity type. |
ai_query | Ask a natural-language question about the data. |
Read-only mode
For safety, you can restrict the MCP server to read-only operations by setting the environment variable:
PANTERRA_MCP_MODE=readonly
In read-only mode, all write tools (create_*) are disabled.
Claude Desktop configuration
Add the following to your Claude Desktop claude_desktop_config.json file
to connect Panterra as an MCP server:
{
"mcpServers": {
"panterra": {
"command": "node",
"args": ["path/to/panterra-api/dist/mcp/start-mcp.js"],
"env": {
"PANTERRA_API_KEY": "pt_your_api_key"
}
}
}
}
SDKs
Official client libraries make it easy to integrate Panterra into your application. Both SDKs provide typed interfaces, automatic pagination, and error handling across all 13 verticals.
TypeScript / JavaScript
npm install @panterra/sdk
import { PanterraClient } from '@panterra/sdk';
const client = new PanterraClient({ apiKey: 'pt_your_api_key' });
// Accounting: List invoices
const invoices = await client.accounting.invoices.list('conn_abc123');
// CRM: List deals
const deals = await client.crm.deals.list('conn_def456');
// E-commerce: List orders
const orders = await client.ecommerce.orders.list('conn_ghi789');
// Auto-paginate through all invoices
for await (const inv of client.accounting.invoices.listAll('conn_abc123')) {
console.log(inv.invoiceNumber, inv.totalAmount);
}
// Create an invoice
const newInvoice = await client.accounting.invoices.create('conn_abc123', {
contactId: 'ct_abc123',
dueDate: '2026-04-15',
lineItems: [
{ description: 'Consulting', quantity: 10, unitAmount: 150 },
],
});
Python
pip install panterra
from panterra import PanterraClient
client = PanterraClient(api_key="pt_your_api_key")
# Accounting: List invoices
invoices = client.accounting.invoices.list("conn_abc123")
# CRM: List deals
deals = client.crm.deals.list("conn_def456")
# E-commerce: List orders
orders = client.ecommerce.orders.list("conn_ghi789")
# Auto-paginate through all invoices
for inv in client.accounting.invoices.list_all("conn_abc123"):
print(inv.invoice_number, inv.total_amount)
# Create an invoice
new_invoice = client.accounting.invoices.create(
"conn_abc123",
contact_id="ct_abc123",
due_date="2026-04-15",
line_items=[
{"description": "Consulting", "quantity": 10, "unit_amount": 150},
],
)
API Reference
For the complete auto-generated API reference with request/response schemas for all 13 verticals, visit the interactive API Reference page powered by Swagger/OpenAPI.
Back to top