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

  1. Sign up at the Panterra Dashboard and create an organization.
  2. Generate an API key from the dashboard. Keys start with pt_.
  3. Embed the Connect Widget in your app so your users can authorize their software systems.
  4. Make your first API call using the connection ID returned by the widget.

Base URL

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:

Pattern
/v1/{vertical}/{entity}
/v1/{vertical}/{entity}/:id
Examples
/v1/accounting/invoices
/v1/crm/contacts
/v1/payments/transactions
/v1/ecommerce/orders
/v1/hris/employees

Your first API call

TypeScript
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
Note: Replace 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.

HTTP Header
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.

HTTP Header
Authorization: Bearer <token>

Sign up

POST /v1/auth/signup

Creates a new user and organization. Returns the user object, organization, and a JWT token.

JSON — Request Body
{
  "email": "dev@acme.com",
  "password": "a-strong-password",
  "name": "Jane Doe",
  "orgName": "Acme Corp"
}
JSON — Response
{
  "user": { "id": "usr_...", "email": "dev@acme.com", "name": "Jane Doe" },
  "organization": { "id": "org_...", "name": "Acme Corp" },
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

Log in

POST /v1/auth/login

Authenticates an existing user. Returns the same shape as sign up.

JSON — Request Body
{
  "email": "dev@acme.com",
  "password": "a-strong-password"
}

Create API key

POST /v1/auth/keys

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

GET /v1/auth/me

Returns the authenticated user and their organization details.

Heads up: All vertical data endpoints (invoices, contacts, transactions, etc.) also require the 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.

VerticalProvidersAuth
AccountingQuickBooks, Xero, FreshBooks, Wave, Sage, NetSuiteOAuth 2.0
CRMSalesforce, HubSpot, PipedriveOAuth 2.0
PaymentsStripe, Square, PayPalOAuth 2.0 / API Key
E-commerceShopify, WooCommerce, BigCommerceOAuth 2.0
HRISBambooHR, Gusto, RipplingOAuth 2.0
TicketingJira, Asana, LinearOAuth 2.0
MessagingSlack, Microsoft Teams, DiscordOAuth 2.0
SupportZendesk, Intercom, FreshdeskOAuth 2.0 / API Key
File StorageGoogle Drive, Dropbox, BoxOAuth 2.0
AnalyticsGoogle Analytics, Mixpanel, AmplitudeOAuth 2.0 / API Key
EmailGmail, Outlook, SendGridOAuth 2.0
SchedulingCalendly, Cal.com, Google CalendarOAuth 2.0
ATSGreenhouse, Lever, WorkdayOAuth 2.0

OAuth flow

To initiate a connection, redirect your user (or open a popup) to the provider's connect URL:

GET /v1/{vertical}/{provider}/connect?api_key=pt_xxx

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

GET /v1/connections

Returns all active connections for your organization.

JSON — Response
{
  "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

DELETE /v1/connections/:id

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:

HTML
<script src="https://panterra.io/connect.js"></script>

Usage

JavaScript
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

OptionTypeRequiredDescription
apiKeystringYesYour Panterra API key (starts with pt_).
verticalsstring[]NoLimit which verticals are shown. Defaults to all.
providersstring[]NoLimit which providers are shown. Defaults to all supported providers.
onSuccessfunctionYesCalled with the connection object on successful authorization.
onErrorfunctionNoCalled with an error object if authorization fails.
onClosefunctionNoCalled when the user closes the widget without completing.

What happens behind the scenes

  1. The widget opens a modal overlay with the Panterra-branded vertical and provider picker.
  2. When the user selects a provider, a popup window navigates to the OAuth authorization URL.
  3. After the user authorizes, the popup closes and the modal receives the new connection details.
  4. Your onSuccess callback fires with the connection object containing id, provider, and vertical.

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

GET /v1/providers

Returns every supported provider grouped by vertical, including entity counts and auth types.

JSON — Response
{
  "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

GET /v1/providers/:provider/capabilities

Returns detailed per-entity capability information for a specific provider.

JSON — Response
{
  "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.

JSON — 501 Response
{
  "statusCode": 501,
  "error": "Not Implemented",
  "message": "The provider 'wave' does not support 'purchase_orders'. Use GET /v1/providers/wave/capabilities to see supported entities."
}
Tip: Query the capabilities endpoint during onboarding to tailor your UI based on what the connected provider actually supports. This prevents your users from encountering 501 errors.

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.

QuickBooks Xero FreshBooks Wave Sage NetSuite

Invoices

GET /v1/accounting/invoices

Query parameters

ParameterTypeDescription
cursorstringPagination cursor from a previous response.
limitnumberResults per page (default 50, max 200).
updated_sinceISO 8601Only return invoices updated after this timestamp.
freshbooleanBypass cache and fetch directly from the provider.
detect_anomaliesbooleanRun inline anomaly detection on results.
TypeScript
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();
GET /v1/accounting/invoices/:id
POST /v1/accounting/invoices
JSON — Request Body
{
  "contactId": "ct_abc123",
  "dueDate": "2026-04-15",
  "lineItems": [
    {
      "description": "Consulting services",
      "quantity": 10,
      "unitAmount": 150.00,
      "accountId": "acc_revenue_01"
    }
  ],
  "memo": "March consulting engagement"
}
PATCH /v1/accounting/invoices/:id

Invoice object fields

FieldTypeDescription
idstringPanterra-normalized invoice ID.
remoteIdstringOriginal ID in the provider's system.
invoiceNumberstringHuman-readable invoice number.
contactIdstringAssociated contact ID.
contactNamestringName of the associated contact.
statusstringNormalized status: DRAFT, SENT, AUTHORIZED, PAID, PARTIAL, VOIDED, OVERDUE.
issueDateISO 8601Date the invoice was issued.
dueDateISO 8601Payment due date.
currencystringThree-letter currency code (e.g. USD).
totalAmountnumberTotal amount of the invoice.
amountDuenumberRemaining balance due.
amountPaidnumberAmount already paid.
lineItemsarrayArray of line item objects.
memostringInternal memo or note.
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Contacts

GET /v1/accounting/contacts
TypeScript
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();
GET /v1/accounting/contacts/:id
POST /v1/accounting/contacts
PATCH /v1/accounting/contacts/:id

Contact object fields

FieldTypeDescription
idstringPanterra-normalized contact ID.
remoteIdstringOriginal ID in the provider's system.
namestringFull contact name.
emailstringPrimary email address.
phonestringPrimary phone number.
typestringCUSTOMER, VENDOR, or BOTH.
isActivebooleanWhether the contact is active.
balancenumberOutstanding balance (if available).
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Payments

GET /v1/accounting/payments
GET /v1/accounting/payments/:id
POST /v1/accounting/payments
JSON — Request Body
{
  "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

FieldTypeDescription
idstringPanterra-normalized payment ID.
remoteIdstringOriginal ID in the provider's system.
contactIdstringID of the payer/payee contact.
dateISO 8601Date the payment was made.
amountnumberTotal payment amount.
currencystringThree-letter currency code.
accountIdstringBank or financial account.
referencestringCheck number, transaction reference, etc.
allocationsarrayArray of invoice allocation objects.
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Additional accounting endpoints

The following entities follow the same list/get/create/update pattern.

Items

GET /v1/accounting/items
GET /v1/accounting/items/:id
POST /v1/accounting/items
PATCH /v1/accounting/items/:id

Accounts (Chart of Accounts)

GET /v1/accounting/accounts
GET /v1/accounting/accounts/:id

Bills

GET /v1/accounting/bills
GET /v1/accounting/bills/:id
POST /v1/accounting/bills
PATCH /v1/accounting/bills/:id

Expenses

GET /v1/accounting/expenses
GET /v1/accounting/expenses/:id
POST /v1/accounting/expenses

Credit Notes

GET /v1/accounting/credit-notes
GET /v1/accounting/credit-notes/:id
POST /v1/accounting/credit-notes

Bank Transactions

GET /v1/accounting/bank-transactions
GET /v1/accounting/bank-transactions/:id

Purchase Orders

GET /v1/accounting/purchase-orders
GET /v1/accounting/purchase-orders/:id
POST /v1/accounting/purchase-orders

Journal Entries

GET /v1/accounting/journal-entries
GET /v1/accounting/journal-entries/:id
POST /v1/accounting/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.

Salesforce HubSpot Pipedrive

Contacts

GET /v1/crm/contacts
TypeScript
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();
GET /v1/crm/contacts/:id
POST /v1/crm/contacts
PATCH /v1/crm/contacts/:id

CRM Contact object fields

FieldTypeDescription
idstringPanterra-normalized contact ID.
remoteIdstringOriginal ID in the provider's system.
firstNamestringFirst name.
lastNamestringLast name.
emailstringPrimary email address.
phonestringPrimary phone number.
companyIdstringAssociated company ID.
titlestringJob title.
lifecycleStagestringLead, MQL, SQL, customer, etc.
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Deals

GET /v1/crm/deals
JSON — Response (single deal)
{
  "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"
}
GET /v1/crm/deals/:id
POST /v1/crm/deals
PATCH /v1/crm/deals/:id

Additional CRM endpoints

Companies

GET /v1/crm/companies
GET /v1/crm/companies/:id
POST /v1/crm/companies
PATCH /v1/crm/companies/:id

Activities

GET /v1/crm/activities
GET /v1/crm/activities/:id
POST /v1/crm/activities

Pipelines

GET /v1/crm/pipelines
GET /v1/crm/pipelines/:id

Notes

GET /v1/crm/notes
POST /v1/crm/notes

Leads

GET /v1/crm/leads
GET /v1/crm/leads/:id
POST /v1/crm/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.

Stripe Square PayPal

Transactions

GET /v1/payments/transactions
TypeScript
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();
GET /v1/payments/transactions/:id

Transaction object fields

FieldTypeDescription
idstringPanterra-normalized transaction ID.
remoteIdstringOriginal ID in the provider's system.
amountnumberTransaction amount.
currencystringThree-letter currency code.
statusstringSUCCEEDED, PENDING, FAILED, REFUNDED.
customerIdstringAssociated customer ID.
paymentMethodTypestringCARD, BANK_TRANSFER, WALLET, etc.
descriptionstringTransaction description.
createdAtISO 8601Transaction timestamp.

Customers

GET /v1/payments/customers
GET /v1/payments/customers/:id
POST /v1/payments/customers

Customer object fields

FieldTypeDescription
idstringPanterra-normalized customer ID.
remoteIdstringOriginal ID in the provider's system.
namestringCustomer name.
emailstringEmail address.
defaultPaymentMethodstringDefault payment method ID.
createdAtISO 8601Record creation timestamp.

Additional payments endpoints

Refunds

GET /v1/payments/refunds
GET /v1/payments/refunds/:id
POST /v1/payments/refunds

Payouts

GET /v1/payments/payouts
GET /v1/payments/payouts/:id

Subscriptions

GET /v1/payments/subscriptions
GET /v1/payments/subscriptions/:id
POST /v1/payments/subscriptions

Payment Methods

GET /v1/payments/payment-methods
GET /v1/payments/payment-methods/:id

Disputes

GET /v1/payments/disputes
GET /v1/payments/disputes/:id

Balance

GET /v1/payments/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.

Shopify WooCommerce BigCommerce

Products

GET /v1/ecommerce/products
TypeScript
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();
GET /v1/ecommerce/products/:id
POST /v1/ecommerce/products
PATCH /v1/ecommerce/products/:id

Product object fields

FieldTypeDescription
idstringPanterra-normalized product ID.
remoteIdstringOriginal ID in the provider's system.
titlestringProduct title.
descriptionstringProduct description (HTML or plain text).
vendorstringProduct vendor or manufacturer.
productTypestringProduct type or category.
statusstringACTIVE, DRAFT, ARCHIVED.
variantsarrayArray of variant objects with price, SKU, inventory.
imagesarrayArray of image URLs.
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Orders

GET /v1/ecommerce/orders
JSON — Response (single order)
{
  "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"
}
GET /v1/ecommerce/orders/:id

Additional e-commerce endpoints

Customers

GET /v1/ecommerce/customers
GET /v1/ecommerce/customers/:id

Collections

GET /v1/ecommerce/collections
GET /v1/ecommerce/collections/:id

Fulfillments

GET /v1/ecommerce/fulfillments
GET /v1/ecommerce/fulfillments/:id
POST /v1/ecommerce/fulfillments

Inventory

GET /v1/ecommerce/inventory
PATCH /v1/ecommerce/inventory/:id

Discounts

GET /v1/ecommerce/discounts
GET /v1/ecommerce/discounts/:id
POST /v1/ecommerce/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.

BambooHR Gusto Rippling

Employees

GET /v1/hris/employees
TypeScript
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();
GET /v1/hris/employees/:id
POST /v1/hris/employees

Employee object fields

FieldTypeDescription
idstringPanterra-normalized employee ID.
remoteIdstringOriginal ID in the provider's system.
firstNamestringFirst name.
lastNamestringLast name.
emailstringWork email address.
titlestringJob title.
departmentIdstringAssociated department ID.
managerIdstringManager's employee ID.
statusstringACTIVE, TERMINATED, ON_LEAVE.
startDateISO 8601Employment start date.
terminationDateISO 8601Termination date (if applicable).
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Additional HRIS endpoints

Departments

GET /v1/hris/departments
GET /v1/hris/departments/:id

Time Off

GET /v1/hris/time-off
GET /v1/hris/time-off/:id
POST /v1/hris/time-off

Compensation

GET /v1/hris/compensation
GET /v1/hris/compensation/:id

Payroll

GET /v1/hris/payroll
GET /v1/hris/payroll/:id

Benefits

GET /v1/hris/benefits
GET /v1/hris/benefits/:id

Locations

GET /v1/hris/locations
GET /v1/hris/locations/:id

Ticketing

The ticketing vertical connects to project management and issue tracking systems including Jira, Asana, and Linear. Manage projects, tickets, comments, sprints, and attachments.

Jira Asana Linear

Tickets

GET /v1/ticketing/tickets
TypeScript
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();
GET /v1/ticketing/tickets/:id
POST /v1/ticketing/tickets
PATCH /v1/ticketing/tickets/:id

Ticket object fields

FieldTypeDescription
idstringPanterra-normalized ticket ID.
remoteIdstringOriginal ID in the provider's system.
titlestringTicket title or summary.
descriptionstringTicket description or body.
statusstringOPEN, IN_PROGRESS, DONE, CANCELLED.
prioritystringURGENT, HIGH, MEDIUM, LOW, NONE.
projectIdstringAssociated project ID.
assigneeIdstringAssigned user ID.
sprintIdstringAssociated sprint ID (if applicable).
tagsstring[]Array of tags or labels.
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Additional ticketing endpoints

Projects

GET /v1/ticketing/projects
GET /v1/ticketing/projects/:id

Comments

GET /v1/ticketing/comments
POST /v1/ticketing/comments

Users

GET /v1/ticketing/users
GET /v1/ticketing/users/:id

Sprints

GET /v1/ticketing/sprints
GET /v1/ticketing/sprints/:id

Attachments

GET /v1/ticketing/attachments
POST /v1/ticketing/attachments

Messaging

The messaging vertical connects to team communication platforms including Slack, Microsoft Teams, and Discord. Read channels, messages, and user information.

Slack Microsoft Teams Discord

Channels

GET /v1/messaging/channels
TypeScript
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();
GET /v1/messaging/channels/:id

Channel object fields

FieldTypeDescription
idstringPanterra-normalized channel ID.
remoteIdstringOriginal ID in the provider's system.
namestringChannel name.
descriptionstringChannel topic or description.
typestringPUBLIC, PRIVATE, DIRECT.
memberCountnumberNumber of members.
createdAtISO 8601Channel creation timestamp.

Messages

GET /v1/messaging/messages
GET /v1/messaging/messages/:id
POST /v1/messaging/messages

Users

GET /v1/messaging/users
GET /v1/messaging/users/:id

Support

The support vertical connects to customer support platforms including Zendesk, Intercom, and Freshdesk. Manage support tickets, contacts, conversations, and knowledge base articles.

Zendesk Intercom Freshdesk

Tickets

GET /v1/support/tickets
TypeScript
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();
GET /v1/support/tickets/:id
POST /v1/support/tickets
PATCH /v1/support/tickets/:id

Support Ticket object fields

FieldTypeDescription
idstringPanterra-normalized ticket ID.
remoteIdstringOriginal ID in the provider's system.
subjectstringTicket subject line.
descriptionstringTicket body or initial message.
statusstringNEW, OPEN, PENDING, SOLVED, CLOSED.
prioritystringURGENT, HIGH, NORMAL, LOW.
contactIdstringCustomer/requester ID.
assigneeIdstringAssigned agent ID.
tagsstring[]Array of tags.
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Additional support endpoints

Contacts

GET /v1/support/contacts
GET /v1/support/contacts/:id

Conversations

GET /v1/support/conversations
GET /v1/support/conversations/:id
POST /v1/support/conversations

Articles (Knowledge Base)

GET /v1/support/articles
GET /v1/support/articles/:id

File Storage

The file storage vertical connects to cloud storage platforms including Google Drive, Dropbox, and Box. Browse, read, and manage files and folders.

Google Drive Dropbox Box

Files

GET /v1/filestorage/files
TypeScript
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();
GET /v1/filestorage/files/:id

File object fields

FieldTypeDescription
idstringPanterra-normalized file ID.
remoteIdstringOriginal ID in the provider's system.
namestringFile name.
mimeTypestringMIME type of the file.
sizenumberFile size in bytes.
folderIdstringParent folder ID.
downloadUrlstringTemporary download URL.
createdAtISO 8601File creation timestamp.
updatedAtISO 8601Last modification timestamp.

Folders

GET /v1/filestorage/folders
GET /v1/filestorage/folders/:id
POST /v1/filestorage/folders

Analytics

The analytics vertical connects to product analytics and web analytics platforms including Google Analytics, Mixpanel, and Amplitude. Pull reports and event data.

Google Analytics Mixpanel Amplitude

Reports

GET /v1/analytics/reports
TypeScript
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();
GET /v1/analytics/reports/:id

Events

GET /v1/analytics/events
GET /v1/analytics/events/:id

Email

The email vertical connects to email platforms including Gmail, Outlook, and SendGrid. Read and send messages, manage threads, and work with contact lists.

Gmail Outlook SendGrid

Messages

GET /v1/email/messages
TypeScript
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();
GET /v1/email/messages/:id
POST /v1/email/messages

Email Message object fields

FieldTypeDescription
idstringPanterra-normalized message ID.
remoteIdstringOriginal ID in the provider's system.
subjectstringEmail subject line.
fromobjectSender (email, name).
toarrayArray of recipient objects.
ccarrayCC recipients.
bodystringEmail body (HTML or plain text).
threadIdstringParent thread ID.
isReadbooleanWhether the message has been read.
sentAtISO 8601Send timestamp.

Threads

GET /v1/email/threads
GET /v1/email/threads/:id

Contact Lists

GET /v1/email/contact-lists
GET /v1/email/contact-lists/:id
POST /v1/email/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.

Calendly Cal.com Google Calendar

Event Types

GET /v1/scheduling/event-types
TypeScript
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();
GET /v1/scheduling/event-types/:id

Event Type object fields

FieldTypeDescription
idstringPanterra-normalized event type ID.
remoteIdstringOriginal ID in the provider's system.
namestringEvent type name (e.g. "30-min Discovery Call").
descriptionstringEvent type description.
durationnumberDuration in minutes.
isActivebooleanWhether the event type is bookable.
bookingUrlstringPublic booking URL.
createdAtISO 8601Record creation timestamp.

Bookings

GET /v1/scheduling/bookings
GET /v1/scheduling/bookings/:id
POST /v1/scheduling/bookings

Availability

GET /v1/scheduling/availability

ATS

The ATS (Applicant Tracking System) vertical connects to recruiting platforms including Greenhouse, Lever, and Workday. Manage candidates, jobs, applications, and interviews.

Greenhouse Lever Workday

Candidates

GET /v1/ats/candidates
TypeScript
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();
GET /v1/ats/candidates/:id
POST /v1/ats/candidates

Candidate object fields

FieldTypeDescription
idstringPanterra-normalized candidate ID.
remoteIdstringOriginal ID in the provider's system.
firstNamestringFirst name.
lastNamestringLast name.
emailstringEmail address.
phonestringPhone number.
currentCompanystringCurrent employer.
currentTitlestringCurrent job title.
resumeUrlstringURL to resume file.
tagsstring[]Tags or labels.
createdAtISO 8601Record creation timestamp.
updatedAtISO 8601Last update timestamp.

Jobs

GET /v1/ats/jobs
JSON — Response (single job)
{
  "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"
}
GET /v1/ats/jobs/:id

Additional ATS endpoints

Applications

GET /v1/ats/applications
GET /v1/ats/applications/:id
POST /v1/ats/applications

Interviews

GET /v1/ats/interviews
GET /v1/ats/interviews/:id
POST /v1/ats/interviews

Anomaly Detection

Panterra provides a three-layer anomaly detection system that automatically identifies suspicious patterns in accounting data. Each layer adds increasing intelligence:

  1. Deterministic layer — Rule-based checks for known red flags (duplicate invoices, missing fields, negative amounts, round-number patterns).
  2. Statistical layer — Z-score and IQR-based outlier detection on amounts, frequencies, and timing patterns.
  3. LLM layer — AI-powered contextual analysis that identifies subtle anomalies a rules engine would miss.

Run a scan

POST /v1/accounting/anomalies/scan

Query parameters

ParameterTypeDescription
layersstringComma-separated list: deterministic, statistical, llm. Defaults to all three.
entity_typesstringComma-separated: invoice, payment. Defaults to all.
JSON — Response
{
  "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

GET /v1/accounting/anomalies

Query parameters

ParameterTypeDescription
statusstringFilter by status: open, resolved, dismissed.
severitystringFilter by severity: critical, warning, info.

Resolve an anomaly

PATCH /v1/accounting/anomalies/:id/resolve

Marks the anomaly as resolved. Use this after the underlying issue has been corrected.

Dismiss an anomaly

PATCH /v1/accounting/anomalies/:id/dismiss

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.

HTTP
GET /v1/accounting/invoices?detect_anomalies=true

Anomaly types

TypeSeverityDescription
DUPLICATE_INVOICEcriticalTwo invoices with matching amounts, dates, and contacts.
LINE_ITEM_MISMATCHwarningLine item totals do not sum to the invoice total.
OUTLIER_AMOUNTwarningAmount is a statistical outlier for this contact or category.
UNUSUAL_TIMINGinfoTransaction occurred outside normal business patterns.
ROUND_NUMBERinfoSuspiciously round amount that may indicate estimation.
MISSING_REFERENCEwarningPayment lacks an invoice allocation or reference.
DUPLICATE_PAYMENTcriticalPotential duplicate payment to the same contact.
NEGATIVE_AMOUNTwarningUnexpected negative amount on a receivable or payable.
STALE_DRAFTinfoInvoice has been in DRAFT status for an unusually long time.
CONTEXTUALvariesLLM-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

POST /v1/ai/query

Requires both authentication and the x-connection-id header.

JSON — Request Body
{
  "question": "What are my top 5 overdue invoices?"
}
JSON — Response
{
  "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?"
Note: The AI query feature requires an 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=true to any read endpoint to bypass the cache and fetch directly from the provider.

View sync status

GET /v1/sync/status

Returns the sync state for each entity type per connection.

JSON — Response
{
  "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

POST /v1/sync/trigger

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.

Tip: Use the ?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

POST /v1/webhooks
JSON — Request Body
{
  "url": "https://your-app.com/webhooks/panterra",
  "events": ["accounting.invoice.*", "crm.deal.updated", "payments.transaction.created"]
}
JSON — Response
{
  "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"
}
Important: The secret is shown only once in the create response. Store it securely — you will need it to verify webhook signatures.

List webhook subscriptions

GET /v1/webhooks

View delivery history

GET /v1/webhooks/:id/deliveries

Returns a list of recent delivery attempts with status codes and timestamps.

Delete a webhook

DELETE /v1/webhooks/:id

Event patterns

Events follow the pattern {vertical}.{entity}.{action}.

PatternDescription
accounting.invoice.createdNew invoice detected.
accounting.invoice.updatedInvoice was modified.
accounting.invoice.deletedInvoice was deleted.
accounting.invoice.*All invoice events.
accounting.contact.*All accounting contact events.
accounting.payment.*All payment events.
accounting.anomaly.detectedNew 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.

TypeScript
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:

AttemptDelay
1st retry30 seconds
2nd retry2 minutes
3rd retry8 minutes
4th retry32 minutes
5th retry2 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.

Bash
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.

POST /v1/mcp

Include your API key via the x-api-key header.

Available tools

ToolDescription
list_connectionsList all connected systems across verticals.
list_invoicesList invoices with optional filters.
get_invoiceGet a single invoice by ID.
create_invoiceCreate a new invoice.
list_contactsList contacts (accounting or CRM).
get_contactGet a single contact by ID.
create_contactCreate a new contact.
list_paymentsList payments with optional filters.
get_paymentGet a single payment by ID.
create_paymentCreate a new payment.
list_itemsList items/products.
list_accountsList chart of accounts.
list_dealsList CRM deals.
list_ordersList e-commerce orders.
list_employeesList HRIS employees.
list_ticketsList ticketing tickets.
scan_anomaliesRun anomaly detection scan.
get_sync_statusView sync status per entity type.
ai_queryAsk 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:

Bash
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:

JSON
{
  "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

Bash
npm install @panterra/sdk
Note: The TypeScript SDK is not yet published to npm. For now, install from source or contact us for early access.
TypeScript
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

Bash
pip install panterra
Note: The Python SDK is not yet published to PyPI. Contact us for early access.
Python
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