Skip to main content

Companies API

Merge duplicate companies through POST /api/v1/companies/:id/merge, including what moves, permissions and MCP merge_companies.

Written by Ben Walker

List and show companies with GET /api/v1/companies and GET /api/v1/companies/:id (see Reference data API). This page covers the merge write. All endpoints sit under /api/v1/ and need an account-scoped bearer token. See API authentication, permissions and rate limits.

POST /api/v1/companies/:id/merge

Merges duplicate companies into the company :id, then soft-deletes the duplicates. Clients and suppliers can both be merged. The web merge modal and the MCP tool merge_companies run the same operation, so all three surfaces apply the same rules.

The request needs api_create (the POST verb) and api_delete, because the merged companies are deleted. The record permissions are update_companies and delete_companies. A company the token user cannot read returns 404.

Field

Meaning

source_company_ids

Array of the duplicate company ids. Required. May be sent flat or nested under merge

POST /api/v1/companies/812/merge
{"source_company_ids": [815, 816]}

What moves

  • Projects and opportunities whose client, invoice-to company or referrer is a duplicate, deleted ones included

  • Contracts whose primary contractor is a duplicate

  • Invoices that are not yet approved and not synced

  • Costs, purchase orders, expense claim items and staff credit cards. An expense claim item and its costs move together only when none of them is synced to finance

Records already synced to Xero, MYOB or QuickBooks keep their company, because the company is sent to the accounting software and a change would be pushed there. Approved invoices keep the company they were issued to. Contacts, addresses, notes, custom fields and finance_id stay on the deleted duplicates.

The kept company becomes both when the merge brings both sides together. A kept company that becomes the client of a moved project or opportunity also gets the account's client status (and a client number or code, when the account uses them). A referrer or invoice-to link alone changes neither.

After a merge, a project cannot be newly linked to a merged (deleted) company as its client, invoice-to company or referrer. Such a write is refused with a validation error on every surface. Projects that already point at a deleted company can still be edited.

Everything runs in one transaction. A failed merge changes nothing.

Response (200)

{
"company": {"id": 812, "trading_name": "Acme Pty Ltd", "company_type": "both"},
"merged_companies": [
{"id": 815, "trading_name": "Acme", "discarded_at": "2026-09-25T04:10:00.000Z"},
{"id": 816, "trading_name": "ACME Pty Ltd", "discarded_at": "2026-09-25T04:10:00.000Z"}
],
"moved": {
"projects": 4,
"invoices": 1,
"contracts": 0,
"costs": 12,
"purchase_orders": 2,
"expense_claim_items": 0,
"staff_credit_cards": 0
}
}

company has the same fields as GET /companies/:id.

Errors

Status

code

When

422

missing_input

source_company_ids is empty or missing

422

invalid_input

An id is not a number, or the company is in its own source_company_ids

422

company_deleted

The company :id is deleted. Restore it first

422

source_company_deleted

A source company is already deleted

404

company_not_found

The company :id does not exist in the account or the user cannot read it (field: company_id), or a source company does not (field: source_company_ids)

403

A missing verb permission ({"error": "Insufficient API permissions"})

403

not_authorized

The user lacks update_companies or delete_companies

Did this answer your question?