bluereacher-python
Official Python client for the Blue Reacher API. Send iMessage from your CRM, app, or AI agent over a dedicated line, read replies, manage contacts, and verify webhooks.
- Typed with
TypedDictresponse shapes and full type hints - Built on
httpx, one dependency - Python 3.8+
- No A2P registration required
Docs: https://docs.bluereacher.com
OpenAPI: https://docs.bluereacher.com/openapi.json
Install
pip install bluereacher
Quickstart
import os
from bluereacher import BlueReacher
br = BlueReacher(os.environ["BLUEREACHER_API_KEY"])
# Test keys (brk_test_) hit a simulator: no message is ever sent.
res = br.send_message(to="+13035550101", message="Hey, following up on your quote.")
print(res["message_id"], res["mode"])
status = br.get_status(res["message_id"])
print(status["status"])
Every example here uses the placeholder key brk_test_your_key. Keep live keys (brk_live_) in environment variables, never in source.
Use it as a context manager to close the underlying HTTP connection pool:
with BlueReacher(os.environ["BLUEREACHER_API_KEY"]) as br:
br.send_message(to="+13035550101", message="Reminder for tomorrow.")
Sending
By default a send is queued through the paced drip pipeline. Pass send_mode="instant" to dispatch now.
# Instant, with a native effect
br.send_message(
to="+13035550101",
message="You are confirmed",
send_mode="instant",
message_effect="confetti",
)
# Media
br.send_message(
to="+13035550101",
message="Your receipt",
media_urls=["https://example.com/receipt.pdf"],
)
Contacts and opt-out
br.upsert_contact(phone_number="+13035550101", first_name="Jordan", tags=["lead"])
state = br.get_opt_out("+13035550101")
if not state["opted_out"]:
br.send_message(to="+13035550101", message="...")
# Honor an opt-out
br.set_opt_out(phone="+13035550101", opted_out=True)
Capability check
cap = br.check_capability(["+13035550101", "+13035550102"])
for r in cap["results"]:
print(r["phone"], r["status"]) # "imessage" | "sms" | "unknown" | "pending"
Webhooks
Register your endpoint, store the signing secret, and verify every delivery. Each request carries an X-BlueReacher-Signature header of the form sha256=HMAC-SHA256(secret, raw_body).
from bluereacher import verify_webhook_signature, construct_event
reg = br.register_webhook("https://example.com/hooks/bluereacher")
secret = reg["secret"] # store this
# In your handler, pass the EXACT raw body bytes (not a re-serialized dict):
if not verify_webhook_signature(raw_body, signature_header, secret):
... # reject with 400
event = construct_event(raw_body, signature_header, secret)
print(event["event"], event["data"])
Flask example:
from flask import Flask, request, abort
from bluereacher import construct_event
app = Flask(__name__)
@app.post("/hooks/bluereacher")
def hook():
try:
event = construct_event(
request.get_data(), # raw bytes
request.headers.get("X-BlueReacher-Signature"),
os.environ["BLUEREACHER_WEBHOOK_SECRET"],
)
except ValueError:
abort(400)
# handle event["event"] ...
return "", 200
Error handling
Non-2xx responses raise BlueReacherError with status, code, and help.
from bluereacher import BlueReacherError
try:
br.send_message(to="+13035550101", message="Hi")
except BlueReacherError as err:
print(err.status, err.code, err)
API surface
| Method | Endpoint |
|---|---|
send_message(...) |
POST /v1/messages |
get_status(message_id) |
GET /v1/status/{message_id} |
get_conversation(...) |
GET /v1/conversations |
get_contact_messages(contact_id, ...) |
GET /v1/conversations/{contact_id}/messages |
list_contacts(...) |
GET /v1/contacts |
upsert_contact(...) |
POST /v1/contacts |
update_contact(contact_id, ...) |
PATCH /v1/contacts/{contact_id} |
get_opt_out(phone) |
GET /v1/opt-out |
set_opt_out(...) |
POST /v1/opt-out |
check_capability(phones) |
POST /v1/capability |
get_usage() |
GET /v1/usage |
list_lines() |
GET /v1/devices |
register_webhook(url, events) |
POST /v1/webhooks |
get_webhook() |
GET /v1/webhooks |
delete_webhook() |
DELETE /v1/webhooks |
Development
pip install -e .
python -c "import bluereacher; print(bluereacher.__version__)"
License
MIT. Copyright 2026 Sagency International LLC (Blue Reacher).
Metadata
Release files for bluereacher 0.1.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 | |
|---|---|---|---|
| bluereacher-0.1.0.tar.gz | 8.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bluereacher-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.0 kB
Release files / bluereacher-0.1.0.tar.gz
| Download URL | bluereacher-0.1.0.tar.gz |
|---|---|
| Size | 8.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d73c796c8b4cfe9d0d384fa78a24f085f240a3823258617ab66668911d649ecc
|
|
BLAKE2b-256 checksum How to use checksums |
c8d35d2efe669a8f330de3468553dc6b9c12cdff1234a7a23cacc904cd75375e
|
| 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 20, 2026.
Transparency logRelease files / bluereacher-0.1.0-py3-none-any.whl
| Download URL | bluereacher-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
47c609f5eeba15f74dcd8a4528c243deab8861ddd9ec96ae556f58d10f182a16
|
|
BLAKE2b-256 checksum How to use checksums |
e5c1b3c707f708f6f48c4b6115ac4e40e1f267f8cb39a8993ba0dbb50564959e
|
| 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 20, 2026.
Transparency log