Python SDK for the Speed Merchant API — sync & async, Pydantic v2, full type hints
Project description
⚡ 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.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file speedapi_lib-2.0.2.tar.gz.
File metadata
- Download URL: speedapi_lib-2.0.2.tar.gz
- Upload date:
- Size: 21.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d75118bd54d7e8404c19cb154f762efd8ae4ed9084ded0c2ef254fd679bfe17a
|
|
| MD5 |
8e6e9b79b2177c7f71523caa59192869
|
|
| BLAKE2b-256 |
504a824efa61aa50ff2e215b7aa971a6a4f132bfa563221c80f2da4dc2357d31
|
Provenance
The following attestation bundles were made for speedapi_lib-2.0.2.tar.gz:
Publisher:
publish.yml on furkankoykiran/speedapi_lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
speedapi_lib-2.0.2.tar.gz -
Subject digest:
d75118bd54d7e8404c19cb154f762efd8ae4ed9084ded0c2ef254fd679bfe17a - Sigstore transparency entry: 1044972557
- Sigstore integration time:
-
Permalink:
furkankoykiran/speedapi_lib@1cd99192bc59fa699ecbbfab6cd8ac880685dedb -
Branch / Tag:
refs/tags/v2.0.2 - Owner: https://github.com/furkankoykiran
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1cd99192bc59fa699ecbbfab6cd8ac880685dedb -
Trigger Event:
push
-
Statement type:
File details
Details for the file speedapi_lib-2.0.2-py3-none-any.whl.
File metadata
- Download URL: speedapi_lib-2.0.2-py3-none-any.whl
- Upload date:
- Size: 20.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5aacf4c4c020ddb3fc7398f5a8a57171a4a09497ac88ebe2d49a8a790569b9fa
|
|
| MD5 |
fa8f7e26196cf65469f2abff4d4e4c1b
|
|
| BLAKE2b-256 |
dab2adad7fd313494814c300204ad00bd3ec868ec520b7077fb311875cd79692
|
Provenance
The following attestation bundles were made for speedapi_lib-2.0.2-py3-none-any.whl:
Publisher:
publish.yml on furkankoykiran/speedapi_lib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
speedapi_lib-2.0.2-py3-none-any.whl -
Subject digest:
5aacf4c4c020ddb3fc7398f5a8a57171a4a09497ac88ebe2d49a8a790569b9fa - Sigstore transparency entry: 1044972607
- Sigstore integration time:
-
Permalink:
furkankoykiran/speedapi_lib@1cd99192bc59fa699ecbbfab6cd8ac880685dedb -
Branch / Tag:
refs/tags/v2.0.2 - Owner: https://github.com/furkankoykiran
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1cd99192bc59fa699ecbbfab6cd8ac880685dedb -
Trigger Event:
push
-
Statement type: