hilt-sdk
Official Python SDK for Hilt Pay Workspace and Hilt Pay API.
Source: https://github.com/Hiltpay/hilt-sdk-python
Agent discovery contract:
- Agent manifest:
https://www.hilt.so/.well-known/hilt-agent.json - Agent Discovery Standard:
https://www.hilt.so/agent-discovery-standard - OpenAPI:
https://api.hilt.so/v1/openapi.json - Grok Build guide:
https://docs.hilt.so/developers/grok-build - Runnable Next.js example:
https://github.com/Hiltpay/hilt-developer-assets/tree/main/examples/grok-build-nextjs
This SDK wraps the same public merchant routes documented on docs.hilt.so:
- products
- hosted checkout
- payments
- memberships
- receipts
- support
- webhooks
- Hilt Pay API apps, products, entitlements, setup manifests, and agent bootstrap
- native subscription state and cancellation helpers
- x402 V2 settlement and atomic metered-entitlement consumption
Install
pip install hilt-sdk
Source and release history: https://github.com/Hiltpay/hilt-sdk-python
Example
Metered agent requests
import os
from hilt_sdk import HiltClient, protect_request
client = HiltClient(api_key=os.environ["HILT_API_KEY"])
decision = protect_request(
client=client,
external_product_id="research-calls",
customer_id="agent_42",
request_id="req_01J4W8RQ6M",
resource_url="https://api.example.com/research",
payment_signature=request.headers.get("PAYMENT-SIGNATURE"),
)
if not decision.allowed:
return JSONResponse(decision.body, status_code=decision.status_code, headers=decision.headers)
return run_paid_research()
protect_request returns an allow-or-challenge decision and never authorizes billable work before atomic usage consumption. One payment can grant many units. Use create_payment_signature when the buyer wallet integration already returns a signed Solana transaction as base64.
Guide: https://docs.hilt.so/developers/protect-an-endpoint
Complete TypeScript transaction example: https://github.com/Hiltpay/hilt-developer-assets/tree/main/examples/agent-micropayments
Agent-first Hilt Pay API bootstrap
Hilt Pay API supports live Solana USDC and native SOL settlement. The payment_protocol: "x402" field describes the protected-resource HTTP 402 flow over Solana USDC; native SOL uses hosted payment sessions.
Native SOL hosted payment session
Create a separate one-off product configured with default_rail: "solana_sol", then create a buyer session:
session = client.pay_api.create_payment_session(
{
"external_product_id": "native-sol-api-access",
"external_customer_id": "cust_123",
"wallet": buyer_wallet,
"rail": "solana_sol",
},
idempotency_key="session-cust-123-native-sol-001",
)
print(session["payment_session"]["checkout_url"])
print(session["payment_session"]["amount_minor_units"]) # lamports
print(session["payment_session"]["asset_symbol"]) # SOL
Send the buyer to the signed, expiring checkout_url. It is bound to the exact API-created payment session and pending entitlement. Hilt reuses that session through buyer-approved settlement, receipt creation, and entitlement activation. Live native SOL settlement costs 1% of a successful payment. Hilt x402 V2 and native subscriptions remain Solana USDC-only.
from hilt_sdk import HiltClient
public_client = HiltClient()
setup = public_client.pay_api.agent_bootstrap(
{
"agent_name": "Acme API Builder",
"agent_platform": "cursor",
"requested_use_case": "Protect /ai/pro with Hilt Pay API",
"contact_email": "founder@acme.test",
"requested_permissions": ["access:read", "access:write", "access:webhooks"],
}
)
manifest = public_client.pay_api.submit_agent_setup_manifest(
setup["setup_intent_id"],
{
"setup_token": setup["setup_token"],
"manifest": {
"app": {"name": "Acme AI"},
"product": {
"external_product_id": "pro-api",
"title": "Pro API access",
"amount_minor_units": 79000000,
"default_rail": "solana_usdc",
"billing_model": "recurring",
"renewal_mode": "solana_native_subscription",
"billing_interval_days": 30,
"cancel_at_period_end": True,
"expected_monthly_payments": 120,
"expected_monthly_volume_usd": 9480,
},
"payment_protocol": "x402",
"settlement_rail": "solana_usdc",
"protected_resource": {
"url": "https://api.acme.test/ai/pro",
"method": "POST",
"customer_identity": "external_customer_id",
},
"webhook": {
"url": "https://api.acme.test/webhooks/hilt",
"subscribed_events": ["access.entitlement.activated", "payment.confirmed"],
},
},
},
)
print(manifest["pricing_recommendation"]["recommended_plan"]) # live or enterprise
print(setup["owner_approval_url"]) # send the owner here for the one-minute approval step
Check durable or time-based access
Use this for subscriptions, memberships, and other durable access where the question is whether a customer has access right now. For each billable metered request, use atomic consume_entitlement instead.
import os
from fastapi import FastAPI, Header, HTTPException
from hilt_sdk import HiltClient
app = FastAPI()
client = HiltClient(api_key=os.environ["HILT_API_KEY"])
@app.post("/ai/pro")
async def pro_ai(x_customer_id: str = Header(...)):
access = client.pay_api.check_entitlement(
{
"external_product_id": "pro-api",
"external_customer_id": x_customer_id,
}
)
if not access["has_access"]:
raise HTTPException(
status_code=402,
detail={
"error": "payment_required",
"status": access["status"],
"reason": access["reason"],
"external_product_id": access["external_product_id"],
},
)
return {"ok": True}
Merchant workspace product
from hilt_sdk import HiltClient
client = HiltClient(api_key="hk_live_...")
product = client.products.create(
{
"product_type": "PAYMENT_LINK",
"title": "30-day members lounge",
"amount_minor_units": 200000,
"token_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"merchant_wallet": "So1anaMerchantWallet1111111111111111111111111",
"delivery_type": "REDIRECT",
"delivery_value": "https://example.com/welcome",
"membership_config": {
"enabled": True,
"platform": "CUSTOM",
"identity_type": "WALLET",
"identity_required": False,
"renewal_mode": "ONE_OFF",
"billing_interval_days": 30,
"grace_period_days": 3,
},
}
)
print(product["id"], product["slug"])
Native subscription state and cancellation
subscription = client.pay_api.get_native_subscription("AUTHORIZATION_ID")
cancel_intent = client.pay_api.create_native_subscription_cancel_intent(
"AUTHORIZATION_ID",
{
"reason": "buyer_requested",
"cancel_at_period_end": True,
},
)
cancelled = client.pay_api.confirm_native_subscription_cancel(
"AUTHORIZATION_ID",
{
"cancel_tx_signature": "SOLANA_CANCEL_TRANSACTION_SIGNATURE",
"reason": "buyer_requested",
"immediate_revoke": False,
},
idempotency_key="native-cancel-AUTHORIZATION_ID-001",
)
print(subscription["status"], cancel_intent["status"], cancelled["status"])
Sandbox session helpers
sandbox = client.pay_api.create_sandbox_payment_session(
{
"external_product_id": "pro-api",
"external_customer_id": "cust_123",
"rail": "solana_usdc",
"confirm_sandbox_mode": True,
},
idempotency_key="sandbox-session-cust-123-pro-api-001",
)
confirmed = client.pay_api.confirm_sandbox_payment_session(
sandbox["payment_session"]["id"],
{"proof": "sandbox-confirmed-access"},
idempotency_key="sandbox-confirm-cust-123-pro-api-001",
)
print(confirmed["entitlement"])
Webhook verification and routing
from hilt_sdk import construct_webhook_event, create_webhook_router
router = create_webhook_router()
@router.on("payment.confirmed")
async def grant_access(event):
await sync_access(event["data"])
async def hilt_webhook(request):
raw_body = await request.body()
event = construct_webhook_event(
raw_body,
request.headers.get("X-Hilt-Signature"),
HILT_WEBHOOK_SECRET,
)
await router.dispatch(event)
return {"ok": True}
Hilt signs <timestamp>.<raw_json_body> and sends the signature as X-Hilt-Signature: t=<unix_timestamp>,v1=<hex_hmac_sha256>.
Error handling
from hilt_sdk import HiltApiError
try:
client.pay_api.create_payment_session(body, idempotency_key="session-001")
except HiltApiError as exc:
print(exc.code, exc.status_code, exc.request_id, exc.retryable, exc.docs_url)
HiltApiError includes the public error code, HTTP status, Hilt request id when available, retryability, docs URL, and safe response details.
The error catalog lives at https://docs.hilt.so/developers/errors. SDK docs_url values point to anchors such as #payment-failed, #idempotency-in-progress, and #request-timeout.
Subscription helper boundary
The SDK exposes the current public native subscription routes: read an authorization, create a cancellation intent, and confirm the signed cancellation. Public endpoints for list, pause, resume, or browser-safe customer management sessions are not exposed yet, so the SDK does not fake those methods. Build recurring access today with a recurring product, a payment session, signed webhooks, and entitlement checks.
Proposed backend contract for future high-level subscription helpers:
POST /v1/access/subscriptions
GET /v1/access/subscriptions/{subscription_id}
GET /v1/access/subscriptions
POST /v1/access/subscriptions/{subscription_id}/pause
POST /v1/access/subscriptions/{subscription_id}/resume
POST /v1/access/subscriptions/{subscription_id}/cancel
POST /v1/access/customer-sessions
POST /v1/access/sandbox/subscriptions/{subscription_id}/advance-period
The browser-facing contract should return only a short-lived customer token or hosted management URL. It must never expose a Hilt API key in browser code.
Quick start
- Create or approve a Hilt Pay API setup intent.
- Use the SDK to create an app, product, payment session, and webhook.
- Use sandbox sessions to validate object handling without live money.
- Use entitlement checks before serving paid work.
- For recurring access, create products with
billing_model: "recurring"andrenewal_mode: "solana_native_subscription".
Auth surfaces
For most merchant routes, configure either:
api_keyfor server-to-server merchant automationbearer_tokenfor dashboard-session tooling
Webhook endpoint management currently requires a dashboard session token, so the webhook resource uses the configured bearer_token.
What the SDK is best at
- products and hosted checkout
- payment confirmation and reads
- membership lookup, renewal intelligence, and recovery
- receipt proof, PDF access, and proof sending
- support tickets and webhook endpoint operations
Build from source
python setup.py sdist bdist_wheel
Metadata
Release files for hilt-sdk 1.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hilt_sdk-1.4.0.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hilt_sdk-1.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.0 kB
Release files / hilt_sdk-1.4.0.tar.gz
| Download URL | hilt_sdk-1.4.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
82afef341f6950074ff5ad74f8f3b8c5b388c667dca21bac4e4b167c4516d132
|
|
BLAKE2b-256 checksum How to use checksums |
6ee5abfb03ace5a9deeefe567f58c35bfe4069091bbd2f8bd14c59509eeba7d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|
Release files / hilt_sdk-1.4.0-py3-none-any.whl
| Download URL | hilt_sdk-1.4.0-py3-none-any.whl |
|---|---|
| Size | 16.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7bca29f60585b4ee28a21c1eed03426cee0d9e54c80c7c8e88448369479c3b5b
|
|
BLAKE2b-256 checksum How to use checksums |
2b1b18081ba6aff01f653cb30761d38689f8d077389a4abf917810e54752e33b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.16
|