Skip to main content
Object models are native, Cargo-managed data models for the core entities your team works with — accounts, contacts, deals, leads, and any custom object you need. Unlike integration models that mirror data from an external source, object models are owned by your workspace: your plays, tools, and agents create, update, and remove records in them directly. Use object models when you need a writable system of record inside Cargo — for example, a list of qualified leads built from research, a pipeline of opportunities sourced from intent signals, or a custom catalog of partners, products, or territories that doesn’t live anywhere else.

Create an object model from the CLI

Object models are owned by Cargo. You can create them and their columns imperatively with the storage commands, or declaratively in code with the CDK (see below):
Object models are stored in the same data warehouse as your integration models, so you can join, query, and unify them using SQL like any other model. The built-in Account / Contact / Deal / Lead types ship pre-shaped — you only add columns for fields beyond their standard schema.

Define an object model in code

Not every model sits behind a connector. With the CDK, pass kind: "native" to defineModel to declare an object model in the workspace’s built-in dataset — defineCustom for a free-form schema, or the CRM-shaped defineAccount / defineContact / defineDeal / defineLead:
models/companies.ts
Deploying binds the model into cargo.state.json, so your plays, tools, and agents can reference it by handle. To adopt one of the four unified models from code instead, see Unification.
Relationships join two object models in the same dataset. Declare them in code with defineRelationship, referencing the CLI-created models by modelRef(uuid):
relationships/contact-account.ts
Not using the CDK? Set the same join from the CLI with cargo-ai storage relationship set --dataset-uuid <uuid> --relationships '<json array>' — see Relationships for the field reference.

When to use object models

For models that mirror data from an external system (HubSpot, Salesforce, Snowflake, a webhook, etc.), use integration models instead.

Built-in object types

Cargo ships five native object types. The first four come pre-shaped with the standard fields for their entity, so you can start writing records immediately and they will participate in unification out of the box.

Account

A company. Pre-mapped with name, website, linkedin_url, industry, number_of_employees, annual_revenue, billing address, owner, and parent account.

Contact

A person tied to an account. Pre-mapped with first/last name, email, phone, title, linkedin_url, mailing address, lead source, and owner.

Deal

An opportunity tied to an account. Pre-mapped with amount, stage_name, close_date, probability, forecast_category, is_closed, is_won, owner, and campaign.

Lead

An unqualified person + company combined into one record. Includes conversion fields (is_converted, converted_account_id, converted_contact_id, converted_opportunity_id) for handoff to Account/Contact.

Custom

An object you define from scratch. Pick the columns and types you need — string, number, boolean, date, object, array, or vector.
Each built-in type has a default id column (a Cargo-generated UUID on insert) and a sensible title column (name for Account/Contact/Deal/Lead, id for Custom).
Need a field that isn’t on the built-in schema? Add a custom column with storage column create — your plays can upsert values into it without changing the underlying schema.

How object models compare


Writing to an object model

Object models are designed to be written to from inside Cargo — from the storage steps in a workflow that backs a play or tool. The Storage actions below all target object models specifically; when you pick a model in the node configuration, only object models appear in the picker.
1

Pick a target object model

Use the Model dropdown on any of the actions above. The dropdown is scoped to native objects — integration models and unified models are intentionally hidden.
2

(For update / upsert / remove) choose a matching column

Cargo will resolve every record where the matching column equals the matching value. Use a unique column (typically id, email, or website) to avoid touching unintended rows.
3

Map the values

Provide a value for each column you want to write. Values support expressions (e.g. {{nodes.start.email}}).
id is generated by Cargo on insert and cannot be supplied. For updates and upserts, do not include id in the column mappings — use it as the matching column instead.

Object models and unification

Account and Contact object models declare a unification type by default, so the records you write into them roll up into the unified Account and Contact models alongside your CRM, enrichment, and other sources. This means an account you create from a research agent, a contact you upsert from a webhook, and a company synced from HubSpot all collapse into the same canonical record when they share a domain or LinkedIn identifier.
Lead and Custom object models don’t participate in unification. Convert leads to Account / Contact records (using the converted_account_id / converted_contact_id fields) once they qualify.

Querying object models

Like every model in Cargo, object models materialize as a table in your data warehouse. They follow the same table naming convention as integration models, under the native dataset:
You can join object models with integration or unified models freely — for example, find every sourced lead whose company already exists in your unified Account model:

Next steps

Models overview

See how object models fit alongside integration and unified models.

Unification

Learn how Account and Contact object records merge with CRM and enrichment data.

Workflows

Insert, update, upsert, and remove records from your plays and tools.

Querying data

Query object models with SQL alongside the rest of your warehouse.