By Your Side SDK: give an AI a phone (outbound objective-driven calls).
Project description
By Your Side Python SDK
Zero-dependency Python client for the By Your Side Agent Outbound-Call API. Place objective-driven AI calls, poll for results, and verify webhooks using only the Python standard library.
Requires Python 3.8+. No third-party packages needed.
Quick start
Place a call and wait for the result
from byourside import Client
client = Client(api_key="bys_ak_YOUR_KEY")
# Place an outbound call with an objective
call = client.place_call(
to="+14155550123",
objective="Confirm the appointment for tomorrow at 2pm and ask if they need to reschedule.",
fields=[
{"name": "confirmed", "type": "boolean"},
{"name": "new_time", "type": "string"},
],
)
print("Placed:", call["callId"], "status:", call["status"])
# Poll until the call reaches a terminal status (default timeout: 180s)
result = client.wait_for_call(call["callId"], timeout=180, interval=5)
print("Final status:", result["status"])
print("Extracted fields:", result.get("extracted"))
List recent calls
calls = client.list_calls(limit=10)
for c in calls:
print(c["callId"], c["status"])
Get a specific call
call = client.get_call("call_abc123")
print(call)
Call statuses
| Status | Meaning |
|---|---|
queued |
Call accepted, waiting to be placed |
in_progress |
Call is active |
completed |
Call finished normally (terminal) |
no_answer |
Recipient did not pick up (terminal) |
voicemail |
Reached voicemail (terminal) |
declined |
Recipient declined the call (terminal) |
failed |
Call could not complete (terminal) |
wait_for_call returns once the status is one of the five terminal states.
Webhook verification
By Your Side sends a X-BYS-Signature header with each webhook delivery.
Verify it before processing the payload.
Flask example
from flask import Flask, request, abort
from byourside import verify_webhook
app = Flask(__name__)
WEBHOOK_SECRET = "whsec_YOUR_SECRET"
@app.route("/webhook/bys", methods=["POST"])
def bys_webhook():
sig = request.headers.get("X-BYS-Signature", "")
raw_body = request.get_data(as_text=True)
if not verify_webhook(sig, raw_body, WEBHOOK_SECRET):
abort(400, "Invalid signature")
payload = request.get_json()
print("Call update:", payload["callId"], payload["status"])
return "", 200
The signature format is t=<unix_seconds>,v1=<hex> where
hex = HMAC-SHA256(secret, f"{t}.{raw_body}").
verify_webhook never raises. It returns False for invalid or expired signatures
(default tolerance: 300 seconds).
Error handling
All API errors raise ByoursideError:
from byourside import Client, ByoursideError
client = Client(api_key="bys_ak_YOUR_KEY")
try:
client.place_call(to="+19001234567", objective="Sell something")
except ByoursideError as e:
print(e.code) # e.g. "destination_blocked"
print(e.status) # HTTP status, or 0 for network/timeout errors
print(str(e)) # Human-readable message
Common error codes:
| Code | Meaning |
|---|---|
destination_blocked |
Destination not allowed (premium, IRSF, or unsupported country) |
invalid_number |
Number must be E.164, e.g. +14155550123 |
to_required |
Missing destination number |
objective_required |
Missing call objective |
caller_id_not_owned |
Caller ID not on your account |
rate_limited |
Rate limit reached, retry shortly |
over_minute_cap |
Outbound usage limit reached |
unauthorized |
Invalid or missing API key |
not_found |
Call ID not found |
placement_failed |
Carrier or trunk issue, retry shortly |
store_error |
Temporary service error, retry shortly |
network_error |
Could not reach the API |
timeout |
wait_for_call deadline exceeded |
Development
Clone the repo. No install step needed for local use: run tests from the sdks/python/ directory so that byourside/ is on the path automatically.
cd sdks/python
python3 -m unittest discover -s tests
Expected output: all tests pass (11 tests across errors, client, wait, and webhooks).
If your environment does not add CWD to the path automatically, use:
cd sdks/python
PYTHONPATH=. python3 -m unittest discover -s tests
Syntax check all source files:
python3 -m py_compile byourside/errors.py byourside/client.py byourside/webhooks.py byourside/__init__.py
Publishing to PyPI is deferred. Do not publish without explicit owner approval.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file byourside-0.1.0.tar.gz.
File metadata
- Download URL: byourside-0.1.0.tar.gz
- Upload date:
- Size: 7.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e08d2d3b6723277a899a2888a28be9d3f5ab0f25e7e5b0e1d93744e3c859f868
|
|
| MD5 |
1a804b2667dc9b053922206c3e833ee0
|
|
| BLAKE2b-256 |
dae7986000c393e16cdd584da19a7e249113cea4ea53722d22114000a712a436
|
File details
Details for the file byourside-0.1.0-py3-none-any.whl.
File metadata
- Download URL: byourside-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1339c511709cbec07c9835fbb0045b365c608d7ffea5cdf693597bc7250d19b7
|
|
| MD5 |
addd5fe32d1ffc7f19e10e1c9a77ce5c
|
|
| BLAKE2b-256 |
80b0f8b1f8791abae4d6b456a564719afe7bbfada7c3bd8d43e72984745c0153
|