Skip to main content

Screening completed

Type: com.auditdata.listo.screening.completed.v1 Emitted when: The Listo iPad app submits a finished screening session and the Listo backend successfully persists it.

This is the only event type emitted in v1. There are no update events, no deletion events, and no lifecycle events.

Envelope

The envelope follows the standard described on Envelope. The envelope is present on Service Bus deliveries only; the Sessions API returns the screening payload directly without the envelope.

For this event type:

AttributeValue
specversion"1.0"
type"com.auditdata.listo.screening.completed.v1"
datacontenttype"application/json"
sourceStable per environment, e.g. "https://api.<environment>/screener"

Payload schema

New optional fields may be added to this payload within the .v1 type without a version bump. Existing fields will not change meaning, type, or required-ness within .v1. See Versioning & compatibility.

The data field carries the full screening session. Fields are grouped below by topic; the flat, exhaustive table is at Data schema reference.

All field names are camelCase. All timestamps are RFC 3339 date-times. testTime and emailSentDateTime preserve the offset they were recorded with (matching the underlying datetimeoffset storage) and may carry any offset — e.g. 2026-05-08T11:25:33+02:00. birthday is emitted at midnight UTC (1972-11-04T00:00:00Z). All identifiers are either UUIDs or signed integers as documented per field.

Identifiers

FieldTypeNullableNotes
idintegernoListo's database ID for the session. Stable across the Sessions API and redelivery. Use as your primary application-level idempotency key.
tenantIdstring (UUID)noThe Tenant that owns this session. Matches one of the TenantIds linked to your account.

Patient demographics

All fields in this group are nullable strings unless noted. Fields are captured by the iPad app at intake; what's filled in depends on the tenant's configured intake flow.

FieldTypeNullableNotes
firstnamestringyesUp to 100 characters.
lastnamestringyesUp to 100 characters.
titlestringyesUp to 50 characters. Free-form (e.g. "Mr.", "Dr.").
emailstringyesUp to 100 characters. Not validated as RFC 5321 — may be free text.
phonestringyesUp to 50 characters. Free-form, no canonical format.
birthdaystring (RFC 3339 date-time)yesThe patient's birth date. Emitted as an RFC 3339 date-time at midnight UTC, e.g. "1972-11-04T00:00:00Z". The time component is always 00:00:00Z; the date is the meaningful part.

Office and location

The location where the session was performed.

FieldTypeNullableNotes
officeIdintegernoListo's internal office ID.
officeNamestringyesUp to 200 characters.
officeExternalIdstringyesThe tenant's own ID for the office, if integrated.
officeExternalAltIdstringyesAlternate external ID, if integrated.

Device, transducer, and test flow

What hardware and configuration produced the result.

FieldTypeNullableNotes
deviceTypestringyesFree-form device-type string.
deviceNamestringyesUp to 100 characters. The device's display name.
transducerNamestringyesUp to 50 characters. The headphones / transducer model.
testFlowNamestringyesUp to 250 characters. The display name of the configured test flow.

Test results

The numerical outcome of the screening.

FieldTypeNullableNotes
leftTestResultintegernoCoded outcome for the left ear. See Test result codes below.
rightTestResultintegernoCoded outcome for the right ear. See Test result codes below.
stimulusTypeintegernoCoded stimulus presented to the patient. See Stimulus type codes below.
noiseLevelstringyesCoded ambient-noise level reported by the iPad. One of "1", "2", "3" — see Noise level codes below.

Test result codes

A coded summary of one ear's screening outcome. Set independently for left and right ears (leftTestResult, rightTestResult).

ValueMeaning
0Unknown / not computed.
1Normal hearing.
2Some hearing loss.
3Significant hearing loss.

New result codes can appear in future versions; default to "unknown" in your handler.

Stimulus type codes

The kind of acoustic stimulus presented to the patient.

ValueMeaning
0Unknown.
1Tone — pure tone.
2Pulse — pulsed tone.
3Warble — frequency-modulated tone.
4PulseWarble — pulsed warble tone.

Treat unknown integer values as opaque codes; the meanings above reflect the v1 deployment.

Noise level codes

The iPad's reported ambient-noise level. Stored as a string in the database; values come from a fixed set chosen at intake.

ValueMeaning
"1"Silent.
"2"Some noise.
"3"A lot of noise.

Treat unknown string values as opaque; the values above reflect the v1 intake configuration.

Audiograms

There are three audiogram-shaped objects on the payload — two measured audiograms (one per ear) and the noise-correction baseline.

Each is an object of the form:

{
"f250": null,
"f500": 15,
"f1000": 20,
"f2000": 25,
"f4000": 30,
"f6000": null,
"f8000": 35
}

Every field is a nullable integer in dB at the labelled frequency in Hz. A null value means "no threshold available at this frequency" (frequency wasn't tested, no response, or out of range). The seven frequencies are fixed and complete — there are no more, no fewer.

FieldTypeNullable (object)Meaning
leftAudiogramobjectno (object always present)Measured thresholds for the left ear.
rightAudiogramobjectnoMeasured thresholds for the right ear.
noiseCorrectionobjectnoThe ambient-noise baseline subtracted from raw measurements.

The audiogram object itself is always present; individual frequency values inside it are nullable.

All consent fields are nullable integers. The encoding is:

ValueMeaning
0Refused
1Granted
nullNot asked / not applicable for this tenant's intake flow
FieldNotes
consentAgreeWithTermsConditionsAgreed to terms and conditions.
consentContactEmailConsents to be contacted by email.
consentContactPhoneConsents to be contacted by phone.
consentCustom1Tenant-defined custom consent slot 1. Meaning is configured per tenant.
consentCustom2Tenant-defined custom consent slot 2.
consentCustom3Tenant-defined custom consent slot 3.

Status and timestamps

Lifecycle timestamps. All RFC 3339 date-times.

FieldTypeNullableNotes
testTimestring (RFC 3339)noWhen the screening was performed on the iPad. The offset is preserved as recorded by the device (e.g. 2026-05-08T11:25:33+02:00); not normalized to UTC. This is the field the Sessions API filters on.
emailSentDateTimestring (RFC 3339)yesWhen the patient-facing results email was sent. The offset is preserved as recorded (e.g. 2026-05-08T11:30:14+02:00); not normalized to UTC. null on the Service Bus event — email sending is async and runs after the event is published. The Sessions API returns the accurate value once the email has been dispatched.
emailStatusstringyesEmail delivery status. One of "Sent", "Failed", or null (not attempted). null on the Service Bus event for the same reason; the Sessions API returns the accurate value once the email has been dispatched.

Complete worked example (Service Bus envelope)

The example below is the full CloudEvent as it arrives on Service Bus — envelope plus screening payload. The Sessions API returns just the contents of data directly under each items[i], with no envelope wrapper around it.

{
"specversion": "1.0",
"id": "7c4e6a41-7e70-4f3d-9e24-1c3f0c1c2a01",
"source": "https://api.<environment>/screener",
"type": "com.auditdata.listo.screening.completed.v1",
"time": "2026-05-08T09:30:12Z",
"datacontenttype": "application/json",
"data": {
"id": 1138291,
"tenantId": "0d3e2b51-4e7a-44b6-8d5e-1c3a9b2f7c40",

"firstname": "Avery",
"lastname": "Larsen",
"title": "Ms.",
"email": "avery.larsen@example.org",
"phone": "+45 12 34 56 78",
"birthday": "1972-11-04T00:00:00Z",

"officeId": 9412,
"officeName": "Hearing & Co. Copenhagen Central",
"officeExternalId": "HC-CPH-CENTRAL",
"officeExternalAltId": null,

"deviceType": "iPad",
"deviceName": "Listo-iPad-04",
"transducerName": "Sennheiser HDA 280",
"testFlowName": "Standard adult — 7 frequency",

"leftTestResult": 1,
"rightTestResult": 2,
"stimulusType": 0,
"noiseLevel": "2",

"leftAudiogram": {
"f250": 10, "f500": 15, "f1000": 20,
"f2000": 25, "f4000": 30, "f6000": null, "f8000": 35
},
"rightAudiogram": {
"f250": 5, "f500": 10, "f1000": 15,
"f2000": 20, "f4000": 30, "f6000": 35, "f8000": 40
},
"noiseCorrection": {
"f250": 5, "f500": 0, "f1000": 0,
"f2000": 0, "f4000": 0, "f6000": 0, "f8000": 5
},

"consentAgreeWithTermsConditions": 1,
"consentContactEmail": 1,
"consentContactPhone": 0,
"consentCustom1": 1,
"consentCustom2": null,
"consentCustom3": null,

"testTime": "2026-05-08T11:25:33+02:00",
"emailSentDateTime": null,
"emailStatus": null
}
}

Where to next