People
A person is someone your workspace knows across every event — not a registration for one event. Someone who attended three conferences is one person with three registrations.
These are the organiser’s data subjects — not ours, and not yours. Your lawful basis for holding this data, your retention period, and your erasure route are yours to hold. Reading through this API does not transfer any of that to Novex.
Two key permissions, and the difference matters
| Permission | What it returns |
|---|---|
people.read | The person: names, company, job title, country, type, consent state, first/last seen. |
people.contact.read | Adds email and phone. Nothing else. |
people.contact.read widens people.read; it does not replace it. A key
holding only the widener is refused.
⚠️ A key with
people.contact.readcan read every attendee’s email address and phone number for your whole account — not one event. Treat it like a mailing-list export credential, because that is what it is. If your integration only needs names, create a key withpeople.readalone: a leaked key of that class costs you names rather than a contact list.
Without people.contact.read, email and phone are ABSENT from the
response — not null. That is deliberate: a null would mean “this person has
no email address”, which is a fact about the person, while absence means “this
key may not see it”, which is a fact about the key. Do not treat them as the
same.
GET /people
curl -sS "https://nov3x.com/api/public/v1/people?marketingOptedOut=false" \
-H "Authorization: Bearer [REDACTED]"Query parameters
| Parameter | Type | Notes |
|---|---|---|
limit | integer | Page size, 1–100. Defaults to 25. |
cursor | string | From the previous response’s meta.cursor. |
updatedSince | ISO 8601 | Only people updated at or after this instant. An unparseable value is rejected with 400. |
personType | string | One of ATTENDEE, GUEST, VIP. Any other value is rejected with 400. |
eventId | string | Only people with a registration for that event. |
marketingOptedOut | boolean | false gives you the contactable set. |
There is no free-text search and no email= lookup, deliberately. An
address-lookup endpoint answers “is this person in your database” at scale, and
a rate limit is not the right control for that question.
GET /people/{id}
Returns 404 if the person is not in your workspace, is archived, or has been
quarantined by our identity system.
Consent and opt-outs
Consent status is reported, never inferred. UNKNOWN is not permission.
People who have opted out of marketing are returned, and flagged — they are not hidden from you. That is on purpose: an opt-out that disappears from your copy is an opt-out you will re-import from somewhere else and act on.
| Field | Meaning |
|---|---|
marketingOptedOut | true when this person withdrew consent. Check this one. |
marketingOptedOutAt | When they withdrew it, or null. |
consentStatus | UNKNOWN, GRANTED or WITHDRAWN — kept alongside because marketingOptedOut: false conflates “said yes” with “nobody ever asked”. |
The flag is named marketingOptedOut and not optedOut because it is the
narrower claim: it is about marketing, not about all contact.
Names, Arabic and Latin
Arabic names are recorded, not generated. Do NOT transliterate one. Where
nameAr is absent there is no Arabic name for that person. The Latin name may
itself be a transliteration and is never an authority for the Arabic spelling.
| Field | Notes |
|---|---|
name | The authoritative display string. |
firstName, middleName, lastName | The Latin parts. The middle name is not optional detail — in this market it is the patronymic, and a badge printed from first + last stops matching the person’s ID document. |
nameAr, firstNameAr, middleNameAr, lastNameAr | The Arabic equivalents. |
nameStructured | The switch. When false, the parts have not been split for this person: use name and ignore them. |
When rendering, put Arabic and Latin fields in separate directional contexts rather than concatenating them into one string.
GET /people/removals
curl -sS "https://nov3x.com/api/public/v1/people/removals?since=2026-09-01T00:00:00Z" \
-H "Authorization: Bearer [REDACTED]"Returns { id, removedAt } and no personal data — a tombstone is not a place
to re-disclose someone.
You need this endpoint. A person who is removed simply stops appearing in
GET /people, and a delta sync cannot tell “removed” from “unchanged”. Without polling this feed your copy keeps every person we removed, for ever.
⚠️ Removals do NOT appear in
updatedSince. Poll this feed separately, and reconcile against the full list periodically.
⚠️ A removal can appear more than once. Person has no dedicated
“removed at” column, so the feed keys on last-modified: any later edit to an
already-removed person re-emits its tombstone on your next incremental poll.
Deleting a copy you have already deleted is harmless — treat tombstones as
idempotent — but do not treat a repeat as a new event.
⚠️ removedAt is when we recorded the removal, not a guaranteed instant of
deletion. The feed never misses a removal inside your window; it can occasionally
report one twice, and deleting a copy you have already deleted is harmless. Do
not build an audit claim on the exact timestamp.
What this API does not return
nationalId, gender, dietary requirements, city, internal notes, identity
verification state and consent provenance are stored in Novex and are never
returned here — each for its own reason. Dietary requirements in particular
routinely contain health and religious information, which no integration use
justifies exporting.
Erasure — read this before you build
Novex does not implement person-level erasure today, and this API does not pretend otherwise. The endpoints return only non-archived, non-quarantined people; subject-level erasure is currently handled at the workspace level.
Your mirror is outside our reach entirely. When you copy this data into your system, honouring a person’s erasure request there is your obligation, not ours. The removals feed is the signal you need in order to meet it.
Where this data goes
Reading through this API can move personal data outside Saudi Arabia, and the transfer obligation sits with the organiser whose workspace it came from.
Organisers can see every call: Settings → Audit shows the API key by name, the source IP, the time, and — for calls that returned contact details — how many records were read.