Interaction
Object Shape
An interaction object will always have this shape when not embedded into other objects:
{
"id": "integer",
"_type": "string",
"firstDelegate": "object:delegate",
"secondDelegate": "object:delegate",
"thirdDelegate": "object:delegate",
"firstDevice": "object:device",
"secondDevice": "object:device",
"thirdDevice": "object:device",
"interactionType": "string",
"data": "object",
"recordedAt": "string",
"createdAt": "string",
"updatedAt": "string"
}
The data property inside the interaction object does not have a configurable structure and will depend on the type
of interaction. For example a lead interaction will have all answers loaded in this property.
Posting Form Answers
When an interaction captures a form submission (for example a lead capture, a poll vote, a registration form
or any custom form-based interaction), answers must be posted following the convention below. The backend will
automatically reshape them into the structures expected by reporting, exports and downstream consumers.
This convention applies to every source — REST API, mobi/rego sites, portal, batch imports, when-then actions — because the reshaping happens in a single event subscriber, regardless of where the interaction was created.
Input shape
Send the form payload inside the interaction’s data property:
{
"firstDelegate": 789,
"firstDevice": 85,
"data": {
"form": "leadcapture",
"answers": [
{
"field": "name",
"fieldLabel": "Full Name",
"fieldType": "text",
"answer": "Jane Doe"
},
{
"field": "company",
"fieldLabel": "Company",
"fieldType": "text",
"answer": "Acme Corp"
},
{
"field": "contact.email",
"fieldLabel": "Email Address",
"fieldType": "email",
"answer": "jane@satellite.test"
},
{
"field": "contact.phone",
"fieldLabel": "Phone Number",
"fieldType": "tel",
"answer": "+64 21 555 0000"
}
]
}
}
Required keys inside data:
form— a string identifier for the form (used to disambiguate when an interaction type has multiple forms).answers— a flat list of answer objects.
Each answer object supports:
Key |
Required |
Description |
|---|---|---|
|
yes |
The field path. Use dot-notation ( |
|
yes |
The submitted value (string, number, boolean, array — whatever the field type produces). |
|
no |
Human-readable label. Used as the key in |
|
no |
The form field type ( |
How the backend reshapes the payload
After the interaction is received, the original data is augmented with two derived structures:
answersData— the answers reassembled into a nested object that mirrors the dot-notation paths. Use this when reading answers programmatically.reportData— a flatlabel => valuemap. Use this for exports, CSV/XLSX downloads and reports where the human-readable label is what matters.
The original form and answers keys are preserved untouched.
Given the request above, the stored data becomes:
{
"form": "lead-capture",
"answers": [
{ "field": "name", "fieldLabel": "Full Name", "fieldType": "text", "answer": "Jane Doe" },
{ "field": "company", "fieldLabel": "Company", "fieldType": "text", "answer": "Acme Corp" },
{ "field": "contact.email", "fieldLabel": "Email Address", "fieldType": "email", "answer": "jane@acme.test" },
{ "field": "contact.phone", "fieldLabel": "Phone Number", "fieldType": "tel", "answer": "+64 21 555 0000" }
],
"answersData": {
"name": "Jane Doe",
"company": "Acme Corp",
"contact": {
"email": "jane@acme.test",
"phone": "+64 21 555 0000"
}
},
"reportData": {
"Full Name": "Jane Doe",
"Company": "Acme Corp",
"Email Address": "jane@acme.test",
"Phone Number": "+64 21 555 0000"
}
}
Notes and gotchas
Always send the flat
answersarray. Do not pre-buildanswersDataorreportData— the subscriber will skip reshaping ifanswersDatais already present in the payload, leaving an inconsistent record.Field paths are dot-separated, not bracketed. Use
contact.email, notcontact[email].Answers without a
fieldare silently skipped; make sure every answer object has one.formis required for the reshaping to run. An interaction withanswersbut noformwill be stored as-is, with noanswersData/reportData.The convention is the same for
POST /interaction/new/{type}andPOST /interaction/batch.
Interaction Types
This list will be updated, it’s NOT UP TO DATE.
A non exhaustive list of the standard interactions is:
- check-in
Indicates someone has checked in into a session or interacted with any device. It’s the most common action you can use anywhere you don’t need to define custom behaviour or attach complex data to it.
- check-out
The opposite of a check-in, when someone leaves a session. Currently used to enable “single-entry” sessions.
- join
Usually referred to a session, it’s a broad term and generally means that delegate is supposed to show up at a particular session or that they are allowed into such session.
- booking, cancel-booking
These events allow you to book devices. The device you can book should be of a bookable type but this is not enforced. This has been used only for the meeting tables feature so far.
- invite, uninvite, notify-invitees
These actions are used to invite delegates to a session and/or to notify them. This most likely requires some custom logic that can be added to the AppBundle.
Some interaction types we’ve used so far are summarised below:
Interaction |
Description |
|
|---|---|---|
check-in |
R M S |
A delegate shows up (physically) to an event or session |
check-out |
M S |
A delegate leaves an event or session |
join |
R M S |
A delegate is allowed to, has booked or is assigned to an event, session, … |
seen |
U |
A delegate has been seen at an event or session (usually by a UHF reader) |
entered |
U |
A delegate has entered an area (usually based on where they’ve been seen) |
exited |
U |
A delegate has left an area (usually based on where they’ve been seen) |
connect |
S |
A delegate sends a connection request |
connected |
S |
A delegate has connected with someone (usually when both reciprocally connect) |
booking |
S |
A delegate has booked something like a meeting, session, … |
cancel-booking |
S |
A delegate has cancelled a booking |
invite |
S |
A delegate has invited someone to something |
uninvite |
S |
A delegate has uninvited someone he previously invited |
notify-invitee |
S |
A delegate asks to notify an invitee about something |
order |
M S |
A delegate orders something, usually a drink |
order-processing |
S |
A delegate’s order is being processed |
order-cleared |
S |
A delegate’s order has been completed (usually this fires a text message) |
download |
M S |
A delegate requests to download something |
downloaded |
M S |
A delegate has downloaded something |
upload |
M |
A delegate uploads something |
feedback |
S |
A delegate sends their feedback |
competition |
S |
A delegate enters a competition |
voucher |
S |
A delegate consumes a voucher |
question |
S |
A delegate asks a question |
lead |
M |
A delegate records a lead |
poll-vote |
S |
A delegate votes in a poll |
own |
M S |
A delegate owns a device (usually for sponsors, to identify staff members) |
R |
A delegate’s badge has been printed (usually from the registration app) |
GET /interaction/list
Get the list of interactions matching the specified query.
Note
This method supports pagination.
Use limit and offset to paginate returned results. The defaults if no limit or offset are provided are limit=5000 and offset=0.
GET /interaction/list?offset=0&limit=5000
The total result set count is returned in all responses in the meta property. Links to the next or previous page
are also provided in the same property.
Searching interactions
Pass a search query parameter with a JSON expression to filter the list. See Searching lists for the full
operator reference.
Category |
Fields |
|---|---|
Direct fields |
|
Relations (by ID) |
|
Interaction filters |
Not supported. Using |
Filter by interaction type:
GET /interaction/list?search={"==":["interactionType","check-in"]}
Check-ins for a specific delegate:
GET /interaction/list?search={"and":[{"==":["interactionType","check-in"]},{"==":["firstDelegate",789]}]}
Interactions for a specific device:
GET /interaction/list?search={"==":["firstDevice",85]}
Multiple interactions by ID:
GET /interaction/list?search={"in":["id",[101,102,103]]}
POST /interaction/new/{interactionType}
Creates a new interaction.
See the list of Error Responses for more information, in particular error 1301, 1401, 1501, 1502, 1503.
Some examples for common interactions:
POST /interaction/new/check-in
POST /interaction/new/join
POST /interaction/new/lead
POST /interaction/new/print
Example request to check-in a delegate into a session:
POST /interaction/new/check-in
{
"firstDelegate": 789,
"firstDevice": 85,
"recordedAt": 1696185089
}
Or, because only one delegate and one device are involved:
{
"delegate": 789,
"device": 85,
"recordedAt": 1696185089
}
Example response:
{
"data": {
"id": 89027,
"_type": "interaction",
"firstDelegate": {
"id": 789,
"_type": "delegate"
},
"firstDevice": {
"id": 6,
"_type": "device"
},
"interactionType": "check-in",
"recordedAt": "2018-03-13T23:31:16+00:00",
"createdAt": "2018-03-13T23:31:32+00:00",
"updatedAt": "2018-03-13T23:31:32+00:00"
},
"meta": {}
}
POST /interaction/test/{interactionType}
Tests if creating an interaction with the given parameter would succeed or not. This can be used for example to validate tickets before using them.
See the list of Error Responses for more information, in particular error 1301, 1401, 1501, 1502, 1503.
Example request to check-in a delegate into a session:
POST /interaction/test/check-in
{
"firstDelegate": 789,
"firstDevice": 85,
"recordedAt": 1696185089
}
Or, because only one delegate and one device are involved:
{
"delegate": 789,
"device": 85,
"recordedAt": 1696185089
}
Example response:
{
"data": {
"id": null,
"_type": "interaction",
"firstDelegate": {
"id": 789,
"_type": "delegate"
},
"firstDevice": {
"id": 6,
"_type": "device"
},
"interactionType": "check-in",
"recordedAt": "2018-03-13T23:31:16+00:00",
"createdAt": "2018-03-13T23:31:32+00:00",
"updatedAt": "2018-03-13T23:31:32+00:00"
},
"meta": {}
}
Example of response in case of failure:
{
"data": {},
"meta": {
"error": {
"code": 412,
"message": "Too many interactions",
"internalCode": 740
}
}
}
DELETE /interaction/id:{id}
Delete the given interaction. Returns a no content response (status 204).
Example request to delete interaction 123:
POST /interaction/id:123
POST /interaction/batch
You can send a batch of interaction to this endpoint and they will be processed in order and a ordered collection of responses will be returned.
See the list of Error Responses for more information, in particular error 1301, 1401, 1501, 1502, 1503.
Example request:
POST /interaction/batch
{
"interactions": {
"a": {
"firstDelegate": 1,
"interactionType": "upload"
},
"b": {
"firstDelegate": 3,
"firstDevice": 123,
"interactionType": "check-in"
}
},
"sharedValues": {
"upload": "iVBORw0KGgoAA[ ... more base64 encoded stuff ... ]oI5NwAAAABJRU5ErkJggg=="
}
}