ByteChef LogoByteChef
Embedded

Unified API

One normalized, provider-agnostic REST schema across many CRM and Accounting providers — integrate once, support many.

The Unified API is a normalized REST layer that gives you a single schema across many third-party providers in the same category. Instead of learning HubSpot's account model, then Pipedrive's, then Xero's, you write against one ByteChef account shape and ByteChef translates every request and response to whichever provider your connected user actually connected.

Why a unified API

An embedded product that supports "CRM" usually means supporting five CRMs, each with its own object model, field names, pagination scheme, and auth. The Unified API collapses that fan-out:

  • Integrate once. Build your feature against the unified account (or contact, opportunity, …) model. Adding a new provider in the same category requires no code change on your side.
  • Provider-agnostic. The same request works whether the connected user is on HubSpot, Pipedrive, or Xero — ByteChef maps unified fields to the provider's fields and back.
  • Connected-user scoped. Every call runs against the calling connected user's own connection, so you never handle provider credentials directly.

Under the hood the Unified API is built on the same component connectors that power everything else in Embedded. Each supporting provider component ships a mapping between its native model and the unified model; the Unified API sits on top of those component connections and does the translation for you.

Enterprise Edition, feature-flagged

The Unified API is an Enterprise Edition surface and is gated behind a deployment feature flag. When the flag is enabled, the Unified API categories also appear as filters on the Integrations list.

Categories and models

The Unified API is organized into categories (a domain such as CRM or Accounting) and, within each category, a catalog of normalized models (common objects). The category model catalogs are:

CategoryModels
CRMaccount, contact, lead, opportunity, engagement, note, task, user
Accountingaccount, contact, address, attachment, company_info, credit_note, expense, balance_sheet, cash_flow_statement, and more

Currently exposed endpoints

The model catalogs above define the normalized schema. The REST endpoints wired today are the Account resource in both the CRM and Accounting categories. Additional model endpoints follow the same request/response contract as they are enabled.

Provider coverage today includes HubSpot and Pipedrive (CRM) and Xero (Accounting). Because the mapping lives in each provider component, coverage grows as more components implement the unified mapping — with no change to your integration code.

Base path and endpoint shape

All Unified API endpoints live under the embedded API, namespaced by category:

/api/embedded/v1/unified/{category}

{category} is crm or accounting. Each resource exposes standard REST operations. For the Account resource:

MethodPathOperationSuccess
POST/accountsCreate an account200 with { "id": "..." }
GET/accounts/{account_id}Get a single account200 with the account object
GET/accountsList accounts (paginated)200 with a page slice
PATCH/accounts/{account_id}Update an account204 No Content

Full example paths:

GET   /api/embedded/v1/unified/crm/accounts
POST  /api/embedded/v1/unified/crm/accounts
GET   /api/embedded/v1/unified/accounting/accounts/{account_id}

Authentication

Every request is authenticated as a connected user with a bearer token:

Authorization: Bearer <connected-user-token>

The token resolves the calling connected user; ByteChef then selects that user's integration instance and connection for the target category and runs the operation against the provider they connected. A caller can never reach another connected user's connection — an x-instance-id that does not belong to the resolved connected user is rejected. See connected users and tenant-isolated security.

Request headers

HeaderRequiredDescription
AuthorizationYesBearer <connected-user-token> — identifies the connected user.
X-EnvironmentNoTarget environment: TEST or PRODUCTION.
x-instance-idNoThe integration instance ID identifying the connected user's specific integration instance. When omitted, ByteChef picks the connected user's integration instance for the requested category.

Common query parameters

ParameterApplies toDescription
include_raw_dataGET account, GET accountsWhen true, includes the untranslated raw payload from the third-party provider alongside the unified fields (remoteData).
sizeGET accountsNumber of items to return per page.
sortGET accountsField to sort by.
directionGET accountsSort direction.
continuationTokenGET accountsOpaque cursor for the next page (see Pagination).

Pagination

List endpoints use cursor-based pagination. A list response is a page slice:

FieldTypeDescription
contentarrayThe list of unified objects for this page.
hasNextbooleanWhether another page is available.
sizeintegerThe requested page size.
continuationTokenstring / nullCursor to fetch the next page. null when there is no next page.

To page forward, pass the continuationToken from one response as the continuationToken query parameter of the next request:

GET /api/embedded/v1/unified/crm/accounts?size=50
GET /api/embedded/v1/unified/crm/accounts?size=50&continuationToken=<token-from-previous-response>

The continuation token encodes the query filter it was issued for. Changing the sort or direction while paging with a token is rejected — start a fresh page (drop the token) whenever you change the filter.

Example: create an account

Request:

POST /api/embedded/v1/unified/crm/accounts HTTP/1.1
Authorization: Bearer <connected-user-token>
X-Environment: PRODUCTION
Content-Type: application/json

{
  "name": "ByteChef",
  "description": "Integration API",
  "industry": "Software",
  "numberOfEmployees": 120,
  "website": "https://bytechef.io/"
}

Response:

{ "id": "1234" }

Example: list accounts

Request:

GET /api/embedded/v1/unified/crm/accounts?size=2 HTTP/1.1
Authorization: Bearer <connected-user-token>
X-Environment: PRODUCTION

Response:

{
  "content": [
    {
      "id": "1234",
      "name": "ByteChef",
      "industry": "Software",
      "website": "https://bytechef.io/",
      "remoteId": "account_1234",
      "createdDate": "2023-02-27T00:00:00Z",
      "lastModifiedDate": "2023-02-27T00:00:00Z"
    }
  ],
  "hasNext": true,
  "size": 2,
  "continuationToken": "cD0yMDIxLTAxLTA2KzAzJTNBMjQ..."
}

Unified account fields

A subset of the normalized CRM account model:

FieldTypeDescription
idstringThe unified account ID.
namestringThe account (company) name.
descriptionstringFree-text description.
industrystringIndustry classification.
numberOfEmployeesintegerEmployee count.
websitestringCompany website URL.
addressesarrayPostal addresses.
emailsarrayEmail addresses.
phonesarrayPhone numbers.
lifecycleStageobjectLifecycle stage of the account.
ownerIdstringID of the owning user.
lastActivityDatedate-timeTimestamp of the last activity.
customFieldsobjectProvider-specific custom fields passed through unchanged.
remoteIdstringThe record's ID in the third-party provider.
remoteDataobjectThe raw provider payload, present when include_raw_data=true.
createdDatedate-timeWhen the record was created.
lastModifiedDatedate-timeWhen the record was last modified.

The Accounting account model is different — it carries fields such as accountNumber, classification, currency, currentBalance, status, type, and parentAccountId. Each category defines its own normalized schema; the shared machinery (auth, pagination, remoteData, customFields) is the same across both.

How it relates to component connectors

The Unified API does not replace components — it composes them:

  • A connected user still connects a specific provider (HubSpot, Pipedrive, Xero) through the normal connection flow.
  • Each supporting provider component declares how its native objects map to the unified model.
  • When you call the Unified API, ByteChef looks up the connected user's connection for the category, invokes the matching component action, and translates between the unified schema and the provider's schema in both directions.

That means you get the breadth of the component catalog with the ergonomics of a single, stable schema — integrate once against the Unified API, and every provider that implements the mapping is available to your connected users automatically.

How is this guide?

Last updated on

On this page