Skip to main content

pitchmentor

PyPI Python CI MIT

Official Python SDK for the Pitch Mentor API (https://api.pitchmentor.net/v1). Python 3.11+, synchronous, built on requests. Responses are plain dicts typed with TypedDicts (Call, Lead, Page[Call], …), so editors and mypy check them.

API reference: https://pitchmentor.net/docs

Install

pip install pitchmentor

Authentication

Create a team API key (pm_live_…) in the Pitch Mentor dashboard. It is sent as Authorization: Bearer pm_live_…. The client reads PITCHMENTOR_API_KEY (and optionally PITCHMENTOR_BASE_URL) from the environment, or takes them as arguments. Each key has scopes (calls:read, leads:write, …); every method's docstring names the scope it needs.

from pitchmentor import PitchMentor

pm = PitchMentor()  # or PitchMentor("pm_live_…", base_url=..., max_retries=2, timeout=60.0)

The client holds a requests.Session; use it as a context manager (with PitchMentor() as pm:) or call pm.close().

Quick start

me = pm.get_me()
detail = pm.get_call("call_id")
overview = pm.get_analytics_overview(period="30d")
per_member = pm.get_analytics_by_member(period="30d")
pm.upsert_lead({"name": "Ada Lovelace", "externalId": "crm-42", "email": "ada@example.com"})
pm.update_team_config({"toneGuidelines": "Friendly, concise."})
team = pm.get_team_config()
billing = pm.get_billing_status()
usage = pm.list_member_usage()
referrals = pm.get_referral_stats()
csv = pm.export_calls(format="csv")
pm.list_calls(from_="2026-01-01", archived=True)  # `from` is `from_` in Python

Every API operation is a method named after its operationId in snake_case (list_calls, get_call, create_webhook_endpoint, …). pm.request(method, path, query=..., body=...) reaches endpoints newer than the SDK.

Pagination

List methods return one page: {"data": [...], "has_more": bool, "next_cursor": str | None}. Pass next_cursor as cursor for the next page, or use the …_iter method, which walks every page:

page = pm.list_calls(period="7d", limit=50)
for call in pm.list_calls_iter(period="7d"):
    print(call["id"], call["prospectName"])

Paginated: list_calls, list_leads, list_api_keys, list_webhook_endpoints, list_webhook_deliveries.

Retries, timeouts and idempotency

429, 5xx and connection errors are retried (max_retries, default 2) with exponential backoff, honoring retry-after. Every POST carries an Idempotency-Key, generated unless you pass one and reused across retries, so a retried POST never runs twice. Pass your own key to make a POST safe to repeat across processes:

pm.upsert_lead({"name": "Ada", "externalId": "crm-42"}, idempotency_key="import-42")

Errors

Non-2xx responses raise a PitchMentorError subclass with status, code (machine-readable, e.g. not_found, insufficient_scope), message, headers and body: BadRequestError (400), AuthenticationError (401), PermissionDeniedError (403), NotFoundError (404), ConflictError (409), UnprocessableEntityError (422), RateLimitError (429, has retry_after seconds), InternalServerError (5xx). A request that never got a response raises APIConnectionError.

from pitchmentor import NotFoundError, PitchMentorError

try:
    pm.get_call("missing")
except NotFoundError:
    print("no such call")
except PitchMentorError as e:
    print(e.status, e.code, e.message)

Webhooks

Webhooks are signed with Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature). verify_webhook checks the signature against your endpoint's whsec_… secret, rejects timestamps older than 5 minutes (tolerance=300), and returns the parsed event. Always pass the raw request body.

import os

from flask import Flask, request
from pitchmentor import verify_webhook, WebhookVerificationError

app = Flask(__name__)

@app.post("/hooks/pitchmentor")
def hook():
    try:
        event = verify_webhook(os.environ["PITCHMENTOR_WEBHOOK_SECRET"], request.headers, request.get_data())
    except WebhookVerificationError:
        return "", 400
    if event["type"] == "call.completed":
        print(event["data"]["id"])
    return "", 204

Development

python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/mypy && .venv/bin/python -m unittest discover -s tests

Regenerating from the API

src/pitchmentor/_generated.py is generated by codegen/generate.mjs from openapi.json, a copy of the live spec at https://api.pitchmentor.net/v1/openapi.json. Don't edit it by hand:

scripts/regen.sh       # download the live spec and regenerate (needs curl and Node 20+)
node codegen/generate.mjs    # regenerate from the committed openapi.json (after changing the generator)

Everything else (transport, retries, errors, pagination, webhooks) is hand-written. The weekly Regen workflow runs the same script and opens a pull request when the live spec changes.

Releasing

  1. Bump version in pyproject.toml and __version__ in src/pitchmentor/_client.py (scripts/check-version.sh X.Y.Z checks both), merge to main.
  2. git tag vX.Y.Z && git push origin vX.Y.Z. The Release workflow tests, builds and publishes to PyPI with trusted publishing (environment pypi, with attestations) and creates the GitHub Release.

Support

Docs · Status · Discord. Security issues: see the security policy.

License

MIT

Metadata

Release files for pitchmentor 0.1.1

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

Source distribution (sdist)

Source distribution for pitchmentor 0.1.1
File Size Uploaded Provenance Actions
pitchmentor-0.1.1.tar.gz 18.9 kB Without provenance Details for pitchmentor-0.1.1.tar.gz

Built distribution (wheel)

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

Total release size: 34.2 kB

Release files / pitchmentor-0.1.1.tar.gz

Download URL pitchmentor-0.1.1.tar.gz
Size 18.9 kB
Tags Source
SHA-256 checksum
How to use checksums
07a0406d4ddc87ee147281a41422a7a71975493fac0584f466cc73ad0a8b27ca
BLAKE2b-256 checksum
How to use checksums
46a61fa6a61a6ec49168c18e475665f9b3ec8d974429d99328d48c5d628edda6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / pitchmentor-0.1.1-py3-none-any.whl

Download URL pitchmentor-0.1.1-py3-none-any.whl
Size 15.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
299420829e09cbec83a29d0b6d3a3dc6ab117996133d847a9718ed5038de5c14
BLAKE2b-256 checksum
How to use checksums
8e3db4f114dda2f9ca9a862562efdac5fc0ce965e65679b9bebae4de0175f4e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for pitchmentor 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.1.1 This release

2 release files No 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