Connect
REST API reference
A small, predictable JSON API for syncing contacts into Zoye. Send people or companies, search them, and look one up by id. Authenticate with a Bearer key and you are done.
Base URL
All endpoints are relative to:
https://api.zoye.ioAuthentication
Every request carries your key in the Authorization header as a Bearer token:
Authorization: Bearer zk_live_YOUR_KEYSecret vs publishable keys
| Key | Prefix | Can do | Use it |
|---|---|---|---|
| Secret | zk_live_... | Create, read, search, and write privileged routing fields | Server-side only |
| Publishable | zk_pub_... | Create contacts only (standard fields) | Browser-safe, can appear in page source |
Privileged fields and publishable keys
If a publishable key sends a privileged field (such as tags or assigneeId), the field is silently ignored and returned to you in the ignoredFields array of the response. The contact is still created from the standard fields. See the field reference for which fields are privileged.
Create a contact
/public/v1/contactsCreates a single contact. Requires at least one of email, phone, or name. Works with both key types (publishable keys are limited to standard fields).
curl https://api.zoye.io/public/v1/contacts \
-H "Authorization: Bearer zk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Jordan Rivera",
"email": "jordan@northwind.com",
"phone": "+1 555 0100",
"company": "Northwind Inc",
"position": "Head of Ops",
"type": "person",
"source": "website-form",
"notes": "Asked about the Growth plan",
"customFields": { "Budget": "5k-10k" },
"tags": ["inbound", "priority"]
}'{
"id": "ctc_9aZ2bQ",
"created": true,
"ignoredFields": [],
"unresolvedCustomFields": []
}ignoredFields lists any privileged fields dropped because the key was publishable. unresolvedCustomFields lists any custom-field labels that did not match an existing custom field in your workspace.
Create contacts in batch
/public/v1/contacts/batchCreates up to 100 contacts in one request. Send a contacts array of the same objects you would post to the single endpoint.
curl https://api.zoye.io/public/v1/contacts/batch \
-H "Authorization: Bearer zk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{ "name": "Jordan Rivera", "email": "jordan@northwind.com" },
{ "name": "Sam Lee", "email": "sam@globex.com", "company": "Brightwave" }
]
}'{
"total": 2,
"succeeded": 2,
"results": [
{ "id": "ctc_9aZ2bQ", "created": true },
{ "id": "ctc_7bY1cR", "created": true }
]
}Search contacts
/public/v1/contactsSearch your contacts. Requires a secret key. Supports these query parameters:
q- free-text search across name, email, company.email- exact email match.limit- page size (default and max set by your plan).offset- number of results to skip, for pagination.
curl "https://api.zoye.io/public/v1/contacts?q=northwind&limit=20&offset=0" \
-H "Authorization: Bearer zk_live_YOUR_KEY"{
"data": [
{ "id": "ctc_9aZ2bQ", "name": "Jordan Rivera", "email": "jordan@northwind.com" }
],
"total": 1,
"limit": 20,
"offset": 0
}Get a contact by id
/public/v1/contacts/:idReturns the full contact record. Requires a secret key.
curl https://api.zoye.io/public/v1/contacts/ctc_9aZ2bQ \
-H "Authorization: Bearer zk_live_YOUR_KEY"Inspect your key
/public/v1/whoamiReturns metadata about the key you authenticated with. Handy for confirming a key is wired up and which capabilities it has.
curl https://api.zoye.io/public/v1/whoami \
-H "Authorization: Bearer zk_live_YOUR_KEY"{
"keyType": "secret",
"scopes": ["contacts:create", "contacts:read", "contacts:search"],
"projectId": "prj_4tH8mN",
"rateLimitTier": "growth"
}Fields
For the complete list of fields you can send on a contact, their types, and which key types can write each one, see the field reference.