Skip to Content
APIReferenceRegistrations

Registrations

A registration is one person signing up for one event.

Archived registrations are not returned. Archiving is how the Novex UI removes a registration, so an archived row disappears from both GET /registrations and GET /registrations/{id} — the detail route returns 404. There is no way to read an archived registration through the API.

GET /registrations

curl -sS "https://nov3x.com/api/public/v1/registrations?eventId=clx1234567890" \ -H "Authorization: Bearer nvx_live_your_key_here"

Scope: registration.read

Query parameters

ParameterTypeNotes
limitintegerPage size, 1–100. Defaults to 25.
cursorstringFrom the previous response’s meta.cursor.
updatedSinceISO 8601Only registrations updated at or after this instant.
eventIdstringRestrict to one event.
statusstringFilter by registration status.

POST /registrations

Create a registration for an event. This is the same path the public registration form takes, so capacity, waitlist, plan limits, duplicate detection and the organiser’s own custom fields all behave exactly as they do on the form — because it is the same code underneath, not a second implementation.

curl -sS -X POST "https://nov3x.com/api/public/v1/registrations" \ -H "Authorization: Bearer nvx_live_…" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "eventId": "clx1234567890", "name": "Aisha Rahman", "email": "aisha@acme.example", "company": "Acme" }'

Scope: registration.write · Rate limit: 120/min (the write ceiling) · Idempotency-Key required — see Idempotency.

Body

FieldTypeNotes
eventIdstringRequired. The event to register for.
namestringRequired. Up to 200 characters.
emailstringRequired. Up to 320 characters.
formIdstringOptional when the event has exactly one open registration form. Required when it has several — see below.
phonestringE.164 preferred.
salutationstringFeeds the email greeting.
companystring
jobTitlestring
countrystring
citystring
languagestringThe attendee’s language, used for their confirmation email.
ticketTypeIdstringMust belong to this event.
customFieldsobjectThe organiser’s own form fields, keyed by field id. Required fields are enforced; an unknown key is ignored.
notifybooleanDefaults to true. Set false for a bulk import of historical attendees, which must not email everyone.

Which form?

An event can have more than one registration form (a delegate form and a speaker form, say). When exactly one is open, you may omit formId and we use it. When several are open, formId is required and omitting it returns 422 — which form an attendee belongs to is not something we can guess for you.

Responses

StatusMeaning
201Created. The body is the registration, in the same shape the GET routes return.
202The event was full and has a waitlist, so the attendee was waitlisted. data.status is WAITLISTED — do not tell them they have a seat.
404No such event in your workspace, or it is archived, cancelled or postponed.
409See the table below — branch on error.code, not on the status.
422The body failed validation, a required custom field is missing, or the event has several forms and you named none.

409 codes

error.codeWhat happened
EVENT_FULLAt capacity with no waitlist configured.
DUPLICATE_REGISTRATIONThis person is already registered for this event.
PLAN_LIMIT_REACHEDThe workspace has hit its plan’s registration limit for this event.
IDEMPOTENCY_KEY_REUSEDThe key was used for a different request body.
IDEMPOTENCY_REQUEST_IN_PROGRESSThe original request under this key is still running.
IDEMPOTENCY_RESPONSE_UNAVAILABLEThe original response was too large to store for replay.

A new Idempotency-Key will not clear the first three. They are properties of the event or the attendee, not of your request: raise the capacity, enable the waitlist, or check whether the person is already in.

Duplicates

A registration is refused as a duplicate when the name, email and phone all match an existing active registration for the same event. Several people legitimately share one email address — a company admin registering colleagues, a family — so an email-only match would drop real attendees.

Confirmation email

By default the attendee gets the same confirmation email and QR badge the public form sends. Pass "notify": false to suppress it.

We do not record marketing consent through this endpoint, and there is no field for it. Consent has to be something the person actually gave; a flag set by an integrator is not that, and it would be indistinguishable from a real one afterwards.

GET /registrations/{id}

Returns 404 if the registration is not in your workspace.

Fields

FieldTypeNotes
idstringStable identifier
eventIdstringThe event this registration belongs to
statusstringe.g. CONFIRMED
namestringAttendee name
emailstringAttendee email
checkedInbooleanWhether they have been checked in
checkedInAtISO 8601 or nullWhen, or null if not checked in
createdAtISO 8601Created
updatedAtISO 8601Last modified — use for sync

POST /registrations/{id}/check-in

Marks an attendee as arrived. There is no request body — the registration id is the whole input.

Check-in is state on the registration, not a separate resource: it is an action on a registration, and you read the result back as checkedIn and checkedInAt. There is no check-in collection to list.

curl -sS -X POST \ "https://nov3x.com/api/public/v1/registrations/clx1234567890/check-in" \ -H "Authorization: Bearer [REDACTED]" \ -H "Idempotency-Key: 8f14e45f-ea0a-4c1b-9a6e-0d1c2b3a4e5f"

Scope: registration.checkin — deliberately narrower than registration.write. A badge or kiosk vendor can check attendees in without gaining the ability to create registrations.

The Idempotency-Key header is required. A write without one is refused with 400 IDEMPOTENCY_KEY_REQUIRED.

Returns the registration itself, in exactly the shape GET /registrations/{id} returns — so you never need a second call to see the result.

Re-scanning is safe

If the attendee is already checked in, this returns 200 with the current record, not an error, and checkedInAt keeps the instant they actually arrived. That is deliberate: a scanner at a door re-scans, retries over a flaky link, and runs two lanes against one queue. Treating a successful outcome as a conflict would turn a working door into an alerting one.

Check-in is also idempotent in the data itself — the flag only moves one way — so a duplicate scan changes nothing even if the two requests carried different keys.

When it is refused

StatusCodeWhen
404NOT_FOUNDNo such registration in your workspace, or it is archived.
409REGISTRATION_NOT_CHECKABLEThe booking is not CONFIRMED: it is CANCELED, REJECTED, WAITLISTED or NO_SHOW.

Only a CONFIRMED booking can be checked in. The 409 carries the reason in error.details.reason — one of canceled, rejected, waitlisted or no_show — so your scanner can tell the person at the door why.

This is the same rule every Novex check-in uses: the kiosk, the staffed scanner, the offline kiosk and the registration page all refuse the same bookings. There is no override flag. To admit someone whose booking is not confirmed — a waitlisted guest you have a seat for, a no-show who turns up late — change the booking’s status to CONFIRMED in Novex first, then check them in with a new Idempotency-Key.

⚠️ A 409 REGISTRATION_NOT_CHECKABLE is remembered against your Idempotency-Key. So if you confirm the booking and retry with the same key, you get the stored refusal back rather than a fresh attempt. Retry with a new key after correcting the cause. This is also why you should derive the key from the attempt — a fresh UUID per scan — rather than from the registration id: a key derived from the record inherits the record’s history.

What is not exposed

The endpoint records who performed the check-in in your workspace’s audit trail, not on the registration. An API call has no Novex user behind it, so no staff member is named — and the internal staff-user field is not part of any public payload in the first place.

What it does not do

Nothing else. A check-in through the API does exactly what a check-in at the kiosk does: it writes the record and an audit entry. No email, no notification, no webhook — the desk does not send one either, and an integration should not quietly do more than the product does.

⚠️ Badge QR tokens are never returned by this API. A badge token is the entire credential for that badge — anyone holding it could present it and be checked in — so it is not part of any public payload, by design.

What is not included

Attendee phone, company, job title, country and city are stored in Novex but are not returned by this API in v1. We expose the minimum that makes the resource useful. If your integration genuinely needs more, tell us — adding a field is a non-breaking change, so we can do it without a new version.

Last updated on