---
title: "Create custom contact field"
method: POST
path: "/v2/api/crm/attributes"
tags: ["CRM"]
---

# Create custom contact field

`POST /v2/api/crm/attributes`

## Request

- Base URL: `https://api.withallo.com`
- URL: `https://api.withallo.com/v2/api/crm/attributes`
- Auth: API key in header `Authorization`

Creates a custom field on your team's people. The key is derived from the label. `DROPDOWN` fields need a non-empty `options` list. Creating the same label with the same type again returns the existing field with `already_existed` set to `true`. Creating a label that matches a deleted field restores it, with its previously stored values.

## Request body

- CreateCrmAttributeRequest: Request body for creating a custom contact field
  - `label` string, required: Display name of the field. The key is derived from it: lowercase, accents removed, runs of non-alphanumeric characters replaced by `_`, truncated to 64 characters. Must contain at least one letter or digit and must not resolve to a built-in field key such as `name`, `company` or `website`.
  - `type` 'TEXT' | 'NUMBER' | 'DATE' | 'BOOLEAN' | 'DROPDOWN', required: Value type of the field
  - `options` CompanyAttributeOptionInput[]: Allowed values. Required, with at least one option, for `DROPDOWN`; rejected for other types.
    - `label` string, required: Display name of the option
    - `key` string: Existing option key. Send it when editing an attribute to keep the option's key stable while its label changes. Keys that do not match an existing option are ignored and a key is derived from the label.

## Response `201`

The custom field that was created, restored or already existing

- object
  - `data` CreateCrmAttributeResult
    - `key` string: Key derived from the label
    - `label` string: Stored label. When the field already existed, this is the label it was first created with.
    - `type` 'TEXT' | 'NUMBER' | 'DATE' | 'BOOLEAN' | 'DROPDOWN'
    - `options` CompanyAttributeOption[], nullable: Allowed values. Only set for `DROPDOWN` fields.
      - `key` string
      - `label` string
    - `already_existed` boolean: `true` when a field with the same key and type already existed, or a deleted one was restored, and nothing new was created

## Other responses

- `400`: Invalid request parameters
- `401`: Invalid or missing API key
- `403`: API key lacks the required scope or access to the resource
- `404`: Resource not found
- `409`: Conflict with existing resource
- `429`: Rate limit exceeded

## Changes

- **2026-11-03** `46c77103dd14`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/withallo/apis/allo-api/changes/v2/api/crm/attributes/post.md)

---

[API](https://skmtc.dev/withallo/apis/allo-api.md) - [All operations](https://skmtc.dev/withallo/apis/allo-api/llms.txt) - [OpenAPI document](https://skmtc.dev/withallo/apis/allo-api/revisions/46c77103dd14?raw)
