Skip to main content

baark

A typed Python SDK for Bark push notifications. Matching sync and async clients, connection pooling, rich notifications, and optional AES encryption. Requires Python 3.13+; built on httpx2 and PyCryptodome.

Install

From PyPI:

uv add baark

Quick start

Copy your device key from Bark. A URL ending in the key also works.

from baark import Baark

with Baark("YOUR_DEVICE_KEY", group="backups") as client:
    result = client.send(
        "The backup finished.",
        title="Backup",
        logo="https://example.com/backup.png",
        url="https://example.com/backups/latest",
    )
    print(result.ok)

Reuse the client for repeated sends; the context manager closes its connections. result.ok confirms server acceptance, not delivery to the phone. For a single send, use baark.send("Hello", device_key="YOUR_DEVICE_KEY").

Async

import asyncio

from baark import AsyncBaark


async def main() -> None:
    async with AsyncBaark("YOUR_DEVICE_KEY") as client:
        await client.send("Job finished", title="Build")


asyncio.run(main())

Both clients have the same options and operations; await async network calls. The one-shot async helper is baark.async_send().

Notification options

Pass options to send(), store them in a Message, or set client defaults. Per-call options override message fields, which override client defaults. Pass None in a call to clear an inherited option.

Purpose Options
Content body, title, subtitle, markdown
Media icon / logo (aliases), image, sound
Attention level, volume, badge, call
Interaction url, action, copy, auto_copy
History group, archive, ttl
Lifecycle id, delete

Use Python booleans for flags. Media URLs must be reachable by the phone. See message types for all options and Bark's field reference for device behavior.

Update and delete

with Baark("YOUR_DEVICE_KEY") as client:
    client.send("Downloading…", id="download-42")
    client.update("download-42", "Complete")
    client.delete("download-42")

Updates replace the complete message using the same ID. They require Bark 1.5.2+ and bark-server 2.2.5+. Deletion removes the notification and its history entry; it requires Background App Refresh and may be delayed by iOS.

Encryption

Use GCM for new configurations. It encrypts the message and detects ciphertext tampering. CBC and ECB are available for compatibility with existing Bark settings.

import os

from baark import Baark, Encryption

settings = Encryption(os.environ["BAARK_ENCRYPTION_KEY"])  # GCM by default
with Baark("YOUR_DEVICE_KEY", encryption=settings) as client:
    client.send("Private content", title="Private title")

Use the same key, algorithm, mode, and padding in Bark's Push Encryption settings. Keys are 16, 24, or 32 printable ASCII characters, selecting AES-128, AES-192, or AES-256. Key size and mode are separate choices: a longer key does not add tamper detection to CBC or ECB.

Mode Protection IV / nonce in baark Bark padding Choose it for
GCM (default) Encrypts and detects tampering Fresh 12-character nonce per message noPadding New setups
CBC Encrypts; no tamper detection Fresh 16-character IV by default pkcs7 Existing CBC setups
ECB Encrypts but reveals repeated blocks; no tamper detection None pkcs7 Legacy compatibility only

An IV or nonce is a public value used alongside the key. Leave iv unset so baark generates it for each GCM or CBC message; Bark reads it from the request. Fixed GCM nonces are rejected because reuse breaks its security. Fixed CBC IVs are supported for compatibility, but reuse leaks repeated message prefixes. See PyCryptodome's GCM and CBC/ECB documentation for the underlying modes.

To create settings, run settings = Encryption.generate() once, save the key, and enter settings.key, settings.algorithm, settings.mode, and settings.padding in Bark. It defaults to AES-256-GCM. To import an encoded key, use Encryption.from_key(value, encoding="hex") or encoding="base64"; enter the decoded key in Bark. Hex and base64 are encodings, not encryption methods.

Encryption hides message fields, including titles and media URLs, from the Bark server. Device routing, IVs, and id/delete controls remain visible. The key is never sent. Without this option, HTTPS protects transport but the server can read notification content.

Configuration and errors

Set server_url= for a custom server. Baark.from_env() and AsyncBaark.from_env() read these optional settings from the process environment:

Variable Value
BAARK_DEVICE_KEY Device key or URL ending in the key
BAARK_SERVER_URL Custom server URL
BAARK_ENCRYPTION_KEY Literal key matching Bark
BAARK_ENCRYPTION_MODE GCM (default), CBC, or ECB
BAARK_ENCRYPTION_IV Optional fixed CBC IV

Ordinary constructors do not load these variables or config files. HTTP requests default to a 10-second timeout, with redirects and retries disabled. Set timeout=, auth=, or inject an httpx2.Client / AsyncClient with http_client= for custom transport settings. Injected clients remain caller-owned; configure authentication on them. HTTP query defaults such as authentication tokens are preserved; notification and routing fields come from baark's arguments and messages.

Send to multiple devices with client.send("Hello", device_keys=["KEY_A", "KEY_B"]). Encrypted batches require all recipients to share encryption settings. Partial failures raise BatchError; inspect error.response.deliveries for each result. All SDK errors inherit from BaarkError. APIError exposes status_code, code, and apns_reason; raw server_message is available explicitly and may contain sensitive data.

For alternate endpoints, server utilities, registration, and URL building, see the client API. Also see response and message types, errors, and encryption helpers.

Alternatives

Project Useful when you want Documented encryption support
baark Reusable, typed sync and async Bark clients in Python GCM, CBC, ECB
iskoldtbark A Bark CLI with saved devices, recipient groups, and per-device keys AES-256-GCM; AES-128/192/256-CBC
bark-python A small client with replaceable encryption strategies Built-in CBC and ECB; custom strategies
Apprise One library or CLI for Bark and other notification services Bark AES-GCM

For simple scripts, Bark's HTTP API also works directly with curl or your existing HTTP client.

Development

Install uv, just, and actionlint, then run uv sync --locked. Windows development also needs Bash, as provided by Git for Windows.

Test with your phone

Copy .env.example with cp -n .env.example .env, then edit .env with your device key and optional encryption settings. Leave unused settings commented out.

uv run python scripts/e2e.py --list-cases
uv run --env-file .env python scripts/e2e.py --client sync --case logo image markdown

These selected cases send three real notifications. Check the phone, then repeat with the same client and cases plus --action update or --action delete. --case all covers nine cases; the default client selection, both, doubles the count. Use --help for media URL overrides and other options.

Offline checks

just check
just build
just test-wheel

The test suite uses mock HTTP transports and encryption vectors. Coverage checks enforce the threshold in pyproject.toml. CI tests the built wheel on Python 3.13 and 3.14 across Linux, macOS, and Windows.

License

MIT.

Metadata

Release files for baark 0.1.0

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

Source distribution (sdist)

Source distribution for baark 0.1.0
File Size Uploaded Provenance
baark-0.1.0.tar.gz 84.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for baark 0.1.0
File Interpreter ABI Platform
baark-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 111.0 kB

Release files / baark-0.1.0.tar.gz

Download URL baark-0.1.0.tar.gz
Size 84.8 kB
Tags Source
SHA-256 checksum
How to use checksums
fc5ee0c84ddb991a022648a5bfa7ae2d278c5a7e06b2b391a4b34ecd07c744db
BLAKE2b-256 checksum
How to use checksums
dc36e6d4e00f4757fcad6d9873b1710cd9eecbc70a315f1b90ee76ab17210b7c
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 Sep 15, 2026.

Transparency log

Release files / baark-0.1.0-py3-none-any.whl

Download URL baark-0.1.0-py3-none-any.whl
Size 26.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9fb161c798458fc216de7bff0db9bdb88f236fd3ef40f4dfb3d092ad2ad9ab08
BLAKE2b-256 checksum
How to use checksums
ccc2ee56d815ade622f2f81692a2a3d847ae7bca037fa35ea503b77609e805b9
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 Sep 15, 2026.

Transparency log

Security for baark 0.1.0

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 baark-0.1.0.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 Sep 15, 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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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