Create a custom field
Creates a reusable field definition. Scope: custom_fields:write.
One definition serves the whole platform: reference it from any card’s form_builder (signup form), read/write values via Customer.custom.<key>, render it on wallet passes ({{custom.<key>}} in pass_fields) and in notification templates.
keyis the stable machine handle (^[a-z][a-z0-9_]{1,49}$, unique per organization) -409 key_already_existson collisionfield_type+options+date_granularity+number_formatdefine the value contract (immutable once used)position/labeltranslations are DEFAULTS - each card’s form can override them- Organization cap: 50 definitions (
409 custom_field_limit_reached)
Authorizations
Your secret API key as a Bearer token: Authorization: Bearer vxn_sk_.... Keys are created and scoped in the dashboard - see Authentication.
Headers
UUIDv4 recommended. Replays cached 24h.
Body
Define a reusable custom field. Non-applicable config is normalized automatically (options with text → empty array; date_granularity with number → reset to date).
Customer-facing label - shown on the signup form, referenced on wallet passes, and used in the dashboard. Plain string or per-language object (the platform localization pattern, same as Card.name). This is the DEFAULT - each card's form_builder can override the label per card.
Uniqueness is among active definitions. A label must be unique among the organization's active definitions (409 on conflict). Deleting a definition frees its label for reuse.
1 - 50Field type - see the type table on the Custom Field object. Immutable while in use.
text, textarea, number, currency, date, boolean, select, multiselect "select"
Org-unique machine identifier (optional - derived from the label when omitted). Immutable once the field is in use.
^[a-z][a-z0-9_]{1,49}$"department"
Optional dashboard helper text.
500Dashboard ordering hint.
Required non-empty for select/multiselect. Ignored (forced empty) otherwise.
Date type only. Default date.
year, monthYear, date number fields only. Default decimal.
integer, decimal Response
Created
A reusable custom field DEFINITION - the single vocabulary used across the whole platform: the signup form (via each card's form_builder), the customer record (Customer.custom.<key>), wallet pass slots ({{custom.<key>}} in Card.pass_fields), and notification templates. Define once, reference everywhere.
The definition owns IDENTITY (key, type, options, granularity) and DEFAULTS (label translations, required, position); each card's form owns USAGE (which fields, per-card required/order/label overrides). Limits: 50 definitions per organization (409 custom_field_limit_reached), 20 fields per card form.
Opaque, stable, immutable. cf_ prefix.
^cf_[A-Za-z0-9]+$"cf_01HW9R9Z4EF7N8MTX1RVCFLD01"
Always "custom_field".
"custom_field"Stable machine identifier, unique within the organization (2-50 chars, lowercase snake). Used in {{custom.<key>}} templates and Customer custom.<key> payloads. Renames are blocked while the field is in use (usage_count > 0) to prevent keys diverging across cards.
^[a-z][a-z0-9_]{1,49}$"department"
Customer-facing label - shown on the signup form, referenced on wallet passes, and used in the dashboard. Plain string or per-language object (the platform localization pattern, same as Card.name). This is the DEFAULT - each card's form_builder can override the label per card.
1 - 200What kind of data the field holds - drives form input, validation, and typed pass/notification rendering:
Immutable while the field is used by any card (409 custom_field_in_use).
text, textarea, number, currency, date, boolean, select, multiselect "select"
Unix seconds.
1750000000
Internal helper text for the dashboard.
500"Clinic department the patient is assigned to."
DEFAULT form position when added to a card; each card's form_builder ordering overrides.
2
Choices for select / multiselect (required for those types). Each option is {value, label} - labels are always editable (display only); values are immutable once any customer has stored them and removing a used value is blocked (409 custom_field_in_use). Adding options is always allowed.
DATE type only - controls the stored format: date → YYYY-MM-DD, monthYear → YYYY-MM, year → YYYY. Forced to date for non-date types.
year, monthYear, date "date"
Read-only. Number of cards referencing this field. Renames + type changes + deletes are blocked while > 0.
3
Read-only. The referencing card ids.
Unix seconds.
1750000000
number fields only: integer rejects fractional input; decimal (default) allows it. Null on other types.
integer, decimal, null