Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

byourside-0.1.0.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

byourside-0.1.0-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

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

Hashes for byourside-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e08d2d3b6723277a899a2888a28be9d3f5ab0f25e7e5b0e1d93744e3c859f868
MD5 1a804b2667dc9b053922206c3e833ee0
BLAKE2b-256 dae7986000c393e16cdd584da19a7e249113cea4ea53722d22114000a712a436

See more details on using hashes here.

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

Hashes for byourside-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1339c511709cbec07c9835fbb0045b365c608d7ffea5cdf693597bc7250d19b7
MD5 addd5fe32d1ffc7f19e10e1c9a77ce5c
BLAKE2b-256 80b0f8b1f8791abae4d6b456a564719afe7bbfada7c3bd8d43e72984745c0153

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page