Addresses, notes and tags
Where they live, what the crew needs to remember, and how to group people. Three things that look similar and aren't.
Three collections hang off every customer, and picking the wrong one is a mess to undo later.
| Holds | Use it when | |
|---|---|---|
| Addresses | Proper postal addresses | You need to turn up somewhere, or bill it |
| Notes | Free text, filed by category, with visibility | A person wrote something worth remembering |
| Tags | Named, coloured labels | You want to group or filter people |
All three live under /api/modules/clients/{client}/… and all support the full set of
read, add, change and delete.
Addresses
POST /api/modules/clients/{client}/addressesWhere the crew actually goes. Dana might have one; a landlord might have twelve.
Prop
Type
await fetch(`${BASE}/api/modules/clients/${customerId}/addresses`, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-XSRF-TOKEN': readCookie('XSRF-TOKEN'),
'X-Location-Id': locationId,
},
body: JSON.stringify({
label: 'Home',
address_line_1: '1200 NW Everett St',
city: 'Portland',
state: 'OR',
postal_code: '97209',
country: 'US',
is_primary: true,
}),
});country is two letters, not a country name
"United States" is a 422. Send "US". This is the single most common failure when
importing addresses from a system that stores names.
state being required is worth planning for outside the US. Most address data has
something that fits — county, province, prefecture — but decide which, consistently,
before you import a few thousand.
Notes
POST /api/modules/clients/{client}/notes"Allergic to lavender." "Key is under the third plant pot." "Prefers we don't ring the bell — baby sleeps until 10."
Prop
Type
curl -X POST https://api.hyphabase.com/api/modules/clients/$CUSTOMER_ID/notes \
-u sk_live_xxx: -H "X-Location-Id: $HYPHABASE_LOCATION_ID" \
-H "Content-Type: application/json" \
-d '{
"category": "Access",
"content": "Key safe by the side gate. Code changes each January.",
"visibility": "internal"
}'visibility is a real boundary, not a hint. internal notes are for your staff; public
ones are shown to the customer through their own portal. There's no default — you have
to choose, which is the right call for a field that decides whether a customer reads what
your crew wrote about them.
category is free text, so agree a vocabulary early. Nothing enforces it, and a mixture of
Access, access and Entry is tedious to clean up at three hundred customers.
Tags
POST /api/modules/clients/{client}/traitsLabels you group people by: VIP, Has dog, Pays late, Eco products only.
Prop
Type
curl -X POST https://api.hyphabase.com/api/modules/clients/$CUSTOMER_ID/traits \
-u sk_live_xxx: -H "X-Location-Id: $HYPHABASE_LOCATION_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "Has dog",
"icon": "dog",
"color": "#00a87e",
"description": "Friendly, but crate him before mopping."
}'Tags come back expanded on the customer, so listing customers gives you their tags without extra requests — which is what makes them usable for display.
Tags aren't a shared list
icon and color are stored on each customer's tag. So "Has dog" on forty customers
stores the styling forty times, and nothing deduplicates it.
Keep the values in a constant on your side so they stay consistent, and expect to make a pass over all of them if you change the styling.
If what you want is a genuinely shared vocabulary with one definition — statuses are that.
Tags or statuses?
Easy to conflate, and the difference is worth getting right:
| Tags | Statuses | |
|---|---|---|
| How many per customer | As many as you like | Exactly one, per site |
| The vocabulary | Ad-hoc, defined per customer | Defined once for the site |
| Right for | Has dog, VIP, Eco products only | New, Regular, Lapsed |
A status is where someone is in your process. Tags are everything else you want to note about them.