> ## Documentation Index
> Fetch the complete documentation index at: https://developer.zeeg.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Attribute to CRM Object

> Add a custom attribute to a Zeeg CRM object via the API. Define typed fields like text, number, select, relation, or currency with auto-generated keys

## Key auto-generation

You do not set the `key` — the server derives it from `label` by converting to snake\_case (e.g. `"Product Name"` → `"product_name"`). The generated key is returned in the `201` response. Use this key to reference the attribute in subsequent `PATCH` calls and when writing record values.

If another attribute with the same derived key already exists, the server appends a suffix (e.g. `product_name_2`).

## Attribute type reference

Every attribute requires `label`, `type`, `isRequired`, and `isArchived`.
The sections below list the extra fields each type needs and what values it stores.

***

### `text`

Stores a free-form string.

**Extra fields**

| Field        | Required | Description                                              |
| ------------ | -------- | -------------------------------------------------------- |
| `isUnique`   | yes      | Reject duplicate values across records.                  |
| `validation` | no       | Array of format validators: `"email"`, `"url"`, or both. |

**Example request**

```json theme={null}
{
  "label": "Work Email",
  "type": "text",
  "isRequired": false,
  "isUnique": true,
  "isArchived": false,
  "validation": ["email"]
}
```

***

### `number`

Stores a numeric value (integer or decimal).

**Extra fields**

| Field      | Required | Description                             |
| ---------- | -------- | --------------------------------------- |
| `isUnique` | yes      | Reject duplicate values across records. |

***

### `phone_number`

Stores a phone number string. Displayed with a phone-number input in the UI.

**Extra fields**

| Field      | Required | Description                             |
| ---------- | -------- | --------------------------------------- |
| `isUnique` | yes      | Reject duplicate values across records. |

***

### `date`

Stores a calendar date (no time component).

No extra fields.

***

### `datetime`

Stores a date and time with timezone.

No extra fields.

***

### `checkbox`

Stores a boolean (`true` / `false`).

No extra fields.

***

### `select`

Stores one value chosen from a fixed list.

**Extra fields**

| Field     | Required | Description                                                                                                                        |
| --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `options` | yes      | Array of 1–20 option objects. Each option: `value` (string), `color` (named color — see below). Do **not** include `id` on create. |

**Allowed colors**

`gray` `primary` `warning` `success` `cyan` `sky` `violet` `fuchsia` `rose` `blue` `green` `red` `pink` `black` `yellow` `orange`

**Example request**

```json theme={null}
{
  "label": "Category",
  "type": "select",
  "isRequired": false,
  "isArchived": false,
  "options": [
    { "value": "Electronics", "color": "primary" },
    { "value": "Clothing",    "color": "success" },
    { "value": "Clearance",   "color": "warning" }
  ]
}
```

***

### `multiselect`

Stores multiple values from a fixed list. Same fields as `select`.

**Extra fields**

Same as `select` — `options` array required.

***

### `status`

Like `select` but rendered as a status badge. Change history is logged for auditing. Same fields as `select`.

**Extra fields**

Same as `select` — `options` array required.

***

### `rating`

Stores an integer rating (1–5 stars in the UI).

No extra fields.

***

### `relation`

Links a record to one or more records in another CRM object.

**Extra fields**

| Field                | Required | Description                                                                                           |
| -------------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `relationType`       | yes      | Cardinality: `one_to_one`, `many_to_one`, `one_to_many`, or `many_to_many`.                           |
| `relatedObjectSlug`  | yes      | Slug of the target object (`people`, `companies`, or a custom object slug). Immutable after creation. |
| `relatedObjectLabel` | yes      | Display label shown for the relation in the UI (e.g. `"Person"`, `"Company"`).                        |

`one_to_one` / `many_to_one` → the field accepts a single linked record.\
`one_to_many` / `many_to_many` → the field accepts multiple linked records.

**Example request**

```json theme={null}
{
  "label": "Assigned Person",
  "type": "relation",
  "isRequired": false,
  "isArchived": false,
  "relationType": "many_to_one",
  "relatedObjectSlug": "people",
  "relatedObjectLabel": "Person"
}
```

***

### `currency`

Stores a numeric monetary value with display formatting.

**Extra fields**

| Field              | Required | Description                                                                                     |
| ------------------ | -------- | ----------------------------------------------------------------------------------------------- |
| `currency`         | yes      | ISO 4217 currency code (e.g. `EUR`, `USD`, `GBP`). Immutable after creation.                    |
| `currencyDisplay`  | yes      | How the currency is shown: `code` (`EUR 12.00`), `name` (`Euro 12.00`), or `symbol` (`€12.00`). |
| `currencyDecimal`  | yes      | `true` to show decimal places.                                                                  |
| `currencyGrouping` | yes      | `true` to use a thousands separator (`1,000.00` vs `1000.00`).                                  |

`currencyDisplay`, `currencyDecimal`, and `currencyGrouping` can be changed later via `PATCH`.
The `currency` code is immutable after creation.

**Supported currency codes**

USD, EUR, GBP, JPY, CHF, CAD, AUD, NZD, SEK, DKK, NOK, CZK, PLN, HUF, RON, BRL, MXN,
CNY, SGD, THB, PHP, IDR, INR, ZAR, MYR, VND, KRW, TND, OMR, QAR, SAR, AED, BHD, KWD, JOD, LYD, IRR, TRY.

**Example request**

```json theme={null}
{
  "label": "Price",
  "type": "currency",
  "isRequired": false,
  "isArchived": false,
  "currency": "EUR",
  "currencyDisplay": "symbol",
  "currencyDecimal": true,
  "currencyGrouping": true
}
```

***

### `user`

Links the record to one or more workspace members. Values are user IDs.

No extra fields. Always supports multiple selection.


## OpenAPI

````yaml POST /crm/objects/{slug}/attributes
openapi: 3.0.0
info:
  title: Zeeg Public API
  description: >-
    Zeeg public API documentation.


    ## Authentication

    All endpoints require a Bearer token. You can generate an API token from
    [your Zeeg dashboard](https://app.zeeg.me/account/settings/api-access).


    Each token is scoped to specific permissions (e.g. `events:read`,
    `webhooks:write`). Make sure your token has the required scopes for the
    endpoints you want to use.


    ## Recommended Headers

    We recommend including the `Accept: application/json` header in all API
    requests to ensure you receive JSON responses.
  version: 2.0.0
  x-logo:
    url: https://app.zeeg.me/img/logo-dark.2ca83593.svg
    backgroundColor: '#f7f7f9'
    altText: zeeg
  contact:
    name: Zeeg Support
    email: support@zeeg.me
    url: https://zeeg.me/en/contact
  license:
    name: Proprietary
    url: https://zeeg.me/en/legal/terms
  termsOfService: https://zeeg.me/en/legal/terms
servers:
  - url: https://api.zeeg.me/v2
    description: Production
security:
  - bearer: []
tags:
  - name: Scheduled Events
    description: Management of events scheduled via Zeeg
  - name: Scheduling Pages
    description: Scheduling pages information and management
  - name: Availability Schedule
    description: Read and change availability for users
  - name: Webhooks
    description: Webhooks management
  - name: Notes
    description: Notes for scheduled events
  - name: Workspaces & Teams
    description: Workspace users and team member management
  - name: AI Agent
    description: AI Agent integration endpoints
  - name: Payloads
    description: Webhook payload schemas
  - name: CRM - Objects
    description: >-
      Discover the schema of CRM objects (standard and custom) including all
      attribute definitions
  - name: CRM - Companies
    description: Create, read, update, and delete CRM company records
  - name: CRM - People
    description: Create, read, update, and delete CRM person records
paths:
  /crm/objects/{slug}/attributes:
    post:
      tags:
        - CRM - Objects
      summary: Add an attribute to a CRM object
      description: >-
        Adds a new custom attribute to an existing CRM object. Works on both
        standard objects (`people`, `companies`) and custom objects.


        The attribute `key` (slug) is auto-generated from the `label`. To get
        the generated key, inspect the `key` field in the response.


        **Required scope:** `crm:write`


        **Type-specific required fields:**

        - `select`, `multiselect`, `status` → `options` array required

        - `relation` → `relationType`, `relatedObjectSlug`, `relatedObjectLabel`
        required

        - `text`, `phone_number`, `number` → `isUnique` required

        - `currency` → `currency`, `currencyDisplay`, `currencyDecimal`,
        `currencyGrouping` required
      operationId: post-crm-object-attributes
      parameters:
        - name: slug
          in: path
          required: true
          schema:
            type: string
            example: people
          description: The object slug to add the attribute to.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - type
                - label
                - isRequired
              properties:
                type:
                  type: string
                  description: Attribute data type. Cannot be changed after creation.
                  enum:
                    - text
                    - number
                    - phone_number
                    - date
                    - datetime
                    - checkbox
                    - select
                    - multiselect
                    - rating
                    - relation
                    - status
                    - user
                    - currency
                  example: select
                label:
                  type: string
                  description: >-
                    Human-readable label. The attribute key is auto-generated
                    from this value.
                  example: Customer Status
                  maxLength: 255
                isRequired:
                  type: boolean
                  description: Whether a value is required when creating a record.
                  example: false
                isUnique:
                  type: boolean
                  description: >-
                    Whether values must be unique across records. Applies to
                    `text`, `phone`, and `number` types.
                  example: false
                validation:
                  type: array
                  description: Validation constraints for `text` type attributes.
                  items:
                    type: string
                    enum:
                      - email
                      - url
                options:
                  type: array
                  description: >-
                    Required for `select`, `multiselect`, and `status` types.
                    Max 20 options.
                  items:
                    $ref: '#/components/schemas/CrmAttributeOption'
                relationType:
                  type: string
                  description: Required for `relation` type.
                  enum:
                    - one_to_one
                    - many_to_one
                    - one_to_many
                    - many_to_many
                  example: many_to_one
                relatedObjectSlug:
                  type: string
                  description: Required for `relation` type. Slug of the object to link to.
                  example: companies
                relatedObjectLabel:
                  type: string
                  description: >-
                    Required for `relation` type. Label shown on the related
                    object's record.
                  example: Contacts
                currency:
                  type: string
                  description: Required for `currency` type. ISO 4217 currency code.
                  example: EUR
                currencyDisplay:
                  type: string
                  description: Required for `currency` type.
                  enum:
                    - code
                    - name
                    - symbol
                  example: symbol
                currencyDecimal:
                  type: boolean
                  description: Required for `currency` type. Show decimal places.
                  example: true
                currencyGrouping:
                  type: boolean
                  description: Required for `currency` type. Use thousands separator.
                  example: true
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  status:
                    type: integer
                    example: 201
                  attribute:
                    $ref: '#/components/schemas/CrmAttribute'
              examples:
                Text attribute:
                  value:
                    success: true
                    status: 201
                    attribute:
                      key: customer_status
                      label: Customer Status
                      type: select
                      isRequired: false
                      isStandard: false
                      isUnique: false
                      isArchived: false
                      options:
                        - id: 1
                          value: Lead
                          color: warning
                        - id: 2
                          value: Active
                          color: success
                      createdAt: '2025-06-15T10:00:00+00:00'
                      updatedAt: '2025-06-15T10:00:00+00:00'
        '400':
          description: Bad Request — attribute limit reached or invalid type change
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  status:
                    type: integer
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: >-
            Forbidden — missing scope, CRM not enabled, or attribute limit
            reached
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  status:
                    type: integer
        '404':
          description: Object not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
                  status:
                    type: integer
        '422':
          $ref: '#/components/responses/422'
      security:
        - bearer: []
components:
  schemas:
    CrmAttributeOption:
      type: object
      description: >-
        A selectable option for a `select`, `multiselect`, or `status`
        attribute.
      required:
        - value
        - color
      properties:
        id:
          type: integer
          nullable: true
          description: >-
            Server-assigned option ID. Omit when adding a new option; include
            when updating an existing one to preserve it.
          example: 1
        value:
          type: string
          description: The option label shown in the UI and stored as the attribute value.
          example: Active
          maxLength: 512
        color:
          type: string
          description: >-
            Color name for the option. Allowed values: `gray`, `primary`,
            `warning`, `success`, `cyan`, `sky`, `violet`, `fuchsia`, `rose`,
            `blue`, `green`, `red`, `pink`, `black`, `yellow`, `orange`.
          example: success
    CrmAttribute:
      type: object
      description: Definition of a single attribute on a CRM object.
      required:
        - key
        - label
        - type
        - isRequired
        - isStandard
        - isUnique
        - isArchived
        - createdAt
        - updatedAt
      properties:
        key:
          type: string
          description: Attribute key used when reading or writing record values.
          example: job_title
        label:
          type: string
          description: Human-readable label shown in the UI.
          example: Job Title
        type:
          type: string
          description: Attribute data type. Cannot be changed after creation.
          enum:
            - text
            - number
            - phone_number
            - date
            - datetime
            - checkbox
            - select
            - multiselect
            - rating
            - relation
            - status
            - user
            - currency
          example: text
        isRequired:
          type: boolean
          description: Whether a value is required when creating a record.
          example: false
        isStandard:
          type: boolean
          description: >-
            `true` for built-in attributes, `false` for custom attributes added
            by your workspace.
          example: false
        isUnique:
          type: boolean
          description: >-
            Whether values must be unique across all records. Applies to `text`,
            `phone`, and `number` types.
          example: false
        isArchived:
          type: boolean
          description: >-
            Whether the attribute is archived. Archived attributes are hidden
            from the UI but their data is preserved.
          example: false
        options:
          type: array
          description: >-
            Available options. Present only for `select`, `multiselect`, and
            `status` attributes.
          items:
            $ref: '#/components/schemas/CrmAttributeOption'
        relatedObjectSlug:
          type: string
          nullable: true
          description: >-
            Slug of the related object. Present only for `relation` attributes.
            Immutable after creation.
          example: companies
        relatedObjectLabel:
          type: string
          nullable: true
          description: >-
            Display label for the relation. Present only for `relation`
            attributes. Can be updated via PATCH.
          example: Company
        relationType:
          type: string
          nullable: true
          description: Cardinality of the relation. Present only for `relation` attributes.
          enum:
            - one_to_one
            - many_to_one
            - one_to_many
            - many_to_many
          example: many_to_one
        isMultipleSelection:
          type: boolean
          description: >-
            `true` when `relationType` is `one_to_many` or `many_to_many`.
            Present only for `relation` attributes.
          example: false
        currency:
          type: string
          nullable: true
          description: >-
            ISO 4217 currency code. Present only for `currency` attributes.
            Immutable after creation.
          example: EUR
        currencyDisplay:
          type: string
          nullable: true
          description: >-
            How the currency value is displayed. Present only for `currency`
            attributes.
          enum:
            - code
            - name
            - symbol
          example: symbol
        currencyDecimal:
          type: boolean
          nullable: true
          description: >-
            Whether decimal places are shown. Present only for `currency`
            attributes.
          example: true
        currencyGrouping:
          type: boolean
          nullable: true
          description: >-
            Whether a thousands separator is used. Present only for `currency`
            attributes.
          example: true
        createdAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the attribute was created.
          example: '2025-06-01T10:00:00+00:00'
        updatedAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the attribute was last updated.
          example: '2025-06-01T10:00:00+00:00'
  responses:
    '401':
      description: Unauthorized
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                example: Unauthenticated.
          examples:
            Unauthenticated:
              value:
                message: Unauthenticated.
    '422':
      description: Unprocessable Entity
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                example: The given data was invalid.
              errors:
                type: object
                additionalProperties:
                  type: array
                  items:
                    type: string
                example:
                  field_name:
                    - The field_name field is required.
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: ''

````