Skip to main content

helpvox — Python SDK for the HelpVox app platform

Build apps that plug into HelpVox: install via OAuth, receive events, give the AI agent tools, embed a dashboard page and call the REST API. Python 3.9+, no dependencies.

pip install helpvox

The wire contract this SDK follows is in docs/apps/platform-contract.md. You need your app's client_id (hvapp_…) and client_secret (hvs_…). The secret is the HMAC key for everything HelpVox sends you — keep it in one environment variable.

Install (OAuth)

Send the merchant to the consent screen, then exchange the code on your callback:

import helpvox

url = helpvox.install_url("loyalty-points", redirect_url="https://app.example/oauth/callback", state=csrf)

# GET /oauth/callback?code=hvic_…&installation_id=…&state=…
token = helpvox.exchange_code(CLIENT_ID, CLIENT_SECRET, code)
# {"access_token": "hva_…", "token_type": "bearer", "scope": "…", "installation_id": "…", "vendor_id": "…"}
store(token["installation_id"], token["access_token"])

# Your agent tools stay off until you say you are ready:
helpvox.Client(token["access_token"]).ready()

Codes live 10 minutes and work once — exchanging the same code twice revokes the installation. Failures raise helpvox.ApiError (e.code == "invalid_grant").

Events

Always verify against the raw request body.

from helpvox import parse_event, SignatureError

try:
    event = parse_event(CLIENT_SECRET, raw_body, request_headers)
except SignatureError:
    return 401

if already_processed(event.id):   # the same id is sent on every retry
    return 200
if event.type == "order.status_changed":
    ...
elif event.type == "app.uninstalled":
    delete_data(event.installation_id)

Event has id, type, created_at, vendor_id, installation_id, data, is_test. Header lookup is case-insensitive and accepts any dict-like headers object. Answer 2xx within 10 seconds. Send yourself a sample with client.send_test_event("order.created") (event.is_test is True).

Agent tools

Your handler gets (input, context) and returns plain text for the agent (cut to 2000 characters), or raises ToolError with a short reason the agent can tell the customer.

from helpvox import ToolContext, ToolError, handle_tool_call

def get_balance(input: dict, ctx: ToolContext) -> str:
    points = lookup(ctx.installation_id, input["phone"])
    if points is None:
        raise ToolError("There is no loyalty account for this phone number.")
    return f"The customer has {points} points."

handle_tool_call returns (status, json_body): 401 for a bad signature, 400 for a malformed body, otherwise 200 with {"result": …} or {"error": …}. Other exceptions propagate; HelpVox then continues without the tool. ToolContext has tool, installation_id, vendor_id, channel, conversation_id, language, country, caller_phone.

Flask:

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.post("/tools/balance")
def balance():
    status, body = handle_tool_call(CLIENT_SECRET, request.get_data(), request.headers, get_balance)
    return jsonify(body), status

FastAPI:

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.post("/tools/balance")
async def balance(request: Request):
    status, body = handle_tool_call(CLIENT_SECRET, await request.body(), request.headers, get_balance)
    return JSONResponse(body, status_code=status)

Phone tools have 1500 ms by default, so keep the handler fast (if it blocks, run it in a thread pool in async frameworks). Events work the same way: parse_event(CLIENT_SECRET, request.get_data(), request.headers).

Dashboard page

If your manifest sets ui.settings_page, HelpVox embeds it with ?installation_id=…&session=<JWT>. The token lives 60 seconds — verify it, then start your own session:

from helpvox import verify_session_token

claims = verify_session_token(CLIENT_SECRET, request.args["session"], CLIENT_ID)
if claims is None:
    abort(401)
login(installation_id=claims["installation_id"], user=claims["sub"], lang=claims["lang"])

sign_session_token(secret, claims) issues one the same way HelpVox does, for your tests.

REST API

from helpvox import ApiError, Client

client = Client(access_token)

client.app()                          # installation, vendor, scopes, ready, capabilities
orders = client.orders(status="new", limit=50)
client.order(order_id)
client.update_order(order_id, {"note": "Gift wrap"})          # orders:write
client.products(); client.calls(); client.call(call_id)
client.callbacks(); client.appointments()

d = client.create_discount(conversation_id, 12.00, "EUR", "Loyalty points", reference="ledger-42")
client.discount(d["id"]); client.cancel_discount(d["id"])

# anything else
client.request("GET", "/api/v1/categories")

try:
    client.calls()
except ApiError as e:
    print(e.status, e.code, e.message, e.scope)   # 403 insufficient_scope … conversations:read

Customer fields are removed from responses without customers:read; transcripts without transcripts:read.

For tests, pass transport= — a callable (method, url, headers, body_bytes) -> (status, body_bytes) — to Client or exchange_code. Signatures: helpvox.sign(secret, body) / helpvox.verify(secret, body, header).

Development

cd sdk/python
python3 -m unittest discover -s tests

Metadata

Release files for helpvox 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for helpvox 0.2.0
File Size Uploaded Provenance
helpvox-0.2.0.tar.gz 15.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for helpvox 0.2.0
File Interpreter ABI Platform
helpvox-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.5 kB

Release files / helpvox-0.2.0.tar.gz

Download URL helpvox-0.2.0.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
a9d8d604642f2032a0dc90c9cde6293552dfc8465af38b766da040cfcd033f97
BLAKE2b-256 checksum
How to use checksums
90a43e745cc10e9c194d25c17212904b2ab585b3511b6cf8218dcecac735f4d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / helpvox-0.2.0-py3-none-any.whl

Download URL helpvox-0.2.0-py3-none-any.whl
Size 15.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ed5841afdb7b93ef2f0da70122f32817a0b0aa464129f0fc511e6ef9448787c2
BLAKE2b-256 checksum
How to use checksums
3d147820e0a32798cda7c138c1491a4deb1556616cef10746aedf21212b44d67
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Security for helpvox 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for helpvox-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page