eufylife-api
Unofficial Python client for the EufyLife smart scale cloud API. No Home Assistant, no cloud functions, no dependencies beyond the standard library — just weight, body fat %, muscle mass, and the rest of what your scale measures, as plain Python objects.
from eufylife_api import EufyLifeClient
client = EufyLifeClient("me@example.com", "hunter2")
for m in client.get_measurements():
print(m.timestamp, m.weight_kg, m.muscle_mass_kg, m.body_fat_percent)
Why this exists
Eufy/Anker do not publish a developer API for their smart scales. The
EufyLife app talks to api.eufylife.com, and a couple of projects have
reverse-engineered that protocol — but tied to a specific framework:
eufylife-api-hacs is a Home
Assistant integration, and eufylife-mcp is an MCP server. Neither is usable
as a plain library if you just want the data in a Python script, a Jupyter
notebook, or your own automation.
This package fills that gap: the same protocol, with no framework dependency.
Credit: the request shapes, headers, and field names used here were
derived by reading the source of m4ary/eufylife-api-hacs (MIT licensed).
This is an independent re-implementation with no shared code and no
Home Assistant dependency, but the protocol knowledge it's built on comes
from that project.
Install
Not yet published to PyPI. For now, install from a local checkout:
pip install -e .
Usage
from eufylife_api import EufyLifeClient
# Credentials are your EufyLife app login (email + password).
client = EufyLifeClient("me@example.com", "hunter2")
# Optional: persist the access token across runs instead of logging in every time.
client = EufyLifeClient("me@example.com", "hunter2", token_cache_path="~/.config/eufy/token.json")
measurements = client.get_measurements() # all history
measurements = client.get_measurements(after=1735689600) # only after this unix timestamp
for m in measurements:
print(m.timestamp, m.weight_kg, m.body_fat_percent, m.muscle_mass_kg)
if m.missing_fields:
print(" this reading didn't include:", m.missing_fields)
Need a field this library doesn't model, or want the exact API response for
logging/debugging? Use get_raw_device_data() instead of get_measurements().
What you get
This is the differentiator: every field the API sends, not just the
handful that eufylife-api-hacs happens to surface as Home Assistant
sensors. Reading only that project's source would tell you the API has 10
metrics; the raw response actually has over 20.
Confirmed (verified against 68 real readings from a Smart Scale P3 —
consistently populated, and matched an independently hand-recorded value
where one existed): weight_kg, body_fat_percent, body_fat_mass_kg,
muscle_mass_kg, skeletal_muscle_mass_kg, bone_mass_kg, water_percent,
subcutaneous_fat_rate_percent, visceral_fat_level, bmi,
bmr_kcal_per_day, body_age_years, protein_ratio_percent,
heart_rate_bpm.
Unconfirmed (present in every response's shape, but 0 in all 68 real
samples used to build this — likely populated by other scale models, exposed
as-is with no scale/unit applied): fat_free_weight_raw, muscle_raw,
water_weight_raw, visceral_fat_index_raw, bone_raw,
standard_weight_raw, height_raw, head_size_raw, impedance_raw. If one
of these is ever non-zero for you, please open an issue with the raw value
and what the app displayed — that's how the "confirmed" list grows.
Categorical (small integers, not physical quantities — 0 may be a real
category, not an absence): body_type, mode, fat_mode.
Plus timestamp, customer_id, device_id, product_code, and the
original raw record for anything not modeled above.
Not every scale model reports every field. Check measurement.missing_fields
rather than assuming everything is populated (it excludes the categorical
fields, since 0 isn't necessarily an absence for those).
⚠ body_fat_mass_kg might just be weight_kg × body_fat_percent
The API does have a body-fat-mass field — earlier versions of this README
said otherwise, because that field isn't in eufylife-api-hacs's mapping
and was missed on first read of the raw response. It's there.
But across 67 comparable readings, body_fat_mass_kg equalled
round(weight_kg * body_fat_percent / 100, 1) in 32 cases and was exactly
0.1kg below that in the other 35 — no other deviation ever appeared. That
bimodal, zero-variance pattern looks like a server-side computation off
slightly different-precision inputs, not an independently corroborating
bioimpedance measurement. So this field — and quite possibly the EufyLife
app's own "body fat mass" display — may already be the weight×percentage
calculation. Treat it as convenient, not as independent verification of
body_fat_percent.
Reliability notes
This is an undocumented API. It can change without notice, and this library has no way to detect that in advance. A few things it does to make failures visible instead of silent:
get_raw_device_data()gives you the exact server response, unmodified.- Parsing failures and API error responses raise (
EufyLifeAPIError,EufyLifeAuthError) rather than returning empty/default data. - Missing fields on a reading are exposed via
Measurement.missing_fieldsinstead of being silently treated as zero.
What it does not do (yet): flag a value as statistically implausible (e.g. a 5kg overnight weight swing), or diff successive readings for you. That's left to the caller, since "what counts as implausible" is domain-specific.
Background
Built while automating daily health tracking — Fitbit/Google Health sync weight and body fat % from Eufy scales, but not muscle mass or several other fields the scale itself reports, because those metrics don't exist in Fitbit's or Apple Health's schema at all. This library exists to reach past that relay and read the scale's own data directly.
License
MIT — see LICENSE.
Metadata
Release files for eufylife-api 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| eufylife_api-0.2.0.tar.gz | 13.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| eufylife_api-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.3 kB
Release files / eufylife_api-0.2.0.tar.gz
| Download URL | eufylife_api-0.2.0.tar.gz |
|---|---|
| Size | 13.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f6de33f40b8a4bdaee339dbc42a1fed467eb18ef249e067ae2031e50b0fd65e8
|
|
BLAKE2b-256 checksum How to use checksums |
c53556daa1a251daa03a146416e19a7685460dfb2acf8fae8224e4900efcf01f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 24, 2026.
Transparency logRelease files / eufylife_api-0.2.0-py3-none-any.whl
| Download URL | eufylife_api-0.2.0-py3-none-any.whl |
|---|---|
| Size | 12.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
541ac72b869512d0f8e81eb21a66ed2dfc49c8fc2e257a69ddc85dd9687c5d8f
|
|
BLAKE2b-256 checksum How to use checksums |
51a9a04262f57513c041b111a4a0f16cc6ff99124b35348e6ca268ae9aff5015
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Aug 24, 2026.
Transparency log