Campfire is an AI-native ERP platform built for high-growth startups and mid-market companies that are outgrowing QuickBooks or Xero, or looking for a modern alternative to NetSuite and Sage Intacct. Founded in 2023 and backed by Accel, Ribbit, Foundation Capital, Y Combinator, and Capital49, it offers a general ledger with multi-entity and multi-currency support, revenue recognition, invoicing, close management, and bank reconciliation. The company raised a $35M Series A led by Accel in June 2025, followed by a $65M Series B co-led by Accel and Ribbit just 12 weeks later, bringing total funding past $100M.
If you're building a product that needs to sync accounting data with Campfire, this guide covers two approaches: integrating directly with the Campfire API, and using a unified API like Apideck to connect to Campfire (and 30+ other accounting platforms) through a single integration.
What the Campfire API covers
Campfire exposes a REST API organized around its core accounting workflows. The base URL for all requests is https://api.meetcampfire.com, and the full API reference lives at docs.campfire.ai.
The API is split across several resource groups:
Cash management covers bank accounts and bank transactions. You can list, create, update, and delete bank accounts, manage individual bank transactions with full CRUD support, and push bank feed data for reconciliation.
Accounts payable handles bills, debit memos, and payment workflows. Beyond basic CRUD, it includes endpoints for marking bills as paid, voiding bills, reopening voided bills, and bulk searching bills by number.
Accounts receivable includes invoices, credit memos, and payment recording. It supports bulk invoice creation, bulk search by invoice number, voiding, and reopening voided invoices.
Core accounting covers journal entries (single-entity and intercompany), budgets, fixed assets, chart transactions, vendor contacts, and custom dimensions. It also includes bulk search endpoints for departments, vendors, and custom dimensions.
Financial statements gives programmatic access to income statements, balance sheets, cash flow statements, trial balances, general ledger data, comparative statements, and cash-basis variants of income and operating statements.
Revenue recognition handles contracts, subscriptions, milestones, usage-based revenue, products, bundles, and bundle allocations. You can create, modify, duplicate, and terminate contracts.
Company objects include chart of accounts, departments, vendors, custom fields, custom dimensions (and dimension groups), cost allocations, and fixed asset classes.
Settings cover entity management, file uploads, currency configuration, and exchange rates.
Integrations provide webhook management for event-driven sync.
Bank reconciliation includes reconciliation report management, GL transaction listing for reconciliation, and bulk matching of GL transactions to statement transactions.
Authentication
Campfire uses static API key authentication. To get set up:
- Log into your Campfire instance and go to Settings > API Keys
- Click "Create User" and assign a role. The three roles determine access scope:
admingrants access to all API endpointsclerkallows viewing all data and posting draft entriesview onlyrestricts to GET endpoints
- Click "Create API Key" on the user. Copy the key immediately since it's only shown once.
Include the token in every request:
Authorization: Token YOUR_API_KEY
There is no OAuth flow for the API itself (though Campfire does support MCP-based integration for AI tools, covered later).
API conventions
Before jumping into examples, a few things about how the API behaves.
Endpoint paths vary by resource group. Bank accounts live under /ca/api/account, bills under /ca/api/v1/bill, invoices under /ca/api/v1/invoice, journal entries under /ca/api/journal, and webhooks under /integrations/api/v1/webhook. There isn't a single prefix convention, so check the API reference for each resource.
Pagination uses limit and offset query parameters. Paginated responses return a count, a results array, and next/previous URLs:
{
"count": 142,
"results": [...],
"next": "https://api.meetcampfire.com/ca/api/account?offset=100&limit=100",
"previous": null
}
Incremental sync is supported through last_modified_at__gte and last_modified_at__lte filters (ISO 8601 format). Most list endpoints also support an include_deleted parameter. When set to true, it returns only deleted records (not active ones) with is_deleted=true and a deleted_at timestamp. When false or omitted, you get only active records. This toggle-based design gives you clean separation between active and deleted data, which is useful for maintaining data consistency across systems.
Object references are numeric IDs. When creating bills, invoices, or journal entries, you first need to look up the IDs of related objects (entities, accounts, vendors, departments, custom dimensions) through their respective list endpoints.
Multi-currency is handled through a two-tier exchange rate model: exchange_rate_book (between the transaction currency and the entity's book currency) and exchange_rate (between the entity currency and the consolidation currency). Both can be auto-computed if omitted.
Direct integration examples
Listing entities
Multi-entity support is core to Campfire. You need entity IDs for nearly every write operation, so this is often the first call an integration makes.
curl --request GET \
--url https://api.meetcampfire.com/ca/api/entity \
--header 'Authorization: Token YOUR_API_KEY'
The response includes parent-child relationships, currencies, and exchange rate configuration per entity. There's also a dedicated endpoint for listing entities available for intercompany journal entries.
Listing the chart of accounts
Account IDs are required for bills, journal entries, and most write operations.
curl --request GET \
--url 'https://api.meetcampfire.com/ca/api/v1/chart_accounts?limit=100' \
--header 'Authorization: Token YOUR_API_KEY'
You can filter by account type and subtype to narrow results. There's also a separate endpoint for income statement accounts specifically.
Listing bank accounts
curl --request GET \
--url https://api.meetcampfire.com/ca/api/account \
--header 'Authorization: Token YOUR_API_KEY'
Supports sorting by most returned fields (prefix with - for descending, e.g. ?ordering=-current_balance), and filtering by chart_of_accounts_account to find bank accounts linked to a specific GL account.
Creating a vendor
Before you can create bills, you need vendor records. This is a common first step when syncing supplier data from an external system.
curl --request POST \
--url https://api.meetcampfire.com/ca/api/vendor \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"name": "Acme Cloud Services",
"email": "billing@acme.example.com",
"currency": "USD",
"payment_terms": "net_30"
}'
Use the bulk search endpoint (POST /ca/api/v1/vendor/bulk_search) to look up vendors by external ID or name, which is useful for matching records during initial sync.
Creating a bill
Bills require references to existing entities, vendors, and expense accounts. Fetch those first, then assemble the bill:
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/bill \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"terms": "net_30",
"bill_date": "2025-07-01",
"due_date": "2025-08-25",
"lines": [
{
"account": "180564",
"amount": 10000,
"description": "Monthly SaaS subscription",
"department": "35",
"tags": [{"id": "8114"}]
}
],
"entity": "5",
"currency": "USD",
"vendor": "34182",
"bill_number": "098765",
"item_date": "2025-07-01",
"mailing_address": "1234 Main St. San Francisco CA"
}'
Key fields on bills: terms accepts values like net_7, net_10, net_15, net_20, net_30, net_40, net_45, net_60, net_90, net_105, net_120, or due_on_receipt. Each line item references an account (the expense account), and can optionally include a department, tags (custom dimension field IDs), and bill_customer for cost center tracking.
Recording a bill payment
Payments in Campfire work through a transaction-based model. You don't simply mark a bill as paid with an amount. You reference an existing journal entry transaction (either one you created or one you found via the list transactions endpoint) and apply it to the bill:
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/bill/{bill_id}/mark_as_paid \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"transactions": [
{
"transaction_id": 21069178,
"account_id": "2550",
"amount": 8999.99
}
]
}'
If the payment doesn't use the full amount of the referenced transaction, Campfire creates a new journal line for the remainder. You can apply multiple transactions to a single bill in one call.
Creating an invoice
Invoices use a different set of reference objects than bills. They require a client (not vendor), a product, and an entity. Optionally, you can link to a revenue recognition contract.
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/invoice \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"terms": "net_30",
"invoice_date": "2025-07-01",
"due_date": "2025-07-31",
"lines": [
{
"service_date": "2025-07-01",
"amount": 300,
"product": "3560",
"rate": 15,
"quantity": 20,
"description": "API usage - July 2025",
"tax": 12
}
],
"entity": "54",
"currency": "USD",
"client": "24020",
"invoice_number": "INV-2025-001",
"billing_address": "456 Commerce Ave, New York NY",
"period_start": "2025-07-01",
"period_end": "2025-07-31",
"contract": "24899"
}'
Invoice line items have product, rate, quantity, and tax fields, which differ from bill line items that use account and a flat amount. The contract field ties the invoice to a revenue recognition contract for ASC 606 compliance.
For high-volume scenarios, use the bulk create endpoint (POST /ca/api/v1/invoice/bulk_create) to submit multiple invoices in a single request.
Recording an invoice payment
Invoice payments follow the same transaction-based pattern as bill payments:
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/invoice/{invoice_id}/mark_as_paid \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"transactions": [
{
"transaction_id": 21069200,
"account_id": "2550",
"amount": 300
}
]
}'
Same mechanics as bill payments: reference an existing journal transaction, and Campfire handles the remainder if the payment is partial. You can also void an invoice payment without voiding the invoice itself using the /void_payment endpoint.
Creating a credit memo
Credit memos are the AR counterpart to debit memos on the AP side. They follow a similar structure to invoices.
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/credit_memo \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"credit_memo_date": "2025-07-15",
"lines": [
{
"amount": 150,
"product": "3560",
"description": "Overpayment refund"
}
],
"entity": "54",
"currency": "USD",
"client": "24020"
}'
Credit memos have their own void, reopen, and "mark as used" lifecycle, similar to invoices.
Bulk searching invoices by number
When reconciling against an external system, you often need to look up invoices by their number rather than iterating through pages.
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/invoice/bulk_search \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"invoice_numbers": ["INV-2025-001", "INV-2025-002", "INV-2025-003"]
}'
The same pattern exists for bills (/ca/api/v1/bill/bulk_search), credit memos, and debit memos.
Posting a journal entry
Journal entries require balanced debit and credit transactions. Each transaction line must have either its debit amounts or credit amounts set, never both.
curl --request POST \
--url https://api.meetcampfire.com/ca/api/journal \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"date": "2025-08-01",
"type": "journal_entry",
"transactions": [
{
"account": "180564",
"debit_amount_native": 1000,
"bank_description": "Monthly rent expense",
"vendor": "34182",
"department": "3613",
"tags": [{"id": "7737"}]
},
{
"account": "8856",
"credit_amount_native": 1000,
"bank_description": "Monthly rent expense",
"department": "3436",
"tags": [{"id": "8330"}]
}
],
"memo": "August 2025 rent",
"entity": "54",
"currency": "USD"
}'
You only need to set debit_amount_native or credit_amount_native. The _book and consolidation amounts are auto-computed from your exchange rates if omitted. Including a reversal_date in the request body will automatically post a reversing journal on that date.
Posting an intercompany journal entry
Intercompany JEs have two key differences from standard journal entries: each transaction line specifies its own entity, and the request includes a top-level entities object with exchange rates for every entity involved.
curl --request POST \
--url https://api.meetcampfire.com/ca/api/intercompany_journal \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"date": "2025-07-01",
"type": "journal_entry",
"transactions": [
{
"entity": 54,
"account": "180564",
"debit_amount_native": 1000,
"debit_amount_book": 1000,
"debit_amount": 1000,
"bank_description": "Interco services - US entity"
},
{
"entity": 5,
"account": "7409",
"credit_amount_native": 1000,
"credit_amount_book": 728.33,
"credit_amount": 1000,
"bank_description": "Interco services - EU entity"
},
{
"entity": 5,
"account": "7405",
"debit_amount_native": 1000,
"debit_amount_book": 728.33,
"debit_amount": 1000,
"bank_description": "Interco elimination - EU"
},
{
"entity": 54,
"account": "8856",
"credit_amount_native": 1000,
"credit_amount_book": 1000,
"credit_amount": 1000,
"bank_description": "Interco elimination - US"
}
],
"memo": "Intercompany services Q3 2025",
"currency": "USD",
"entities": {
"5": {
"id": 5,
"exchange_rate": 1.373,
"exchange_rate_book": 0.728332
},
"54": {
"id": 54,
"exchange_rate": 1,
"exchange_rate_book": 1
}
}
}'
The entities object is keyed by entity ID and contains the exchange rates for each entity. This is how Campfire handles multi-currency consolidation for groups with subsidiaries in different reporting currencies.
Pulling financial statements
The financial statements endpoints return structured report data without requiring any write operations.
# Income statement
curl --request GET \
--url 'https://api.meetcampfire.com/ca/api/income_statement?start_date=2025-01-01&end_date=2025-03-31' \
--header 'Authorization: Token YOUR_API_KEY'
# Balance sheet
curl --request GET \
--url 'https://api.meetcampfire.com/ca/api/balance_sheet?as_of_date=2025-03-31' \
--header 'Authorization: Token YOUR_API_KEY'
# Trial balance
curl --request GET \
--url 'https://api.meetcampfire.com/ca/api/trial_balance?as_of_date=2025-03-31' \
--header 'Authorization: Token YOUR_API_KEY'
# Cash flow statement
curl --request GET \
--url 'https://api.meetcampfire.com/ca/api/cash_flow?start_date=2025-01-01&end_date=2025-03-31' \
--header 'Authorization: Token YOUR_API_KEY'
Campfire also supports cash-basis variants of the income and operating statements for companies that need both accrual and cash-basis reporting, as well as comparative income statements and comparative balance sheets for period-over-period analysis.
Pulling the general ledger
For detailed transaction-level reporting, the general ledger endpoint returns individual GL entries rather than summarized financial statements.
curl --request GET \
--url 'https://api.meetcampfire.com/ca/api/general_ledger?start_date=2025-01-01&end_date=2025-03-31' \
--header 'Authorization: Token YOUR_API_KEY'
This is useful for building custom reports or feeding data into a BI tool where you need line-level detail rather than aggregated statement data.
Posting a bank feed
For banking and fintech integrations, you can push transaction data directly into a bank account.
curl --request POST \
--url https://api.meetcampfire.com/ca/api/account/{account_id}/bank_feed \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"transactions": [
{
"date": "2025-07-15",
"amount": -2500.00,
"description": "Wire transfer to vendor",
"reference": "WT-20250715-001"
}
]
}'
This is the endpoint you'd use if you're building a banking integration that feeds transactions into Campfire for reconciliation.
Setting up webhooks
Rather than polling for changes, you can subscribe to events and receive push notifications:
curl --request POST \
--url https://api.meetcampfire.com/integrations/api/v1/webhook \
--header 'Authorization: Token YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"url": "https://your-app.com/webhooks/campfire",
"topics": [{"name": "invoice.created"}, {"name": "bill.updated"}],
"active": true
}'
Use GET /integrations/api/v1/webhook/events to list all available webhook topics. Each webhook includes a token field you can use to verify incoming payloads.
Voiding and reopening
Both bills and invoices support a void/reopen lifecycle that preserves audit trails:
# Void a bill
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/bill/{bill_id}/void \
--header 'Authorization: Token YOUR_API_KEY'
# Reopen a voided bill
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/bill/{bill_id}/reopen_voided \
--header 'Authorization: Token YOUR_API_KEY'
# Void an invoice
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/invoice/{invoice_id}/void \
--header 'Authorization: Token YOUR_API_KEY'
# Void an invoice payment (without voiding the invoice itself)
curl --request POST \
--url https://api.meetcampfire.com/ca/api/v1/invoice/{invoice_id}/void_payment \
--header 'Authorization: Token YOUR_API_KEY'
This matters for integration builders because you need to handle these state transitions in your sync logic. A voided bill or invoice isn't deleted; it stays in the system with its status changed.
MCP server for AI integrations
Campfire also exposes an MCP (Model Context Protocol) server, which is worth knowing about if you're building AI-powered workflows on top of accounting data.
The MCP server provides 12 tools covering chart of accounts, transactions, entities, vendors, departments, tags, income statements, balance sheets, cash flow, budgets, contracts, and aging reports. It authenticates with the same API token.
Configuration for Claude Desktop:
{
"mcpServers": {
"Campfire": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.meetcampfire.com/mcp",
"--header",
"Authorization:Token YOUR_API_TOKEN"
]
}
}
}
For Cursor and VS Code, the server URL is https://api.campfire.com/mcp (note: different domain from the Claude Desktop config, which uses api.meetcampfire.com) with the token passed in headers. This enables natural language queries against your Campfire data, like pulling income statements or searching transactions without writing API calls.
Challenges of integrating directly
Campfire's API is well-structured and modern, but building a direct integration still involves the typical costs:
Auth management. API keys need to be stored securely for each customer connection, and there's no OAuth flow, so you're managing static credentials.
Data model specifics. Bills use vendor, invoices use client. Payment recording requires referencing journal transactions rather than just posting an amount. Exchange rates have a two-tier model. These are all reasonable design choices, but they mean your integration code is tightly coupled to Campfire's data model.
Maintenance overhead. The API is actively evolving. Endpoint paths don't follow a single convention (some use /ca/api/, others /ca/api/v1/, webhooks use /integrations/api/v1/), so keeping up with changes requires ongoing attention.
Single-provider coverage. If your customers also use QuickBooks, Xero, NetSuite, Sage, FreshBooks, or any of the dozens of other accounting platforms, you need to build and maintain each integration separately.
Integrating with Campfire through Apideck
Apideck provides a unified Accounting API that normalizes data across 30+ accounting platforms, including Campfire. You write one integration and get coverage across all of them.
How it works
- Sign up for Apideck and enable the Campfire connector in your dashboard
- Use the pre-built Vault component to let your users securely connect their Campfire account. Apideck handles credential storage.
- Make API calls using the unified Accounting API
Example: listing invoices
import { Apideck } from '@apideck/node'
const apideck = new Apideck({
apiKey: process.env.APIDECK_API_KEY,
appId: process.env.APIDECK_APP_ID,
consumerId: 'user-123'
})
const { data } = await apideck.accounting.invoicesAll({
serviceId: 'campfire'
})
console.log(`Found ${data.length} invoices`)
The same code works for QuickBooks, Xero, NetSuite, FreshBooks, Exact, and every other connector in the Accounting category. Only the serviceId changes.
What Apideck normalizes
Through the unified API, Campfire data is mapped to 18+ standardized data models including invoices, bills, payments, customers, suppliers, ledger accounts, journal entries, tax rates, bank accounts, and balance sheet reports. You also get webhook support across all connected providers, official SDKs for Node.js, Python, TypeScript, PHP, and Go, and a pre-built auth component so you don't need to build credential management.
When to use which approach
Go direct if Campfire is the only accounting platform you need to support, you need access to Campfire-specific features like intercompany journal entries with multi-entity exchange rate handling, revenue recognition contracts, or bank reconciliation, or you're building an internal tool for a single Campfire instance.
Use Apideck if your product needs to connect to multiple accounting platforms, you want to ship your Campfire integration in days instead of weeks, or you're a vertical SaaS, fintech, or embedded finance platform where multi-provider accounting connectivity is a product requirement.
Getting started
For direct integration, start with the Campfire API quickstart and the four workflow guides covering accounts payable, accounts receivable, journal entries, and MCP integration.
For the unified API route, sign up for Apideck, enable the Campfire connector, and follow the Accounting API docs.
Ready to get started?
Scale your integration strategy and deliver the integrations your customers need in record time.







