WorkonwardSend Python SDK
A minimal Python SDK for the WorkOnward Reach API, mirroring the structure of the JavaScript SDK.
Installation
Install via pip or Poetry:
pip install workonward-reach
# or
poetry add workonward-reach
Usage
from workonward_reach import WorkonwardSend, types
# By default: raises WorkonwardSendHTTPError on non-2xx.
client = WorkonwardSend("us_123")
# 1) TypedDict payload (autocomplete in IDEs). Use dict to pass 'from'.
payload: types.EmailCreate = {
"to": "test@example.com",
"from": "no-reply@example.com",
"subject": "Hello",
"html": "<strong>Hi!</strong>",
}
resp, _ = client.emails.send(payload=payload)
# 2) Or pass a plain dict (supports 'from')
resp, _ = client.emails.send(payload={
"to": "test@example.com",
"from": "no-reply@example.com",
"subject": "Hello",
"html": "<strong>Hi!</strong>",
})
# Idempotent retries: same payload + same key returns the original response
resp, _ = client.emails.send(
payload=payload,
options={"idempotency_key": "signup-123"},
)
# Works for batch requests as well
resp, _ = client.emails.batch(
payload=[payload],
options={"idempotency_key": "bulk-welcome-1"},
)
# If the same key is reused with a different payload, the API responds with HTTP 409.
# 3) Campaigns
campaign_payload: types.CampaignCreate = {
"name": "Welcome Series",
"subject": "Welcome to our service!",
"html": "<p>Thanks for joining us!</p>",
"from": "welcome@example.com",
"contactBookId": "cb_1234567890",
}
campaign_resp, _ = client.campaigns.create(payload=campaign_payload)
# Schedule a campaign
schedule_payload: types.CampaignSchedule = {
"scheduledAt": "2024-12-01T10:00:00Z",
}
schedule_resp, _ = client.campaigns.schedule(
campaign_id=campaign_resp["id"],
payload=schedule_payload
)
# Pause/resume campaigns
client.campaigns.pause(campaign_id="campaign_123")
client.campaigns.resume(campaign_id="campaign_123")
# Toggle behavior if desired:
# - raise_on_error=False: return (None, error_dict) instead of raising
# No model parsing occurs; methods return plain dicts following the typed shapes.
client = WorkonwardSend("us_123", raise_on_error=False)
raw, err = client.emails.get(email_id="email_123")
if err:
print("error:", err)
else:
print("ok:", raw)
Webhook Local Example
For a runnable webhook verification demo project, see:
example/webhook-test-project/README.md
Development
This package is managed with Poetry. Models are maintained in-repo under
workonward_reach/types.py (readable names). Update this file as the API evolves.
It is published as workonward-reach on PyPI.
Available Resources
- Emails:
client.emails.send(),client.emails.get() - ContactBooks:
client.contact_books.list(),client.contact_books.create(),client.contact_books.get(),client.contact_books.update() - Contacts:
client.contacts.create(),client.contacts.list(),client.contacts.get(),client.contacts.bulk_create(),client.contacts.bulk_delete() - Domains:
client.domains.create(),client.domains.get(),client.domains.verify() - Campaigns:
client.campaigns.create(),client.campaigns.get(),client.campaigns.schedule(),client.campaigns.pause(),client.campaigns.resume()
Notes
- Human-friendly models are available under
workonward_reach.types(e.g.,EmailCreate,CampaignCreate,Contact,APIError). - Endpoint methods accept TypedDict payloads or plain dicts via the
payload=keyword.
Metadata
Release files for workonward-reach 2.0.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 | Provenance | Actions |
|---|---|---|---|---|
| workonward_reach-2.0.0.tar.gz | 13.7 kB | Without provenance | Details for workonward_reach-2.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| workonward_reach-2.0.0-py3-none-any.whl | Python 3 | none | any | Details for workonward_reach-2.0.0-py3-none-any.whl |
Total release size: 30.8 kB
Release files / workonward_reach-2.0.0.tar.gz
| Download URL | workonward_reach-2.0.0.tar.gz |
|---|---|
| Size | 13.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
017e80f1d21b9587f7d21fc8f6761f314c384d27d7e6333fdf1e78b34e0fb62e
|
|
BLAKE2b-256 checksum How to use checksums |
59e28018ed343071a1436a02916efa6682f44bae7224c28303a6d7809852f88c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / workonward_reach-2.0.0-py3-none-any.whl
| Download URL | workonward_reach-2.0.0-py3-none-any.whl |
|---|---|
| Size | 17.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2700c00c886a12b9e4d389548b636cb8f518e7d7bfb521ead300cf65c21f29b5
|
|
BLAKE2b-256 checksum How to use checksums |
ec5ab874e45f0cf72204152fee35632dd083531a3f433c35a723fd0d4c54cc20
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for workonward-reach 2.0.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.