Custom Fields
Custom fields are operator-defined per-contact data — things like Favorite Color, Birthday, T-Shirt Size, Newsletter Subscriber. You define them in your Textingline dashboard; the API uses them in two places:
- As keys on the
customFieldsmap when reading or writing a contact (see Contacts). - As merge-tag variables in message bodies (e.g.
{{contact_custom_field_1}}in a broadcast).
The schema endpoint exposes the field definitions so you can discover what's available and how to reference each field correctly.
Endpoint
GET /api/v1/contacts/custom-fields/schema
Example
curl https://platform.textingline.com/api/v1/contacts/custom-fields/schema \
-u "your_key_id:your_key_secret"Response
{
"fields": [
{
"label": "Favorite Color",
"key": "contact_custom_field_1",
"type": "TEXT"
},
{
"label": "Age",
"key": "contact_custom_field_2",
"type": "NUMBER"
},
{
"label": "Newsletter Subscriber",
"key": "contact_custom_field_3",
"type": "BOOLEAN"
},
{
"label": "T-Shirt Size",
"key": "contact_custom_field_4",
"type": "SINGLE_SELECT",
"options": ["S", "M", "L", "XL"]
},
{
"label": "Interests",
"key": "contact_custom_field_5",
"type": "MULTI_SELECT",
"options": ["Sports", "Music", "Travel", "Food"]
}
]
}| Field | Description |
|---|---|
label | Operator-defined human-readable label. Use this as the JSON key when reading or writing customFields on a contact. Unique per account, case-insensitive. Can be renamed in the dashboard. |
key | Stable merge-tag variable name for this field. Use this inside {{...}} in message bodies to substitute the field per recipient. Stable across label renames — unlike label, this never changes once the field is created. |
type | Data type. Determines the accepted value shape on writes and the runtime shape on reads (see below). |
options | Present only for SINGLE_SELECT and MULTI_SELECT fields. Lists the valid choice values. Match is case-sensitive on writes. |
Fields that are currently being deleted or disabled in the dashboard are omitted from the response — they aren't writable or readable via the API.
Field types
| Type | Value shape | Example |
|---|---|---|
TEXT | string | "Red" |
NUMBER | number (finite) | 42 |
BOOLEAN | boolean | true |
DATE | ISO date string in YYYY-MM-DD format | "1985-04-12" |
SINGLE_SELECT | string — must match one of the field's options | "M" |
MULTI_SELECT | array of strings — each must match an option | ["Sports", "Music"] |
Using the schema with contacts
Once you've fetched the schema, you can use the label as the JSON key in the customFields map on any contact write or read:
curl -X PATCH https://platform.textingline.com/api/v1/contacts/by-phone/+18005551234 \
-u "your_key_id:your_key_secret" \
-H "Content-Type: application/json" \
-d '{
"customFields": {
"Favorite Color": "Red",
"Age": 42,
"T-Shirt Size": "M",
"Interests": ["Sports", "Music"]
}
}'Label matching is case-insensitive and trims whitespace — "favorite color", "Favorite Color", and " FAVORITE COLOR " all resolve to the same field. The response always echoes the canonical label as stored on the schema.
Using the schema in message bodies
Use the key returned on each field to reference it in a message body. The platform substitutes per-recipient at send time:
Hi {{contact_first_name}}, your favorite color is {{contact_custom_field_1}}.
If the field has no value for a given recipient, the substitution produces an empty string.
key is stable across label renames. If you rename "Favorite Color" → "Color" in the dashboard, your message templates referencing {{contact_custom_field_1}} continue to work; the label-keyed JSON paths (e.g. "customFields": {"Favorite Color": ...}) need updating in your integration.
Limits
- Up to 7 custom fields per account. Adding an 8th is rejected at the dashboard layer.
- Field labels must be unique per account (case-insensitive). Renaming is allowed; collisions are rejected.
- The schema is read-only via the API. Create, edit, or delete fields in your dashboard.
Common errors
| Code | Description |
|---|---|
33033 | Invalid custom field. The details.reason enum distinguishes the cause (unknown_label, type_mismatch, etc.). See Error Codes. |
33001 | Authentication failed. |
33002 | Rate limit exceeded — schema reads share the contactApiRead bucket (150 requests / 60 seconds, see Rate Limits). |