Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Bluzone exposes a REST API that provides a user with the Distance Tracking and Contact Tracing data of their applicable deviesdevices. The Distance Tracking data is provided by beacons that are configured to emit Distance Tracking packets, while the Contact Tracing data can be provided by these same beacons as well as by the geofence history of a specific beacon. The various APIs for obtaining this data are provided below.

...

Type

Name

Required

Description

Schema

Default

Path

projectId

YES

The ID of the project, e.g. 111

int


Body

start

YES

The start date of the desired time range, in ISO8601 RFC339Nano format

string

Body

end

YES

The end date of the desired time range, in ISO8601 RFC339Nano format

string

...

Response

...

Field Name

Nested Field Name

Description

Schema

population

The number of unique beacons observed within the requested time range

uint32

compliant

The percentage of unique beacon without any Distance Tracking Violations within the requested time range

float

violations

The number of Distance Tracking Violations observed within the requested time range

uint32

uniqueDevices

The number of unique devices that have violated a Distance Tracking Violation within the requested time range

uint32

recent

An array of objects whose fields detail the recent Distance Tracking Violations by hour for the requested time range

[]DistanceViolationRollup

interval

The rollup interval. Only HOURLY is available for now.

enum {
HOURLY
}

timestamp

The timestamp of the rollup, formatted according to RFC3339

String

population

The number of unique devices observed within this rollup

uint32

violations

The number of Distance Tracking Violations within this rollup

uint32

uniqueViolations

The number of unique devices which had at least one violation within this rollup

uint32

todaysViolations

An array of objects whose fields detail the location and corresponding count of Distance Tracking Violations for the requested time range

[]DistanceViolationAggregation

lat

If RTLS is enabled for the project which the requested beacon belongs to, it is the latitude of the location of the last-known location at time of write. Otherwise, it is the latitude of the first Blufi to report this event at time of write.

double

lng

If RTLS is enabled for the project which the requested beacon belongs to, it is the longitude of the location of the last-known location at time of write. Otherwise, it is the longitude of the first Blufi to report this event at time of write.

double

count

The amount of Distance Tracking Violations at this location

uint32

topViolatingBeacons

An array of objects detailing the amount of Distance Tracking Violations per each device for the requested time range, sorted by count, descending

[]DistanceViolationBeacon

id

The device ID

String

violationCount

The amount of Distance Tracking Violations

uint32

topViolatingAreas

An array of objects detailing the amount of Distance Tracking Violations per each location for the requested time range, sorted by count, descending

[]DistanceViolationLocation

name

The location name

String

id

If RTLS is enabled for the project which the requested beacon belongs to, it is the ID of the location of the last-known location at time of write. Otherwise, it is the ID of the location of the first Blufi to report this event at time of write.

uint64

violationCount

The amount of Distance Tracking Violations

uint32

Sample Response

Code Block
{
  "population": 46, //The number of unique devices observed by Bluzone
  "compliant": 71.73913, //The percent of unique devices that do not have an associated Distance Tracking violation
  "violations": 26, //The number of Distance Tracking violations observed
  "uniqueDevices": 13, //The number of unique devices for which Bluzone observed a Distance Tracking violation
  "recent": [
    //Each entry is an hourly report of the observed population, violations, and unique devices with violations
    {
      "latinterval": 30.412875"HOURLY",
      "lngtimestamp": -97.666004"2020-07-16T18:00:00Z",
      "countpopulation": 141,
    },  "violations": 2,
 {       "latuniqueViolations": 30.4129722
    },
    {
      "lnginterval": -97.666179"HOURLY",
      "counttimestamp": 1"2020-07-16T19:00:00Z",
    }  "population": ]40,
      "topViolatingBeaconsviolations": [1,
    //Each entry is a unique device id and the number of associated Distance Tracking violations for this device
    {
"uniqueViolations": 1
    },
    {
      "interval": "HOURLY",
      "idtimestamp": "13765822398147720762020-07-17T17:00:00Z",
      "violationCountpopulation": 1
    },
    {26,
      "idviolations": "8195029735132899180"2,
      "violationCountuniqueViolations": 12
    },
    {
 ],
    "idtodaysViolations": "14147864550494974530",[
    //Each  "violationCount": 1
    },
  ],
  "topViolatingAreas": [
    //Each entry entry is a unique Bluzone locationId, it's name, latitude/longitude tuple and the number of associated Distance Tracking violations forat thisthat location
    {
      "namelat": "My Location"30.413098,
      "locationIdlng": "111"-97.666902,
      "violationCountcount": 261
    },
    ]
}

cURL Example

Code Block
curl -X POST -H "Content-Type: application/json" -H "BZID: ABCDEFGHJILKMNOP" -d '{
	"start": "2020-05-10T14:26:26.462Z",
	"end": "2020-06-10T14:26:26.462Z"
}' "https://bluzone.io/portal/papis/dts/v1/api/dashboard/111"

Device Contact Report

Method

POST

URL

Code Block
https://bluzone.io/portal/papis/dts/v1/api/deviceContactReport/{projectId}/{deviceId}

Response Content-Type

application/json

Header

bzid

Description

Get contact report for the specified device.

Parameters

...

Type

...

Name

...

Required

...

Description

...

Schema

...

Default

...

Path

...

projectId

...

YES

...

The ID of the project, e.g. 111

...

int

...

Path

...

deviceId

...

YES

...

The ID of the device, e.g. 14458689340104137112

...

string

...

Body

...

start

...

YES

...

The start date of the desired time range, in ISO8601 RFC339Nano format

...

string

...

Body

...

end

...

YES

...

The end date of the desired time range, in ISO8601 RFC339Nano format

...

string

Sample Response

Code Block
{
  "violations": 6, //The number of Distance Tracking violations for this device
  "closeDevices": 2, //The number of unique devices that were associated with this device's Distance Trcking violations
  "recent{
      "lat": 30.412875,
      "lng": -97.666004,
      "count": 1
    },
    {
      "lat": 30.412972,
      "lng": -97.666179,
      "count": 1
    }
  ],
  "topViolatingBeacons": [
    //Each entry is a unique device id and the number of associated Distance Tracking violations for this device
    {
      "id": "1376582239814772076",
      "violationCount": 1
    },
    {
      "id": "8195029735132899180",
      "violationCount": 1
    },
    {
      "id": "14147864550494974530",
      "violationCount": 1
    },
  ],
  "topViolatingAreas": [
    //Each entry is an hourly report ofa unique Bluzone locationId, it's name, and the number of associated Distance Tracking violations for this devicelocation
    {
      "intervalname": "HOURLYMy Location",
      "timestamplocationId": "2020-07-17T12:00:00Z111", //ISO8601 RFC3339Nano
      "violationsviolationCount": 126
    },
  ]
 {
      "interval": "HOURLY",
      "timestamp}

cURL Example

Code Block
curl -X POST -H "Content-Type: application/json" -H "BZID: ABCDEFGHJILKMNOP" -d '{
	"start": "2020-0705-17T1110T14:0026:00Z26.462Z",
      "violations": 4
    },
    {
      "interval	"end": "HOURLY",
      "timestamp": "2020-0706-17T1010T14:0026:00Z26.462Z",
}'      "violations": 1
    }
  ],
  "contacts": [
    //Each entry is a report of a Contact Event (either DISTANCE for Distance Violations or GEOFENCE for a shared geofence with another device at this time)
    {
      "deviceId": "8445671781542985407", //The Bluzone deviceId of the device associated with this contact event
      "contactType": "GEOFENCE", //Type of contact (DISTANCE or GEOFENCE)
      "locationName": "BluFi062", //The name of the Bluzone geofence
      "locationId": "125303", //The Bluzone locationId
      "floor": "1", //The configured floor value of the Bluzone location
      "lastContact": "2020-07-17T04:19:33.809Z", //Last contact time with the associated device (ISO8601 RFC3339Nano)
      "durationMillis": 11873 //The total time of this contact event, in milliseconds
    },
    {
      "deviceId": "17895940144574406572",
      "contactType": "GEOFENCE",
      "locationName": "BluFi062",
      "locationId": "125303",
      "floor": "1",
      "lastContact": "2020-07-17T04:19:33.809Z",
      "durationMillis": 11873
    },
    {
      "deviceId": "17895940144574406572",
      "contactType": "GEOFENCE",
      "locationName": "BluFi062",
      "locationId": "125303",
      "floor": "1",
      "lastContact": "2020-07-17T13:30:17.532Z",
      "durationMillis": 11873
    }
  ]
}

cURL Example

Code Block
curl -X POST -H "BZID: ABCDEFGHJILKMNOP" -H "Content-Type: application/json" -d '{
	"start": "2020-06-29T22:08:18.095Z",
	"end": "2020-06-30T22:08:18.095Z"
}' "https://bluzone.io/portal/papis/dts/v1/api/deviceContactReport/111/14458689340104137112"

Distance Violation History

Method

POST

URL

Code Block
https://bluzone.io/portal/papis/dts/v1/api/deviceContactReport/{projectId}/{locationId}

Response Content-Type

application/json

Header

bzid

Description

Get the distance violation history of a Bluzone location.

Parameters

Type

Name

Required

Description

Schema

Default

Path

projectId

YES

The ID of the project, e.g. 111

int

Path

locationId

YES

The ID of the location, e.g. 1443

int

Body

start

YES

The start date of the desired time range, in ISO8601 RFC339Nano format

string

Body

end

YES

The end date of the desired time range, in ISO8601 RFC339Nano format

string
"https://bluzone.io/portal/papis/dts/v1/api/dashboard/111"

...

Device Contact Report

Method

POST

URL

Code Block
https://bluzone.io/portal/papis/dts/v1/api/deviceContactReport/{projectId}/{deviceId}

Response Content-Type

application/json

Header

bzid

Description

Get contact report for the specified device.

Parameters

Type

Name

Required

Description

Schema

Default

Path

projectId

YES

The ID of the project, e.g. 111

int


Path

deviceId

YES

The ID of the device, e.g. 14458689340104137112

string

Body

start

YES

The start date of the desired time range, in ISO8601 RFC339Nano format

string

Body

end

YES

The end date of the desired time range, in ISO8601 RFC339Nano format

string

Response

Field Name

Nested Field Name

Description

Schema

violations

The number of Distance Tracking Violations for the requested device within the requested time range

uint32

closeDevices

The number of unique devices that were associated with the requested device for the requested time range

uint32

recent

An array of objects detailing an hourly report of the number of Distance Tracking Violations for the requested device for the requested time range

[]DeviceContactReportRollup

interval

The rollup interval. Only HOURLY is available for now.

enum {
HOURLY
}

timestamp

The timestamp of the rollup, formatted according to RFC3339

String

violations

The number of Distance Tracking Violations within this rollup

uint32

contacts

An array of objects detailing the contact events for the requested device for the requested time range

[]DeviceContactReportEvent

devceId

The device ID of the participating beacon (the “seen” beacon by the requested beacon)

String

contactType

The Contact Type of the event; either DISTANCE or GEOFENCE

enum {
DISTANCE,
GEOFENCE
}

locationName

The name of the location at which this contact event occurred at time of write.

If this is a GEOFENCE event, it is the name of the location of the geofence at time of write.

If this is a DISTANCE event:

If RTLS is enabled for the project which the requested beacon belongs to, it is the name of the last-known location at time of write of the event. Otherwise, it is the name of the location of the first Blufi to report this event at time of write.

String

locationId

The ID of the location at which this contact event occurred at time of write.

If this is a GEOFENCE event, it is the location ID of the geofence at time of write.

If this is a DISTANCE event:
If RTLS is enabled for the project which the requested beacon belongs to, it is the ID of the last-known location at time of write of the event. Otherwise, it is the ID of the location of the first Blufi to report this event at time of write.

uint64

floor

The floor number of the location at which this contact event occurred at time of write.

If this is a GEOFENCE event, it is the floor number of the geofence at time of write.

If this is a DISTANCE event:

If RTLS is enabled for the project which the requested beacon belongs to, it is the floor number of the last-known location at time of write of the event. Otherwise, it is the floor number of the location of the first Blufi to report this event at time of write

uint64

lastContact

The timestamp of the last contact between the requested device and the participating device, formatted according to RFC3339

String

durationMillis

The duration of this contact event, in milliseconds

uint64

contactStart

The timestamp of the beginning of contact between the requested device and the participating device, formatted according to RFC3339

String

uuid

The UUID of this contact event

String (UUID)

deviceName

The name of the participating device at time of write

String

geofenceId

If this is a GEOFENCE event, this is the geofence ID in which this event occurred. Otherwise, it is null.

uint64

geofenceName

If this is a GEOFENCE event, this is the name of the geofence in which this event occurred. Otherwise, it is null.

String

latitude

If this is a DISTANCE event:

If RTLS is enabled for the project which the requested beacon belongs to, it is the latitude of the last-known location at time of write. Otherwise, it is the latitude of the first Blufi to report this event at time of write.

If this is a GEOFENCE event, this field is null.

double

longitude

If this is a DISTANCE event:

If RTLS is enabled for the project which the requested beacon belongs to, it is the longitude of the last-known location at time of write. Otherwise, it is the latitude of the first Blufi to report this event at time of write.

If this is a GEOFENCE event, this field is null.

double

totalContactTime

DEPRECATED, ignore

uint64

backfill

If this is a DISTANCE event:

This flag is set to true when this contact event for the requested device and participating device was received by Bluzone at least one minute after any previous contact event was received for the requested and participating devices. When this flag is true, the “offlineContactTimeSeconds” field is populated with the total accumulated contact time between the requested device and participating device while outside of Blufi coverage. If the requested device and participating device are still in contact within this same contact event when they return to Blufi coverage, the “offlineContactTime” field will continue to increase until this contact event ends.

If this is a GEOFENCE event, this field is null.

boolean

offlineContactTimeSeconds

For DISTANCE events:

This field is populated when the “backfill” flag is true, otherwise, it is null. This field is the total accumulated contact time between the requested device and participating device for this contact event while outside of Blufi coverage. If the requested device and participating device are still in contact within this same contact event when they return to Blufi coverage, this field will continue to increase until this contact event ends.

uint64

reportingBlufiId

Unimplemented, reserved for future use

uint64

reportingBlufiName

Unimplemented, reserved for future use

String

reportingBlufiLocationId

Unimplemented, reserved for future use

uint64

reportingBlufiLocationName

Unimplemented, reserved for future use

String

Sample Response

Code Block
{
  "violations": 6, //The number of Distance Tracking violations for this device
  "closeDevices": 2, //The number of unique devices that were associated with this device's Distance Trcking violations
  "recent": [
    //Each entry is an hourly report of the number Distance Tracking violations for this device
    {
      "interval": "HOURLY",
      "timestamp": "2020-07-17T12:00:00Z", //ISO8601 RFC3339Nano
      "violations": 1
    },
    {
      "interval": "HOURLY",
      "timestamp": "2020-07-17T11:00:00Z",
      "violations": 4
    },
    {
      "interval": "HOURLY",
      "timestamp": "2020-07-17T10:00:00Z",
      "violations": 1
    }
  ],
  "contacts": [
    //Each entry is a report of a Contact Event (either DISTANCE for Distance Violations or GEOFENCE for a shared geofence with another device at this time)
    {
      "deviceId": "8445671781542985407", //The Bluzone deviceId of the device associated with this contact event
      "deviceName": "My Device", //The name of the device in Bluzone
      "contactType": "DISTANCE", //Type of contact (DISTANCE or GEOFENCE)
      "locationName": "BluFi062", //The name of the Bluzone geofence
      "locationId": "125303", //The Bluzone locationId
      "floor": "1", //The configured floor value of the Bluzone location
      "lastContact": "2020-07-17T04:19:33.809Z", //Last contact time with the associated device (ISO8601)
      "durationMillis": 11873 //The total time of this contact event, in milliseconds
      "contactStart": "2020-07-17T04:19:21.936Z", //The start time of this contact event (ISO8601)
      "uuid": "d3a422b0-5db3-4189-62ed-45b6d858ecf1", //For DISTANCE events, the UUID of the close session. For GEOFENCE events, the UUID of the corresponding policy event
      "latitude": 15.139619643472987, //For DISTANCE events, the latitude of the last known RTLS location of the source beacon at the time this event was created
      "longitude": 57.13328996474993, //For DISTANCE events, the longitude of the last known RTLS location of the source beacon at the time this event was created
      "totalContactTime": 2097, //For DISTANCE events, the total accumulated close contact time across all sessions for the beacon and seen beacon, in seconds
      "backfill": true, //For DISTANCE events, whether or not this contact event happened outside of blufi coverage (offline)
    },
    {
      "deviceId": "17895940144574406572",
      "deviceName": "My Other Device", //The name of the device in Bluzone
      "contactType": "GEOFENCE",
      "locationName": "BluFi062",
      "locationId": "125303",
      "floor": "1",
      "lastContact": "2020-07-17T04:19:33.809Z",
      "durationMillis": 11873,
      "contactStart": "2020-07-17T04:19:21.936Z", //The start time of this geofence event (ISO8601)
      "uuid": "d3a422b0-5db3-4189-62ed-45b6d858ecf1", //For DISTANCE events, the UUID of the close session. For GEOFENCE events, the UUID of the corresponding policy event
      "latitude": 15.139619643472987, //The latitude of the last known RTLS location of the source beacon at the time this event was created
      "longitude": 57.13328996474993, //The longitude of the last known RTLS location of the source beacon at the time this event was created
      "geofenceId": 2, //The ID of the geofence in Bluzone
      "geofenceName": "My Geofence" //The Name of the geofence in Bluzone
    }
  ]
}

cURL Example

Code Block
curl -X POST -H "BZID: ABCDEFGHJILKMNOP" -H "Content-Type: application/json" -d '{
	"start": "2020-06-29T22:08:18.095Z",
	"end": "2020-06-30T22:08:18.095Z"
}' "https://bluzone.io/portal/papis/dts/v1/api/deviceContactReport/111/14458689340104137112"

...

Distance Violation History

Method

POST

URL

Code Block
https://bluzone.io/portal/papis/dts/v1/api/deviceContactReport/{projectId}/{locationId}

Response Content-Type

application/json

Header

bzid

Description

Get the distance violation history of a Bluzone location.

Parameters

Type

Name

Required

Description

Schema

Default

Path

projectId

YES

The ID of the project, e.g. 111

int


Path

locationId

YES

The ID of the location, e.g. 1443

int

Body

start

YES

The start date of the desired time range, in ISO8601 RFC339Nano format

string

Body

end

YES

The end date of the desired time range, in ISO8601 RFC339Nano format

string

Response

Field Name

Nested Field Name

Description

Schema

locationId

The location ID of the requested location

uint64

locationName

The name of the requested location

String

violations

The number of Distance Tracking Violations for the requested location within the requested time range

uint32

uniqueDevices

The number of unique participating beacons across all of the Distance Tracking Violations for the requested location within the requested time range

uint32

recent

An array of objects whose fields detail the recent Distance Tracking Violations by hour for the requested location within the requested time range

[]DistanceViolationHistoryRollup

interval

The rollup interval. Only HOURLY is available for now.

enum {
HOURLY
}

timestamp

The timestamp of the rollup, formatted according to RFC3339

String

violations

The number of Distance Tracking Violations within this rollup

uint32

uniqueViolations

The number of unique devices which had at least one violation within this rollup

uint32

violationsMap

An array of objects whose fields detail the location and corresponding count of Distance Tracking Violations for the requested location within the requested time range

[]DistanceViolationHistoryLocation

lat

If RTLS is enabled for the project which the requested location belongs to, it is the latitude of the location of the last-known location at time of write. Otherwise, it is the latitude of the first Blufi to report this event at time of write. Note that only events belonging to the requested location ID are included.

double

lng

If RTLS is enabled for the project which the requested location belongs to, it is the longitude of the location of the last-known location at time of write. Otherwise, it is the longitude of the first Blufi to report this event at time of write. Note that only events belonging to the requested location ID are included.

double

count

The amount of Distance Tracking Violations at this location. Note that only events belonging to the requested location ID are included.

uint32

devicesSummary

An array of objects detailing the amount of Distance Tracking Violations for each device participating in a contact event for the requested location within the requested time range, sorted by count, descending

[]DistanceViolationHistoryAggregation

id

The device ID

String

violationCount

The amount of Distance Tracking Violations

uint32

violationsResult

An array of objects detailing the Distance Tracking Violations for each device participating with the requested device within the requested time range

[]DistanceViolationHistoryViolation

totalDevices

The number of unique devices participating in this Distance Tracking Violation

uint32

sourceDeviceId

The ID of the device which triggered this Distance Tracking Violation

String

locationId

The ID of the location for this Distance Tracking Violation. This will always match the requested location ID

uint64

locationName

The name of the location of this Distance Tracking Violation at time of write

String

floor

The floor number of the location of this Distance Tracking Violation at time of write

uint32

blufiId

If RTLS is enabled for the project which the requested location belongs to, it is the ID of the blufi of the last-known location at time of write, if available (projects which don’t use the Best Blufi RTLS setting will not have a blufi ID in their last-known location information). Otherwise, it is the ID of the first Blufi to report this event at time of write.

uint64

blufiName

If RTLS is enabled for the project which the requested location belongs to, it is the name of the blufi of the last-known location at time of write, if available (projects which don’t use the Best Blufi RTLS setting will not have a blufi name in their last-known location information). Otherwise, it is the name of the first Blufi to report this event at time of write.

String

durationMillis

The duration of this Distance Tracking Violation, in milliseconds

uint64

dateViolated

The timestamp of the beginning of this Distance Tracking Violation, formatted according to RFC3339

String

dateCleared

The timestamp of the end of this Distance Tracking Violation, formatted according to RFC3339

String

Sample Response

Code Block
{
  "locationId": "62", //Bluzone locationId
  "locationName": "Auto-generated", //Bluzone locationName
  "violations": 1101, //The number of Distance Tracking violations at the requested location during the requested period
  "uniqueDevices": 29, //The unique number of devices which had a Distance Tracking violation
  "recent": [
    //Each entry is an hourly report of the number Distance Tracking violations and unique number of devices for this location
    {
      "interval": "HOURLY",
      "timestamp": "2020-07-08T02:00:00Z",
      "violations": 3,
      "uniqueViolations": 3
    },
    {
      "interval": "HOURLY",
      "timestamp": "2020-07-08T00:00:00Z",
      "violations": 1,
      "uniqueViolations": 1
    },
    {
      "interval": "HOURLY",
      "timestamp": "2020-07-09T19:00:00Z",
      "violations": 2,
      "uniqueViolations": 2
    }
  ],
  "violationsMap": [
    //Each entry is a unique latitude/longitude tuple and the number of associated Distance Tracking violations at that location
    {
      "lat": 26.205577,
      "lng": -80.138385,
      "count": 470
    },
    {
      "lat": 26.205629,
      "lng": -80.138518,
      "count": 1
    }
  ],
  "devicesSummary": [
    //Each entry is a unique device id and the number of associated Distance Tracking packet violations for this device (i.e. the number of times a beaon reported it was too close to another beacon)
    {
      "deviceId": "200042",
      "violations": 1
    },
    {
      "deviceId": "200049",
      "violations": 1
    },
    {
      "deviceId": "200036",
      "violations": 53
    }
  ],
  "violationsResult": [
    //Each entry is a report of a Distance Violation event within the requested location
    {
      "totalDevices": 1, //The number of devices that were in violation with the reporting beacon
      "sourceDeviceId": "14744340248622994841", //The ID of the beacon the reported the violation
      "locationId": "14712", //The ID of the Bluzone location where the violation occured
      "locationName": "Austin Facility", //The name of the Bluzone location
      "floor": 1, //The floor of the Bluzone location
      "blufId": "106709", //The ID of the Blufi which reported the violation
      "blufiName": "BluFi015", //The name of the Blufi
      "durationMillis": "25115", //The total time of the violation
      "dateViolated": "2020-07-22T16:10:16Z", //The ISO8601 RFC339Nano Date of the violation
      "dateCleared": "2020-07-22T16:10:41Z" //The ISO8601 RFC339Nano Date of the clear, if applicable
    },
    {
      "totalDevices": 1,
      "sourceDeviceId": "9834777888017481246",
      "locationId": "14712",
      "locationName": "Austin Facility",
      "floor": 1,
      "blufId": "106738",
      "blufiName": "BluFi044",
      "durationMillis": "75373",
      "dateViolated": "2020-07-22T16:09:20Z",
      "dateCleared": "2020-07-22T16:10:35Z"
    },
    {
      "totalDevices": 1,
      "sourceDeviceId": "1376582239814772076",
      "locationId": "14712",
      "locationName": "Austin Facility",
      "floor": 1,
      "blufId": "106748",
      "blufiName": "BluFi054",
      "durationMillis": "72208",
      "dateViolated": "2020-07-22T15:49:10Z",
      "dateCleared": "2020-07-22T15:50:22Z"
    }
  ]
}

...