Skip to content

API documentation

Some parameters may appear as required. This is a bug with mkdocstrings (scroll down)

FailedRequestError

Bases: Exception

Exception for when a request does not return the expected status code.

InvalidURLError

Bases: Exception

Exception for when an invalid URL is received.

dispatch

The dispatch API.

Address

Bases: BaseModel

Used for static alarms (e.g. a fire or a security alarm).

Parameters:

Name Type Description Default
line1 str

Line 1 of the address

required
line2 str

Line 2 of the address. Optional.

required
city str

The city where the alarm occured

required
state str

The state where the alarm occured

required
zip str

The ZIP code where the alarm occured

required

Alarm(alarm_id, sandbox, owner_id, token, prod_url, session=None)

Class for Alarms.

Danger

DO NOT INSTANTIATE THIS CLASS TO CREATE AN ALARM. USE create_alarm() INSTEAD.

Source code in pynoonlight/dispatch.py
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
def __init__(
    self,
    alarm_id: str,
    sandbox: bool,
    owner_id: str,
    token: str,
    prod_url: Optional[str],
    session: Optional[aiohttp.ClientSession] = None,
) -> None:
    self.id = alarm_id
    self.sandbox = sandbox
    self.owner_id = owner_id
    self._token = token
    self._session = session

    if prod_url:
        self.prod_url = prod_url

cancel(pin) async

Cancel an alarm.

Parameters:

Name Type Description Default
pin str

PIN used to cancel the alarm. Optional.

required

Raises:

Type Description
FailedRequestError

Raised when the request to cancel the alarm fails.

Source code in pynoonlight/dispatch.py
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
async def cancel(self, pin: Optional[str]) -> None:
    """Cancel an alarm.

    Args:
        pin (str, optional): PIN used to cancel the alarm. Optional.

    Raises:
        FailedRequestError: Raised when the request to cancel the alarm fails.
    """
    if not self.active:
        return  # Already canceled :)

    url = (
        SANDBOX_URL.format(path=f"/{self.id}/status")
        if self.sandbox
        else f"{self.prod_url}/{self.id}/status"
    )

    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "Authorization": f"Bearer {self._token}",
    }
    payload = (
        {"status": "CANCELED", "pin": pin}
        if pin is not None
        else {"status": "CANCELED"}
    )

    try:
        await _send_request("POST", url, headers, payload, 201, self._session)
    except RetryError as e:
        raise FailedRequestError from e

    self.active = False

    return

create_events(events) async

Create new events that started the alarm or occured during the alarm.

Parameters:

Name Type Description Default
events list[Event]

See Event.

required

Raises:

Type Description
FailedRequestError

Raised when the request to create the event(s) has failed.

Source code in pynoonlight/dispatch.py
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
async def create_events(self, events: list[Event]) -> None:
    """Create new events that started the alarm or occured during the alarm.

    Args:
        events (list[Event]): See Event.

    Raises:
        FailedRequestError: Raised when the request to create the event(s) has failed.
    """
    event_dicts: list[dict[str, Any]] = []
    for _, event in enumerate(events):
        event.event_time = str(event.event_time).replace(" ", "T")
        event_dicts.append(event.dict())

    for event_dict in event_dicts:
        if event_dict["meta"]["device_id"] is None:
            del event_dict["meta"]["device_id"]
        if event_dict["meta"]["media"] is None:
            del event_dict["meta"]["media"]

    url = (
        SANDBOX_URL.format(path=f"/{self.id}/events")
        if self.sandbox
        else f"{self.prod_url}/{self.id}/events"
    )

    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {self._token}",
    }

    try:
        await _send_request("POST", url, headers, event_dicts, 201, self._session)
    except RetryError as e:
        raise FailedRequestError from e

    return

create_people(people) async

Add new people to the alarm.

Parameters:

Name Type Description Default
people list[Person]

A list of people to add to the alarm

required

Raises:

Type Description
FailedRequestError

Raised when the request to add the people failed.

Source code in pynoonlight/dispatch.py
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
async def create_people(self, people: list[Person]) -> None:
    """Add new people to the alarm.

    Args:
        people (list[Person]): A list of people to add to the alarm

    Raises:
        FailedRequestError: Raised when the request to add the people failed.
    """
    people_dicts = [person.dict() for person in people]
    url = (
        SANDBOX_URL.format(path=f"/{self.id}/people")
        if self.sandbox
        else f"{self.prod_url}/{self.id}/people"
    )

    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {self._token}",
    }

    try:
        await _send_request("POST", url, headers, people_dicts, 201, self._session)
    except RetryError as e:
        raise FailedRequestError from e

    return

update_location(coordinates) async

Update the location of the alarm.

Parameters:

Name Type Description Default
coordinates Coordinates

The new coordinates of the alarm.

required

Raises:

Type Description
FailedRequestError

Raised when the request to update the coordinates fails.

Source code in pynoonlight/dispatch.py
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
async def update_location(self, coordinates: Coordinates) -> None:
    """Update the location of the alarm.

    Args:
        coordinates (Coordinates): The new coordinates of the alarm.

    Raises:
        FailedRequestError: Raised when the request to update the coordinates fails.
    """
    url = (
        SANDBOX_URL.format(path=f"/{self.id}/locations")
        if self.sandbox
        else f"{self.prod_url}/{self.id}/locations"
    )

    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {self._token}",
    }
    payload = coordinates.dict()

    try:
        await _send_request("POST", url, headers, payload, 201, self._session)
    except RetryError as e:
        raise FailedRequestError from e

    return

update_person(person_data) async

Update the alarm owner. You may only update the alarm owner right now.

Parameters:

Name Type Description Default
person_data dict[str, Any]

See here

required

Raises:

Type Description
FailedRequestError

Raised when the request to update the alarm owner fails.

Source code in pynoonlight/dispatch.py
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
async def update_person(self, person_data: dict[str, Any]) -> None:
    """Update the alarm owner. You may only update the alarm owner right now.

    Args:
        person_data (dict[str, Any]): See [here](https://docs.noonlight.com/reference/put_alarms-alarm-id-people-person-id)

    Raises:
        FailedRequestError: Raised when the request to update the alarm owner fails.
    """
    url = (
        SANDBOX_URL.format(path=f"/{self.id}/people/{self.owner_id}")
        if self.sandbox
        else f"{self.prod_url}/{self.id}/people/{self.owner_id}"
    )

    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {self._token}",
    }

    try:
        await _send_request("PUT", url, headers, person_data, 200, self._session)
    except RetryError as e:
        raise FailedRequestError from e

    return

AlarmData

Bases: BaseModel

Alarm data passed on to Noonlight dispatchers.

Parameters:

Name Type Description Default
name str

Name of the alarm owner.

required
phone str

Verified phone number of the alarm owner.

required
pin str

PIN used to cancel the alarm. Optional.

required
owner_id str

Owner ID of the alarm, generated automatically if missing. Optional.

required
location Location

Location of the alarm. This matters the most!

required
workflow Workflow

See Workflow. Optional.

required
services Services

See Services. Optional.

required
instructions Instructions

See Instructions. Optional.

required

Coordinates

Bases: BaseModel

Used for dynamic alarms when the user is constantly changing location.

Parameters:

Name Type Description Default
lat float

Latitude of the alarm

required
lon float

Longitude of the alarm

required
accuracy int

Accuracy of the GPS in meters

required

Event

Bases: BaseModel

An event that occurs during an alarm. This could be a smoke detector being cleared, a door being opened, a water leak being detected, etc.

Parameters:

Name Type Description Default
event_type str

Must be one of 'alarm.device.activated_alarm', 'alarm.person.activated_alarm', 'alarm.device.value_changed'

required
event_time datetime

The time the event occured. (if the datetime object is naive, it will be treated as if it is in local time zone)

required
meta EventMeta

The metadata of the event (see EventMeta)

required

EventMeta

Bases: BaseModel

Metadata of an event to be used in Event. See here.

Instructions

Bases: BaseModel

From Noonlight: Instructions relayed to the dispatchers. Currently, the only allowed type is entry.

Parameters:

Name Type Description Default
entry str

Instructions on how to enter the area of the alarm.

required

Location

Bases: BaseModel

The location of the alarm. At least one argument is required.

Parameters:

Name Type Description Default
address Address

The address of the alarm.

required
coordinates Coordinates

The coordinates of the alarm.

required

Person

Bases: BaseModel

A person that is added to the alarm.

Parameters:

Name Type Description Default
name str

The name of the person.

required
pin str

Their PIN to cancel the alarm.

required
phone str

The phone number of the person.

required

Services

Bases: BaseModel

Requested services for an alarm.

police (bool): Police requested
fire (bool): Fire department requested
medical (bool): Medical personnel requested
other (bool): Other authorities requested

Workflow

Bases: BaseModel

From Noonlight: Optional workflow ID. This will be provided to you by the Noonlight team for certain use cases.

Parameters:

Name Type Description Default
id str

The workflow ID provided to you by the Noonlight team.

required

create_alarm(data, server_token, sandbox=True, client_session=None) async

Create a new alarm.

Parameters:

Name Type Description Default
data AlarmData

Data for the alarm. See AlarmData.

required
server_token str

Your server token. Make sure it matches the sandbox or production token you have!

required
sandbox bool

Set to False if this is a real alarm. Defaults to True.

True
prod_url str

The URL of the production environment (must have https:// and must end in noonlight.com). Optional.

required
client_session aiohttp.ClientSession

The client session used for requests in aiohttp

None

Raises:

Type Description
InvalidURLError

Raised when the production URL provided is invalid.

FailedRequestError

Raised when the request to create the alarm fails

Returns:

Name Type Description
Alarm Alarm

The alarm

Source code in pynoonlight/dispatch.py
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
async def create_alarm(
    data: AlarmData,
    server_token: str,
    sandbox: bool = True,
    client_session: Optional[aiohttp.ClientSession] = None,
) -> Alarm:
    """Create a new alarm.

    Args:
        data (AlarmData): Data for the alarm. See AlarmData.
        server_token (str): Your server token. Make sure it matches the sandbox or production token you have!
        sandbox (bool, optional): Set to False if this is a real alarm. Defaults to True.
        prod_url (str, optional): The URL of the production environment (must have https:// and must end in noonlight.com). Optional.
        client_session (aiohttp.ClientSession, optional): The client session used for requests in aiohttp

    Raises:
        InvalidURLError: Raised when the production URL provided is invalid.
        FailedRequestError: Raised when the request to create the alarm fails

    Returns:
        Alarm: The alarm
    """
    if sandbox:
        url = SANDBOX_URL.format(path="")
    else:
        url = PRODUCTION_URL.format(path="")

    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "Authorization": f"Bearer {server_token}",
    }

    payload = data.dict()

    # Remove all values that are None
    def iterate(dictionary: dict[str, Any]) -> None:
        for key, val in dictionary.copy().items():
            if isinstance(val, dict):
                iterate(val)
            else:
                if val == "" or val is None or val is False:
                    del dictionary[key]

    iterate(payload)
    iterate(payload)

    try:
        response = await _send_request(
            "POST", url, headers, payload, 201, client_session
        )
        response_data = await response.json()
    except RetryError as e:
        raise FailedRequestError from e

    return Alarm(
        alarm_id=response_data["id"],
        sandbox=sandbox,
        owner_id=response_data["owner_id"],
        token=server_token,
        prod_url=url,
        session=client_session,
    )

tasks

The tasks API.

Image

Bases: BaseModel

An image that is provided to the verifier

Parameters:

Name Type Description Default
url str

The URL of the image

required
media_type str

The media type of the image, must be one of image/jpeg, image/png, or image/jpg

required
points_of_interest list[PointOfInterest]

A list of PointOfInterest objects

required

PointOfInterest

Bases: BaseModel

A point of interest in an image. The coordinate system for the points_of_interest field has the origin starting at the top left of the image. The positive x-axis moves right, and the positive y-axis moves down. Coordinates and distances must be non-negative integers.

Parameters:

Name Type Description Default
x int

The x coordinate, in pixels, for the top left corner of the bounding box. Must be a non-negative integer.

required
dx int

The distance from the x field, in pixels, for the bounding box. Must be a non-negative integer.

required
y int

The y coordinate, in pixels, for the top left corner of the bounding box. Must be a non-negative integer.

required
dy int

The distance from the y field, in pixels, for the bounding box. Must be a non-negative integer.

required

VerificationData

Bases: BaseModel

Data for the verifier

Parameters:

Name Type Description Default
id str

The ID of the task. If not provided, it will be auto-generated.

required
owner_id str

The end-user's account ID.

required
location_id str

The location ID of the camera or device.

required
device_id str

The device ID of the camera or device.

required
prompt str

The text displayed to the verifier. They will select yes or no in response to this prompt.

required
expiration int

The amount of time, in seconds, allotted to complete the verification task.

required
attachments Union[list[Image], Video]

The attachment shown to the verifier.

required
webhook_url str

The webhook that will be invoked when the verification is complete. If none is provided, it will use the preconfigured webhook.

required

Video

Bases: BaseModel

A video that is provided to the verifier

Parameters:

Name Type Description Default
url str

The URL of the video

required
media_type str

The media type of the video. For MP4 videos, the alllowed type is video/mp4. For HLS, use application/x-mpegURL.

required

create_task(data, server_token, sandbox=True) async

Create a verification request to verify a piece of media with a prompt

Parameters:

Name Type Description Default
data VerificationData

See VerificationData

required
server_token str

Your server token that matches the sandbox or prod environment

required
sandbox bool

Set to False if this is a real task. Defaults to True.

True
prod_url str

URL for your production environment. Required if sandbox is set to True. Defaults to None.

required

Raises:

Type Description
FailedRequestError

Raised when the request to create the task fails.

InvalidURLError

Raised when the production URL is invalid

Returns:

Name Type Description
str str

The task ID for the given task

Source code in pynoonlight/tasks.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
async def create_task(
    data: VerificationData,
    server_token: str,
    sandbox: bool = True,
) -> str:
    """Create a verification request to verify a piece of media with a prompt

    Args:
        data (VerificationData): See VerificationData
        server_token (str): Your server token that matches the sandbox or prod environment
        sandbox (bool, optional): Set to False if this is a real task. Defaults to True.
        prod_url (str, optional): URL for your production environment. Required if sandbox is set to True. Defaults to None.

    Raises:
        FailedRequestError: Raised when the request to create the task fails.
        InvalidURLError: Raised when the production URL is invalid

    Returns:
        str: The task ID for the given task
    """
    if sandbox:
        url = SANDBOX_URL
    else:
        url = PRODUCTION_URL

    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "Authorization": f"Bearer {server_token}",
    }

    payload = data.dict()
    payload["expiration"] = {"timeout": data.expiration}

    try:
        response = await _send_request(
            "POST", url=url, headers=headers, payload=payload, expected_code=201
        )
    except RetryError as e:
        raise FailedRequestError from e

    response_data = TaskResponse(**await response.json())
    return response_data.id