Skip to main content

Voxplo SDK: give an AI a phone (outbound objective-driven calls).

Project description

Voxplo Python SDK

Zero-dependency Python client for the Voxplo 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 voxplo 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

Voxplo 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 voxplo 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 voxplo 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 voxplo/ 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 voxplo/errors.py voxplo/client.py voxplo/webhooks.py voxplo/__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

voxplo-0.1.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

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

voxplo-0.1.0-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file voxplo-0.1.0.tar.gz.

File metadata

  • Download URL: voxplo-0.1.0.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for voxplo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 972b1c7402531ee32641e0c18aa1d89598a91a7405680e2993c98e8e8623f927
MD5 2008c14b5eb736e1b6e9c7e624b567c6
BLAKE2b-256 65b01e751c77d31d1a46926923d87342071869fee036877d57dbe49f2a5a0770

See more details on using hashes here.

File details

Details for the file voxplo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: voxplo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for voxplo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1c482af60575d144cf450f74c0ed97c9f7873af870ba76b59e5d530875188cad
MD5 fc9f59379cdf7e79f2ac5532936044a8
BLAKE2b-256 59629228cc2d2acccab1a52efce297f7312f0718e6797500ece27d44df4c7dbc

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