Skip to main content

petsafe-api

Connect and control PetSafe Smart Feed, ScoopFree, and Smart Door devices using the PetSafe API.

BREAKING CHANGE: Version 2.0 uses the new PetSafe API. You will need to request new tokens.

PetSafe will lock your account if you request data more often than once per 5 minutes.

Project rename

This repository is now named petsafe-api and the published package name is petsafe-api on PyPI.

Import paths are unchanged: continue using import petsafe and python -m petsafe.

Acknowledgements

This project builds on the excellent prior work from the original developers:

Thank you to both projects for building the API integrations for existing feeder and ScoopFree functionality. This repository includes all of that previous work, with Smart Door API support added on top.

Installation

pip install petsafe-api

If installing from source code, python setup.py install

Local SmartDoor control and provisioning (3.1.0)

LocalPetSafeClient connects to a compatible local server using its HTTPS origin and API token. It does not use a PetSafe vendor login, and returns the same DeviceSmartDoor objects as the cloud client, so existing methods are reused:

import asyncio
import petsafe


async def main() -> None:
    async with petsafe.LocalPetSafeClient(
        "https://petsafe.example", "LOCAL_API_TOKEN"
    ) as client:
        door = (await client.get_smartdoors())[0]
        await door.lock()
        await door.unlock()
        await door.smart_mode()


asyncio.run(main())

BLE provisioning dependencies are optional: pip install petsafe-api[ble]. SetupClient creates a server-correlated setup session; the BLE entry point is provision_smartdoor:

from petsafe import SetupClient
from petsafe.provisioning import WifiNetwork, provision_smartdoor


async def provision() -> None:
    async with SetupClient(SERVER_ORIGIN, API_TOKEN) as setup:
        session = await setup.create(DEVICE_ID, "provision")
        result = await provision_smartdoor(
            ble_device,
            session.endpoint,
            WifiNetwork(ssid=SSID, password=PASSWORD, bssid=BSSID_BYTES),
            confirm=setup.confirmation(session),
        )

Local operation requires a compatible server and a hostname resolving to it. Provisioning also requires supported BLE hardware or a nearby proxy and an HTTPS hostname and certificate trusted by the SmartDoor; hardware testing used an Amazon-trusted certificate. A raw IP address is not a supported or promised substitute.

Cloud login tokens

You must use tokens to interact with the PetSafe Smart-Feed API.
There are two methods to retrieve tokens:

Get tokens using command line

  1. Execute python -m petsafe [email_address] to request an email code.
  2. Check your email for an email code from PetSafe.
  3. Enter your code to generate tokens.

Get tokens using Python

import petsafe as sf


# replace with your email address
client = sf.PetSafeClient(email="email@example.com")
client.request_code()

# check your email for a code
code = input("Enter email code: ")
token = client.request_tokens_from_code(code)

print("email:", client.email)
print("id_token:", client.id_token)
print("refresh_token:", client.refresh_token)
print("access_token:", client.access_token)

Example usage

List feeders

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_feeders(client)

# print all feeders
for device in devices:
    print(device)

Feed 1/8 cup at normal speed

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_feeders(client)

# get the first feeder
feeder = devices[0]
feeder.feed(amount=1, slow_feed=False)

Get current battery level (0 - 100)

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_feeders(client)

# get the first feeder
feeder = devices[0]
print(feeder.battery_level)

Get current food level

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_feeders(client)

# get the first feeder
feeder = devices[0]
status = feeder.food_low_status

if status == 0:
    print("Feeder has food.")
elif status == 1:
    print("Feeder is low on food.")
elif status == 2:
    print("Feeder is out of food.")

SmartDoor controls

import asyncio

import petsafe as sf


async def main() -> None:
    client = sf.PetSafeClient(
        email="email@example.com",
        id_token="YOUR_ID_TOKEN",
        refresh_token="YOUR_REFRESH_TOKEN",
        access_token="YOUR_ACCESS_TOKEN",
    )

    doors = await client.get_smartdoors()
    door = doors[0]

    # Manually lock the door and refresh its reported state
    await door.lock()

    # Switch back to Smart mode without forcing a refresh
    await door.smart_mode(update_data=False)

    # Or use the client helpers that return the updated door instance
    updated = await client.manual_unlock_smartdoor(door.api_name)
    print(updated.mode)


asyncio.run(main())

get litterboxes

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_litterboxes(client)

# print all litterboxes
for device in devices:
    print(device)

get litterbox activity

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_litterboxes(client)

litterbox = devices[0]
print(litterbox.get_schedule())

rake the litterbox

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_litterboxes(client)

litterbox = devices[0]
litterbox.rake()

modify the litterbox rake timer

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_litterboxes(client)

litterbox = devices[0]
litterbox.modify_timer(15)

reset the litterbox rake count

import petsafe as sf

client = sf.PetSafeClient(email="email@example.com",
                       id_token="YOUR_ID_TOKEN",
                       refresh_token="YOUR_REFRESH_TOKEN",
                       access_token="YOUR_ACCESS_TOKEN")
devices = sf.devices.get_litterboxes(client)

litterbox = devices[0]
litterbox.reset()

Contributing

All contributions are welcome. Please, feel free to create a pull request!

Metadata

Release files for petsafe-api 3.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for petsafe-api 3.1.2
File Size Uploaded Provenance
petsafe_api-3.1.2.tar.gz 32.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for petsafe-api 3.1.2
File Interpreter ABI Platform
petsafe_api-3.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 57.6 kB

Release files / petsafe_api-3.1.2.tar.gz

Download URL petsafe_api-3.1.2.tar.gz
Size 32.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a34f5438bf7973190eb1207767dda97ce7ebc0dbeafa14a6200a8d8d49d41980
BLAKE2b-256 checksum
How to use checksums
0ce420bbad1e5a51782c59c46fb410a6293625305d202b4b08e2c9f9cd11ebd3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / petsafe_api-3.1.2-py3-none-any.whl

Download URL petsafe_api-3.1.2-py3-none-any.whl
Size 25.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad0add481a7c437872b2a4540da41168a7199848634d84d2f0682704032484e2
BLAKE2b-256 checksum
How to use checksums
57137ef7b8ceac6d0b81a2d1e61b8da74b6d894517c2da2678d96b34975ef052
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for petsafe-api 3.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for petsafe_api-3.1.2.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page