---
title: "Create a custom contact field"
method: POST
path: "/contact-fields"
tags: ["Contact fields"]
---

# Create a custom contact field

`POST /contact-fields`

## Request

- Base URL: `https://www.unitpost.com/api/v1`
- URL: `https://www.unitpost.com/api/v1/contact-fields`
- Auth: HTTP bearer

Define a new typed custom field that can then be set on any contact and used as a template variable (e.g. `plan`, `signup_date`). An optional `default_value` is the value used for any contact that has none: when an email is sent (merge tags) and when segments are evaluated. It's never written onto contacts, so changing it takes effect everywhere at once. The `key` and `type` are fixed once created — rename the key later with [Rename a custom field's key](#post-contact-fields-id-rename), or change the label with [Update a custom contact field](#patch-contact-fields-id). See existing fields via [List custom contact fields](#get-contact-fields). Requires the `contacts:write` capability.

## Request body

- ContactFieldCreate
  - `key` string, required
  - `label` string, required
  - `type` 'text' | 'number' | 'boolean' | 'date'
  - `default_value` string, nullable: The value used for any contact that has none for this field (key missing or null): when an email is sent (merge tags) and when segments are evaluated. It's never written onto contacts, so changing it takes effect everywhere at once. Stored as a string and coerced to the field's type; null means no default. In segment filters, is_set / is_not_set check whether the contact itself has a value.

## Response `201`

Created.

- ContactField
  - `object` 'contact_field', required
  - `id` string, required
  - `key` string, required
  - `label` string, required
  - `type` 'text' | 'number' | 'boolean' | 'date', required
  - `default_value` string, nullable, required: The value used for any contact that has none for this field (key missing or null): when an email is sent (merge tags) and when segments are evaluated. It's never written onto contacts, so changing it takes effect everywhere at once. Stored as a string and coerced to the field's type; null means no default. In segment filters, is_set / is_not_set check whether the contact itself has a value.
  - `position` number, required
  - `created_at` string, required
  - `updated_at` string, required

## Other responses

- `401`: Missing or invalid API key.
- `409`: A field with that key already exists.
- `422`: Validation error.

---

[API](https://skmtc.dev/unitpost/apis/unitpost-api.md) · [All operations](https://skmtc.dev/unitpost/apis/unitpost-api/llms.txt) · [OpenAPI document](https://skmtc.dev/unitpost/apis/unitpost-api/revisions/86ff7c890967?raw)
