⚡ speedapi-python
The official Python SDK for the Speed Merchant API
Sync & async support · Pydantic v2 models · Full type hints · Webhook verification
Features
- 🔄 Sync & Async clients powered by
httpx - 🧩 Pydantic v2 request / response models with IDE autocomplete
- 🛡️ Rich error hierarchy —
AuthenticationError,RateLimitError,NotFoundErrorand more - 🔗 Checkout Sessions, Invoices, Pay Requests, Balances
- 🔒 Webhook signature verification (HMAC-SHA256 with replay protection)
- 🐍 Python 3.9+ with 100% type annotations
Installation
pip install speedapi-python
Quick Start
Synchronous
from speedapi import SpeedAPI
client = SpeedAPI(api_key="sk_live_...")
# Check balance
balance = client.balances.retrieve()
sats = client.balances.retrieve_sats()
print(f"Available: {sats} SATS")
# Create a checkout session
session = client.checkout_sessions.create(
amount=5000, # amount in cents (for USD)
currency="USD",
success_url="https://example.com/success",
cancel_url="https://example.com/cancel",
description="Premium subscription",
)
print(f"Redirect to: {session.url}")
# Create a Lightning pay request
pr = client.pay_requests.create(
amount=21000,
currency="SATS",
description="Coffee ☕",
)
print(f"Pay via: {pr.lightning_invoice}")
Asynchronous (async/await)
import asyncio
from speedapi import AsyncSpeedAPI
async def main():
async with AsyncSpeedAPI(api_key="sk_live_...") as client:
# All resources work identically — just add await
balance = await client.balances.retrieve()
session = await client.checkout_sessions.create(
amount=5000,
currency="USD",
success_url="https://example.com/success",
)
print(session.url)
asyncio.run(main())
FastAPI Integration Example
from fastapi import FastAPI, Request
from speedapi import AsyncSpeedAPI
app = FastAPI()
speed = AsyncSpeedAPI(api_key="sk_live_...")
@app.post("/create-session")
async def create_session():
session = await speed.checkout_sessions.create(
amount=999,
currency="USD",
success_url="https://myapp.com/success",
)
return {"checkout_url": session.url}
API Reference
SpeedAPI / AsyncSpeedAPI
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str |
required | Your Speed secret key (sk_live_...) |
base_url |
str |
https://api.tryspeed.com |
API base URL |
timeout |
float |
30.0 |
Request timeout in seconds |
Resources
client.balances
| Method | Returns | Description |
|---|---|---|
retrieve() |
Balance |
All available/pending balances |
retrieve_sats() |
float |
Available SATS balance (convenience) |
client.checkout_sessions
| Method | Returns | Description |
|---|---|---|
create(amount, currency, ...) |
CheckoutSession |
Create a hosted checkout page |
retrieve(session_id) |
CheckoutSession |
Get a session by ID |
list(limit, ...) |
CheckoutSessionList |
List sessions (paginated) |
expire(session_id) |
CheckoutSession |
Expire an open session |
client.invoices
| Method | Returns | Description |
|---|---|---|
create(amount, currency, ...) |
Invoice |
Create a new invoice |
retrieve(invoice_id) |
Invoice |
Get an invoice by ID |
list(limit, ...) |
InvoiceList |
List invoices (paginated) |
client.pay_requests
| Method | Returns | Description |
|---|---|---|
create(amount, currency, ...) |
PayRequest |
Create a pay request (Lightning) |
retrieve(pay_request_id) |
PayRequest |
Get a pay request by ID |
list(limit, ...) |
PayRequestList |
List pay requests (paginated) |
Error Handling
speedapi-python raises specific exceptions for every error class — no need to inspect raw status codes.
from speedapi import (
SpeedAPI,
AuthenticationError,
RateLimitError,
NotFoundError,
APIStatusError,
APIConnectionError,
)
client = SpeedAPI(api_key="sk_live_...")
try:
session = client.checkout_sessions.retrieve("cs_nonexistent")
except AuthenticationError:
print("Invalid API key — check your credentials")
except NotFoundError:
print("Session not found")
except RateLimitError:
print("Too many requests — back off and retry")
except APIConnectionError as e:
print(f"Network error: {e}")
except APIStatusError as e:
print(f"Unexpected API error {e.status_code}: {e.response_body}")
Exception Hierarchy
SpeedAPIError
├── AuthenticationError # HTTP 401
├── PermissionDeniedError # HTTP 403
├── NotFoundError # HTTP 404
├── RateLimitError # HTTP 429
├── APIStatusError # other 4xx / 5xx (carries .status_code + .response_body)
└── APIConnectionError # network-level (timeout, DNS, etc.)
Webhook Verification
Speed signs every webhook with HMAC-SHA256. Always verify the signature before processing.
from fastapi import FastAPI, Request, HTTPException
from speedapi.resources.webhooks import Webhooks, WebhookSignatureVerificationError
app = FastAPI()
WEBHOOK_SECRET = "whsec_..." # from your Speed Dashboard
@app.post("/webhooks/speed")
async def speed_webhook(request: Request):
payload = await request.body()
sig_header = request.headers.get("Speed-Signature", "")
try:
event = Webhooks.construct_event(
payload=payload,
sig_header=sig_header,
secret=WEBHOOK_SECRET,
)
except WebhookSignatureVerificationError as e:
raise HTTPException(status_code=400, detail=str(e))
if event.type == "checkout_session.completed":
session_id = event.data.get("object", {}).get("id")
print(f"✅ Checkout completed: {session_id}")
elif event.type == "invoice.paid":
invoice_id = event.data.get("object", {}).get("id")
print(f"💰 Invoice paid: {invoice_id}")
return {"received": True}
Security: The SDK automatically rejects webhooks older than 5 minutes to prevent replay attacks.
Development
# Clone the repo
git clone https://github.com/furkankoykiran/speedapi_lib
cd speedapi_lib
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run the test suite
pytest tests/ -v --tb=short --cov=src/speedapi
# Type check
mypy src/speedapi
License
MIT — see LICENSE for details.
Metadata
Release files for speedapi-lib 2.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| speedapi_lib-2.0.2.tar.gz | 21.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| speedapi_lib-2.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.6 kB
Release files / speedapi_lib-2.0.2.tar.gz
| Download URL | speedapi_lib-2.0.2.tar.gz |
|---|---|
| Size | 21.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d75118bd54d7e8404c19cb154f762efd8ae4ed9084ded0c2ef254fd679bfe17a
|
|
BLAKE2b-256 checksum How to use checksums |
504a824efa61aa50ff2e215b7aa971a6a4f132bfa563221c80f2da4dc2357d31
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 5, 2026.
Transparency logRelease files / speedapi_lib-2.0.2-py3-none-any.whl
| Download URL | speedapi_lib-2.0.2-py3-none-any.whl |
|---|---|
| Size | 20.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5aacf4c4c020ddb3fc7398f5a8a57171a4a09497ac88ebe2d49a8a790569b9fa
|
|
BLAKE2b-256 checksum How to use checksums |
dab2adad7fd313494814c300204ad00bd3ec868ec520b7077fb311875cd79692
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Mar 5, 2026.
Transparency log