Skip to main content

L402-Requests

Discord

Auto-paying L402 HTTP client for Python. APIs behind Lightning paywalls just work.

L402-Requests wraps httpx and automatically handles HTTP 402 responses by paying Lightning invoices and retrying with L402 credentials. It's a drop-in HTTP client where any API behind an L402 paywall "just works."

Install

pip install l402-requests

Quick Start

import l402_requests

# Any L402-protected API just works — invoice is paid automatically
response = l402_requests.get("https://api.example.com/paid-resource")
print(response.json())

That's it. The library detects your wallet from environment variables, pays the Lightning invoice when it gets a 402 response, and retries with L402 credentials.

Wallet Configuration

Set environment variables for your preferred wallet. The library auto-detects in this order:

Priority Wallet Environment Variables Preimage Support
1 LND LND_REST_HOST, LND_MACAROON_HEX Yes
2 NWC NWC_CONNECTION_STRING Yes (CoinOS, CLINK)
3 Strike STRIKE_API_KEY Yes
4 OpenNode OPENNODE_API_KEY Limited

Recommended: Strike (full preimage support, no infrastructure required).

export STRIKE_API_KEY="your-strike-api-key"

LND

export LND_REST_HOST="https://localhost:8080"
export LND_MACAROON_HEX="your-admin-macaroon-hex"
export LND_TLS_CERT_PATH="/path/to/tls.cert"  # optional

NWC (Nostr Wallet Connect)

NWC works out of the box on every platform including Windows — the required crypto (coincurve + cryptography + websockets) ships as a base dependency with prebuilt wheels, so there is no pip install ...[nwc] extra step.

export NWC_CONNECTION_STRING="nostr+walletconnect://pubkey?relay=wss://relay&secret=hex"

The legacy [nwc] extra is preserved as a no-op for back-compat — pip install l402-requests[nwc] still resolves, but the base install already covers it.

OpenNode

export OPENNODE_API_KEY="your-opennode-key"

Note: OpenNode does not return payment preimages, which limits L402 functionality. For full L402 support, use Strike, LND, or a compatible NWC wallet.

Budget Controls

Safety first — budgets are enabled by default to prevent accidental overspending:

from l402_requests import L402Client, BudgetController

# Custom budget limits
client = L402Client(
    budget=BudgetController(
        max_sats_per_request=500,     # Max per single payment (default: 1000)
        max_sats_per_hour=5000,       # Hourly rolling limit (default: 10000)
        max_sats_per_day=25000,       # Daily rolling limit (default: 50000)
        allowed_domains={"api.example.com"},  # Optional domain allowlist
    )
)

# Disable budgets entirely (not recommended)
client = L402Client(budget=None)

If a payment would exceed any limit, BudgetExceededError is raised before the payment is attempted.

Explicit Wallet

from l402_requests import L402Client, StrikeWallet

client = L402Client(
    wallet=StrikeWallet(api_key="your-key"),
)
response = client.get("https://api.example.com/paid-resource")

Async Support

from l402_requests import AsyncL402Client

async with AsyncL402Client() as client:
    response = await client.get("https://api.example.com/paid-resource")
    print(response.json())

Spending Introspection

Track every payment made during a session:

from l402_requests import L402Client

client = L402Client()
client.get("https://api.example.com/data")
client.get("https://api.example.com/more-data")

# Inspect spending
print(f"Total spent: {client.spending_log.total_spent()} sats")
print(f"Last hour: {client.spending_log.spent_last_hour()} sats")
print(f"By domain: {client.spending_log.by_domain()}")

# Export as JSON
print(client.spending_log.to_json())

How It Works

  1. Your code makes an HTTP request via L402Client
  2. If the server returns 200, the response is returned as-is
  3. If the server returns 402 with an L402 challenge:
    • The WWW-Authenticate: L402 macaroon="...", invoice="..." header is parsed
    • The BOLT11 invoice amount is checked against your budget
    • The invoice is paid via your configured Lightning wallet
    • The request is retried with Authorization: L402 {macaroon}:{preimage}
  4. Credentials are cached so subsequent requests to the same endpoint don't require re-payment

Two-Step L402 Flows (Commerce)

Some servers intentionally use a two-step L402 flow where payment and claim are separate endpoints. This is common for physical goods — it separates payment from fulfillment and allows the claim URL to be shared with a gift recipient.

For example, the Lightning Enable Store returns a 402 on POST /checkout, and after payment you claim the order at POST /claim with the L402 credential.

In these cases, L402-Requests pays the invoice automatically. Use the spending_log to retrieve the credential (macaroon + preimage), then make the claim request:

from l402_requests import L402Client, BudgetController

# Store products cost ~48,000 sats incl. shipping — raise the hourly/daily
# caps too, or the default 10k/hour budget rejects the purchase.
client = L402Client(budget=BudgetController(
    max_sats_per_request=50000, max_sats_per_hour=50000, max_sats_per_day=100000))
checkout = client.post("https://store.lightningenable.com/api/store/checkout",
    json={"items": [{"productId": 2, "quantity": 1, "size": "L", "color": "Black"}]})

# Payment was made — retrieve the credential from the spending log
record = client.spending_log.records[-1]
print(f"Paid {record.amount_sats} sats")

# Claim the order with the L402 credential
import httpx
claim = httpx.post(
    "https://store.lightningenable.com/api/store/claim",
    headers={"Authorization": f"L402 {record.macaroon}:{record.preimage}"},
    json=claim_details,  # shipping details etc. — see the store's API docs
)

See the full documentation for the complete store purchasing example.

Usage with AI Agents

L402-Requests is the consumer-side complement to the Lightning Enable MCP Server. While the MCP server gives AI agents wallet tools, L402-Requests lets your Python code access paid APIs without any agent framework.

Part of Lightning Enable — infrastructure for agent commerce over Lightning. See the full ecosystem.

LangChain Tool

from langchain.tools import tool
from l402_requests import L402Client, BudgetController

_client = L402Client(budget=BudgetController(max_sats_per_request=100))

@tool
def fetch_paid_api(url: str) -> str:
    """Fetch data from an L402-protected API. Payment is handled automatically."""
    response = _client.get(url)
    return response.text

See the full LangChain integration guide.

AG2 (AutoGen) Tool

from l402_requests import L402Client, BudgetController
from autogen import ConversableAgent, register_function

client = L402Client(budget=BudgetController(max_sats_per_request=100))

def fetch_l402_resource(url: str) -> str:
    """Fetch data from an L402-protected API. Payment is handled automatically."""
    response = client.get(url)
    return response.text

assistant = ConversableAgent("assistant", llm_config=llm_config)
executor = ConversableAgent("executor", human_input_mode="NEVER")

register_function(
    fetch_l402_resource,
    caller=assistant,
    executor=executor,
    description="Fetch data from an L402-protected API with automatic Lightning payment",
)

See the full AG2 integration guide.

CrewAI Tool

from crewai.tools import tool
from l402_requests import L402Client, BudgetController

_client = L402Client(budget=BudgetController(max_sats_per_request=100))

@tool("L402 API Fetcher")
def fetch_l402_api(url: str) -> str:
    """Fetch data from an L402-protected API. Payment is handled automatically."""
    response = _client.get(url)
    return response.text

See the full CrewAI integration guide.

Standalone Script

import l402_requests

# Any L402-protected API just works
data = l402_requests.get("https://api.example.com/premium-data").json()

What is L402?

L402 (formerly LSAT) is a protocol for monetizing APIs with Lightning Network micropayments. Instead of API keys or subscriptions, servers return HTTP 402 ("Payment Required") with a Lightning invoice. Once paid, the client receives a credential (macaroon + payment preimage) that grants access.

Learn more: docs.lightningenable.com

Example: MaximumSats API

MaximumSats provides paid Lightning Network APIs including AI DVM, WoT reports, Nostr analysis, and more. Use L402-Requests to automatically pay for these endpoints:

import l402_requests

# Call MaximumSats AI DVM endpoint — invoice is paid automatically
response = l402_requests.get("https://maximumsats.com/api/dvm")
data = response.json()

Set your wallet via environment variable:

export STRIKE_API_KEY="your-strike-api-key"

The library automatically handles the L402 payment protocol — you just get the data.

License

MIT — see LICENSE.

Metadata

Release files for l402-requests 0.8.0

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

Source distribution (sdist)

Source distribution for l402-requests 0.8.0
File Size Uploaded
l402_requests-0.8.0.tar.gz 81.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for l402-requests 0.8.0
File Interpreter ABI Platform
l402_requests-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 135.3 kB

Release files / l402_requests-0.8.0.tar.gz

Download URL l402_requests-0.8.0.tar.gz
Size 81.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0d9d5103c96f8e544a9a4e4dc793aea7d5c11ca25af469f4869c8a9404560362
BLAKE2b-256 checksum
How to use checksums
2d11802fe84fa1558be7f655d4b0acbdcf7bf8aa90cfc3855499cdccd1d29613
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release files / l402_requests-0.8.0-py3-none-any.whl

Download URL l402_requests-0.8.0-py3-none-any.whl
Size 53.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81e84d1dadc103d3fa07f34113ee0dfde7b03d84a38e19d8a8c2ea69ab7ef3c8
BLAKE2b-256 checksum
How to use checksums
e5c3e7112c1e0e893ef88e5c5018431910715b5c89847ebd8428966cf387b37c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.16

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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