Documentation
SDKs
Zero-dependency Python and Node clients for the By Your Side Agent calling API. Both SDKs include a wait_for_call helper that handles polling automatically and a verify_webhook helper for signature verification.
Running from source. Both SDKs are not yet published to PyPI or npm. Clone the repository and run them from sdks/python/ or sdks/node/ respectively. Package publishing is planned for a future release.
Node SDK
Requires Node 18 or newer. No third-party packages needed.
Install (from source)
# Clone the repository and run from source (sdks/node/)
# npm publish is coming in a future release
import { Client, ByoursideError, verifyWebhook } from './src/index.js';Create a client
import { Client, ByoursideError } from './src/index.js';
const client = new Client({ apiKey: 'bys_ak_YOUR_KEY' });Constructor options: apiKey (required), baseUrl (default https://api.byourside.ai), fetchImpl (override built-in fetch, useful for tests), sleep (override poll sleep, useful for tests).
Place a call and wait for the result
// Place a call
const { callId } = await client.placeCall({
to: '+14155550123',
objective: 'Confirm the appointment for tomorrow at 2 PM and ask if they need to reschedule.',
fields: [
{ name: 'confirmed', type: 'boolean' },
{ name: 'new_time', type: 'string' },
],
});
console.log('Placed:', callId);
// Wait until terminal (default timeout: 3 minutes)
const result = await client.waitForCall(callId, { timeoutMs: 180_000, intervalMs: 5_000 });
console.log('Status:', result.status);
console.log('Summary:', result.summary);
console.log('Extracted:', result.extracted);List recent calls
const calls = await client.listCalls({ limit: 20 });
calls.forEach((c) => console.log(c.callId, c.status));Error handling
All API errors throw ByoursideError with a .code token (see the API reference error table) and a .status HTTP status code (0 for network errors).
try {
const { callId } = await client.placeCall({
to: '+19001234567',
objective: 'Test blocked destination',
});
} catch (err) {
if (err instanceof ByoursideError) {
console.error(err.code); // "destination_blocked"
console.error(err.status); // 400
console.error(err.message);
}
}Verify a webhook (Express)
import express from 'express';
import { verifyWebhook } from './src/index.js';
const app = express();
// Parse the body as raw bytes so the signature can be verified.
app.post('/webhooks/bys', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-bys-signature'];
const rawBody = req.body.toString('utf8');
if (!verifyWebhook(sig, rawBody, process.env.BYS_WEBHOOK_SECRET)) {
return res.status(400).send('Bad signature');
}
const event = JSON.parse(rawBody);
console.log('Event:', event.event, event.callId, event.status);
res.status(200).send('OK');
});Python SDK
Requires Python 3.8 or newer. No third-party packages needed.
Install (from source)
# Clone the repository and run from source (sdks/python/)
# PyPI publish is coming in a future release
from byourside import ClientCreate a client
from byourside import Client, ByoursideError
client = Client(api_key='bys_ak_YOUR_KEY')Place a call and wait for the result
# Place a call
call = client.place_call(
to='+14155550123',
objective='Confirm the appointment for tomorrow at 2 PM and ask if they need to reschedule.',
fields=[
{'name': 'confirmed', 'type': 'boolean'},
{'name': 'new_time', 'type': 'string' },
],
)
print('Placed:', call['callId'], 'status:', call['status'])
# Wait until terminal (default timeout: 180 seconds)
result = client.wait_for_call(call['callId'], timeout=180, interval=5)
print('Status:', result['status'])
print('Extracted:', result.get('extracted'))List recent calls
calls = client.list_calls(limit=10)
for c in calls:
print(c['callId'], c['status'])Error handling
All API errors raise ByoursideError with a .code token and a .status HTTP status code.
try:
call = client.place_call(to='+19001234567', objective='Test blocked destination')
except ByoursideError as e:
print(e.code) # "destination_blocked"
print(e.status) # 400
print(str(e))Verify a webhook (Flask)
from flask import Flask, request, abort
from byourside import verify_webhook
app = Flask(__name__)
SECRET = 'whsec_YOUR_SECRET'
@app.route('/webhooks/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, SECRET):
abort(400, 'Invalid signature')
payload = request.get_json()
print('Event:', payload['event'], payload['callId'], payload['status'])
return '', 200Terminal statuses
wait_for_call (Python) and waitForCall (Node) poll until the call reaches one of these five terminal statuses, then return the call record. A timeout error is raised/thrown if the deadline is exceeded.
| Status | Meaning |
|---|---|
completed | Call finished normally. Summary and extracted fields available. |
no_answer | Destination did not pick up. |
voicemail | Reached voicemail. |
declined | Call rejected by recipient. |
failed | Technical failure. |
For the full API shape, see the API reference. For real-time call events without polling, see Webhooks.