Inbox
Define typed fields on contacts, such as plan, city or renewal date, set them from your app or a workflow, and use them in segments and messages.
Custom fields add your own data to contacts: a customer's plan, their city, the date their trial ends. You define a field once per profile, with a type, then set values per contact. Fields feed broadcast segments, workflow conditions and message personalisation.
#Define a field
curl -X POST https://api.pozy.ai/v1/custom-fields \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profileId": "6650c1e2a3b4c5d6e7f80911",
"name": "Plan",
"slug": "plan",
"type": "select",
"options": ["free", "pro", "team"]
}'const res = await fetch("https://api.pozy.ai/v1/custom-fields", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.POZY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
profileId: "6650c1e2a3b4c5d6e7f80911",
name: "Plan",
slug: "plan",
type: "select",
options: ["free", "pro", "team"],
}),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
console.log(data.field.id, data.field.slug);import os
import requests
resp = requests.post(
"https://api.pozy.ai/v1/custom-fields",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
json={"profileId": "6650c1e2a3b4c5d6e7f80911", "name": "Plan", "slug": "plan", "type": "select", "options": ["free", "pro", "team"]},
timeout=30,
)
print(resp.json()["field"])| Field | Notes |
|---|---|
profileId |
Required. Fields belong to one profile |
name |
Required. Shown in the dashboard |
slug |
The key you use in the API and in templates. Generated from the name when you leave it out |
type |
Required: text, number, date, boolean or select |
options |
The allowed values for select fields |
The type is fixed once the field exists. PATCH /v1/custom-fields/{fieldId} can rename it or change options, not the type. To change the type, create a new field and copy the values.
#Set and clear values
PUT /v1/contacts/{contactId}/fields/{slug} sets or overwrites one value. The value must match the field's type: a number for number, true or false for boolean, an ISO date for date, one of the options for select.
curl -X PUT https://api.pozy.ai/v1/contacts/6650c1e2a3b4c5d6e7f80c44/fields/plan \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "value": "pro" }'const res = await fetch("https://api.pozy.ai/v1/contacts/6650c1e2a3b4c5d6e7f80c44/fields/plan", {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.POZY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ value: "pro" }),
});
if (!res.ok) throw new Error((await res.json()).error);requests.put(
"https://api.pozy.ai/v1/contacts/6650c1e2a3b4c5d6e7f80c44/fields/plan",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
json={"value": "pro"},
timeout=30,
)DELETE /v1/contacts/{contactId}/fields/{slug} clears the value. Deleting the field definition with DELETE /v1/custom-fields/{fieldId} removes its values from every contact.
Values come back on every contact under customFields, keyed by slug.
#Where fields are used
| Where | How |
|---|---|
| Broadcast segments | segmentFilters.customFields matches contacts holding exact values, for example { "plan": "pro" }. Types must match too: 5 does not match "5". See Broadcasts |
| Workflows | {{contact.fields.plan}} in any message, condition rules on it, and set_field nodes to write it. See Workflow nodes |
#Field changes as webhooks
contact.field_changed fires whenever a value actually changes, with field, previousValue, value and source (api, workflow or automation). Writing the value a contact already has fires nothing. Use it to mirror fields into your CRM without polling.
#Endpoints
| Endpoint | What it does |
|---|---|
PUT /v1/contacts/{contactId}/fields/{slug} |
Set custom field value |
DELETE /v1/contacts/{contactId}/fields/{slug} |
Clear custom field value |
GET /v1/custom-fields |
List custom field definitions |
POST /v1/custom-fields |
Create custom field |
PATCH /v1/custom-fields/{fieldId} |
Update custom field |
DELETE /v1/custom-fields/{fieldId} |
Delete custom field |
#Webhook events
| Event | When it fires |
|---|---|
contact.field_changed |
Contact field changed. |