Skip to main content

⚡ 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 hierarchy — AuthenticationError, 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

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)

Source distribution for speedapi-lib 2.0.2
File Size Uploaded
speedapi_lib-2.0.2.tar.gz 21.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for speedapi-lib 2.0.2
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

2.0.2 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

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