---
title: "How to Integrate With the Campfire API"
description: "Campfire is an AI-native ERP for high-growth startups and mid-market companies. This guide covers 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."
author: "GJ"
published: "2026-03-14T12:00+01:00"
updated: "2026-03-16T08:51:48.137Z"
url: "https://www.apideck.com/blog/how-to-integrate-with-the-campfire-api"
category: "Accounting"
tags: ["Accounting", "Guides & Tutorials"]
---

# How to Integrate With the Campfire API

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 build an [Campfire Integration](https://www.apideck.com/blog/how-to-integrate-with-the-campfire-api "Campfire Integration") (and 30+ other accounting platforms).

## 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](https://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:

1. Log into your Campfire instance and go to **Settings > API Keys**
2. Click "Create User" and assign a role. The three roles determine access scope:
   - `admin` grants access to all API endpoints
   - `clerk` allows viewing all data and posting draft entries
   - `view only` restricts to GET endpoints
3. 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:

```json
{
  "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.

```bash
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.

```bash
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

```bash
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.

```bash
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:

```bash
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:

```bash
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.

```bash
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:

```bash
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.

```bash
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.

```bash
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.

```bash
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.

```bash
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.

```bash
# 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.

```bash
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.

```bash
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:

```bash
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:

```bash
# 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:

```json
{
  "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](https://www.apideck.com) 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

1. Sign up for Apideck and enable the Campfire connector in your dashboard
2. Use the pre-built [Vault](https://www.apideck.com/products/vault) component to let your users securely connect their Campfire account. Apideck handles credential storage.
3. Make API calls using the unified Accounting API

### Example: listing invoices

```javascript
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](https://docs.campfire.ai/quickstart) and the four workflow guides covering [accounts payable](https://docs.campfire.ai/guides/accounts-payable), [accounts receivable](https://docs.campfire.ai/guides/accounts-receivable), [journal entries](https://docs.campfire.ai/guides/journal-entries), and [MCP integration](https://docs.campfire.ai/guides/ai-integration).

For the unified API route, [sign up for Apideck](https://app.apideck.com/signup), enable the Campfire connector, and follow the [Accounting API docs](https://developers.apideck.com/apis/accounting/reference).