Skip to main content

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

PyPI version Python Versions License: MIT Type Checked

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 hierarchyAuthenticationError, RateLimitError, NotFoundError and 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.


Built with ❤️ by Furkan Köykıran

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

speedapi_lib-2.0.2.tar.gz (21.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

speedapi_lib-2.0.2-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

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

Hashes for speedapi_lib-2.0.2.tar.gz
Algorithm Hash digest
SHA256 d75118bd54d7e8404c19cb154f762efd8ae4ed9084ded0c2ef254fd679bfe17a
MD5 8e6e9b79b2177c7f71523caa59192869
BLAKE2b-256 504a824efa61aa50ff2e215b7aa971a6a4f132bfa563221c80f2da4dc2357d31

See more details on using hashes here.

Provenance

The following attestation bundles were made for speedapi_lib-2.0.2.tar.gz:

Publisher: publish.yml on furkankoykiran/speedapi_lib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for speedapi_lib-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5aacf4c4c020ddb3fc7398f5a8a57171a4a09497ac88ebe2d49a8a790569b9fa
MD5 fa8f7e26196cf65469f2abff4d4e4c1b
BLAKE2b-256 dab2adad7fd313494814c300204ad00bd3ec868ec520b7077fb311875cd79692

See more details on using hashes here.

Provenance

The following attestation bundles were made for speedapi_lib-2.0.2-py3-none-any.whl:

Publisher: publish.yml on furkankoykiran/speedapi_lib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page