---
title: "Create Custom Field"
description: "Creates a new custom field definition."
---

`POST /api/custom-fields`

## Request Body

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `organizationId` | number | Yes | - | Organization ID |
| `name` | string | Yes | - | Display name |
| `fieldKey` | string | No | auto from name | Unique key (auto-normalized: lowercase, non-alphanumeric → `_`) |
| `fieldType` | string | No | `text` | `text`, `select`, or `multiselect` |
| `isRequired` | boolean | No | false | Whether the field is required |
| `displayOrder` | number | No | 0 | Sort order |
| `options` | array | No | `[]` | Options for select/multiselect types |
| `placeholder` | string\|null | No | null | Placeholder text |
| `helpText` | string\|null | No | null | Help text below the field |
| `showInTable` | boolean | No | true | Show in table views |

## Example (cURL)

```bash
curl -X POST "$BASE_URL/api/custom-fields" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "organizationId": 1,
    "name": "Environment",
    "fieldType": "select",
    "options": ["production", "staging", "development"],
    "isRequired": true,
    "showInTable": true
  }'
```

## Common errors

- `409 Conflict` when `fieldKey` already exists for the organization

## Response

Returns the created custom field object. See [Error Codes](/api/error-codes-and-known-pitfalls) for error responses.
