Now in early access·Start your 14-day free trial →
By Your Side
Sign inBook a demoStart free trial

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)

Node SDK - import 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

Node SDK - create 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

Node SDK - placeCall + waitForCall
// 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

Node SDK - listCalls
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).

Node SDK - error handling
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)

Node SDK - verifyWebhook (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)

Python SDK - import from source
# Clone the repository and run from source (sdks/python/)
# PyPI publish is coming in a future release
from byourside import Client

Create a client

Python SDK - create client
from byourside import Client, ByoursideError

client = Client(api_key='bys_ak_YOUR_KEY')

Place a call and wait for the result

Python SDK - place_call + wait_for_call
# 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

Python SDK - list_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.

Python SDK - error handling
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)

Python SDK - verify_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 '', 200

Terminal 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.

StatusMeaning
completedCall finished normally. Summary and extracted fields available.
no_answerDestination did not pick up.
voicemailReached voicemail.
declinedCall rejected by recipient.
failedTechnical failure.

For the full API shape, see the API reference. For real-time call events without polling, see Webhooks.