---
title: Objects, fields and records
description: "The data model: fourteen standard objects, nineteen field kinds in five families, what a record stores, and which parts of a live object can still change."
---

An **object** is a kind of thing a workspace keeps — an account, a quote, a task. A **field** is one piece of information an object's records hold. A **record** is one instance. Every endpoint under `/objects` works on one of those three.

## Standard objects

Fourteen standard objects exist, and each belongs to a module. [`POST /bootstrap`](/reference/crm/post-api-v1-bootstrap) installs the ones the workspace's enabled modules own, so **which objects a workspace has depends on what it has switched on.** Running it again leaves already-installed objects as they are.

| Module | Objects |
| --- | --- |
| core, always on | `account` 取引先 · `contact` 取引先責任者 · `lead` リード · `opportunity` 商談 · `activity` 活動 · `event` 行動 · `task` タスク · `note` ノート |
| `cpq` | `product` 商品 · `quote` 見積 · `quote_line_item` 見積明細 · `contract` 契約 |
| `marketing` | `campaign` キャンペーン · `campaign_member` キャンペーンメンバー |

Read [`GET /objects`](/reference/crm/get-api-v1-objects) rather than assuming the full list. `marketing` has no endpoint in this API at all, so its two objects exist but are not reachable through it.

**The labels are Japanese, and so are the select options on standard fields.** A label is display copy — what a user sees in the application — and it is stored once rather than translated per request, so it comes back in the language the product is authored in. Match on the key, never on the label.

`activity` (活動) and `event` (行動) are different objects and a frequent confusion. An activity is a logged contact, carrying the channel it came through, its result and how warm it left the lead. An event is a scheduled meeting, carrying a type and how it shows on a calendar.

## Field kinds

Nineteen kinds exist, in five families. What a family is decides whether you can write it, filter it, or configure it.

**Thirteen scalar kinds** are stored in one column and configured by nothing but their type: `text`, `longtext`, `decimal`, `currency`, `percent`, `boolean`, `date`, `datetime`, `email`, `url`, `phone`, `user`, `address`.

| Kind | What it holds |
| --- | --- |
| `text` | A single line, at most 16,384 characters |
| `longtext` | A document — a note's body, minutes — at most 1,000,000 characters, bounded by the request size rather than the line limit |
| `decimal`, `currency`, `percent` | A decimal **string**, never a number. See [conventions](/guides/conventions) |
| `date` | `YYYY-MM-DD` |
| `datetime` | ISO 8601 **with an offset**; a value without one is refused |
| `email`, `url`, `phone` | A validated address, an `http`/`https` URL, a string of at most 255 characters |
| `user` | A user id. Whether that user belongs to the organization is checked by the application; the column itself is text |
| `address` | Five parts — `postalCode`, `prefecture`, `city`, `street`, `building` — a Japanese address, not a free-form one |

**Two option kinds**, `select` and `multi_select`, hold values from a list the field defines. A multi-select takes at most 200 options and refuses a repeat.

**`relation`** points at a record in another object. The field names its `targetObjectId` and its `cardinality` when it is created.

**`formula`** computes one arithmetic step, not an expression: `left`, an operator from `add`, `subtract`, `multiply`, `divide`, and `right`, where each side names another field by key.

**Two virtual kinds**, `rollup` and `days_since`, have no column at all: the client computes them from other records or fields. Nothing is stored and nothing can be written, so a record write that carries one is refused with `field_not_scalar`.

## What a record stores

A record answers `id`, `objectId`, `name`, `revision`, `createdAt`, `updatedAt`, `archivedAt`, `values` — one entry per field — and, when the object has relation fields, `relations`.

`name` and `updated_at` are reserved **filter and sort keys**, which is a different list from the response shape above: a view sorts on `updated_at`, while a response carries `updatedAt`.

**Empty is one state, not five.** An absent key, `null`, a blank string, an empty multi-select, and an address with every part blank are all the same thing, and all stored as no value. Reading one back gives `null` whichever form you sent.

**A select option is its own stored value**, so writing an option the field does not offer is refused with `field_value_invalid`. On the standard fields that means an option list is only ever added to, never renamed: the old string is what the existing records hold.

## Creating and changing a field

Adding an object or a field needs the `custom_objects` module; reading and writing records does not.

[`POST /objects/{objectId}/fields`](/reference/crm/post-api-v1-objects-by-object-id-fields) takes a different body per family — seven shapes in all. Every one carries `key`, `label`, `required` and `visibleByDefault`; the option families add `options`, at most 200 of them, each 1 to 120 characters; a relation adds `targetObjectId`.

**Almost nothing about a field moves once it exists.** [`PATCH`](/reference/crm/patch-api-v1-objects-by-object-id-fields-by-field-id) accepts `key`, `type` and `targetObjectId` but refuses to change them, and it does not accept `options` at all. Only `label` and `required` are adjustable. Plan the key, the kind and the option list before the field has records; see [custom objects](/guides/modules/custom-objects).

`visibleByDefault` is list metadata: whether a list shows the field before anyone picks columns. It has nothing to do with who may read the field — that is [permissions](/guides/concepts/permissions).

## Converting a lead

A lead becomes an account and a contact. [`GET /objects/{objectId}/records/{recordId}/conversion-matches`](/reference/crm/get-api-v1-objects-by-object-id-records-by-record-id-conversion-matches) finds candidates to merge into instead of creating duplicates.

**The scan is bounded.** `partial: true` means the scan stopped before it ran out of records, so finding nothing proves nothing. Treat an empty result under `partial` as "unknown", not as "no match exists".
