Deliveries
A delivery is the digital-fulfilment counterpart to a shipment. Where a shipment hands a parcel to a courier, a delivery hands a download link (or a license) to a buyer of a type: "digital" product. Each delivery has a max download count, an expiry, and an event trail. The Python SDK wraps three endpoints behind fulkruma.deliveries. For HTTP shapes, see API → Deliveries.
Namespace
fulkruma.deliveries # DeliveriesResources
Three methods. There's no update (delivery terms are immutable after issuance) and no revoke — the closest thing to "revoke" is letting the delivery expire, or revoking the underlying license via licenses.revoke if the product is license-gated.
Methods
create
fulkruma.deliveries.create(body: dict, *, on_behalf_of: str | None = None) -> dict
Issues a delivery. Pass the product, the customer, the checkout session it came from, and optionally a download cap and expiry. The SDK auto-mints an idempotency key.
from datetime import datetime, timedelta, timezone
result = fulkruma.deliveries.create({
"productId": "prod_01HX...",
"customerId": "cus_01HX...",
"checkoutSessionId": "cs_01HX...",
"maxDownloads": 5,
"expiresAt": (datetime.now(timezone.utc) + timedelta(days=30)).isoformat(),
"externalSource": "storlaunch",
"externalRef": "order-118-dl-1",
})
print(result["delivery"]["id"], result["delivery"].get("downloadUrl"))
maxDownloads defaults to whatever the product configures (or unlimited if neither sets one). expiresAt defaults to 30 days.
The
downloadUrlis signed and short-lived. It carries an embedded HMAC and expires after a few minutes. Email it to the buyer directly; don't cache it in your own system. Re-fetching viadeliveries.getreturns a freshly-signed URL each time.
get
fulkruma.deliveries.get(delivery_id: str, *, on_behalf_of: str | None = None) -> dict
Fetches one delivery by del_* ID. Returns a fresh signed downloadUrl and the latest download-count metrics.
result = fulkruma.deliveries.get("del_01HX...")
d = result["delivery"]
print(f"{d['downloadCount']}/{d.get('maxDownloads') or '∞'} downloads used")
list
fulkruma.deliveries.list(*, on_behalf_of: str | None = None) -> dict
Returns every delivery in the workspace, freshest first. Not paginated.
result = fulkruma.deliveries.list()
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
expired = [
d for d in result["deliveries"]
if d.get("expiresAt") and datetime.fromisoformat(d["expiresAt"]) < now
]
Types
Each method returns a plain dict. Key shape:
{
"delivery": {
"id": "del_...",
"accountId": "acc_...",
"productId": "prod_...",
"customerId": "cus_...",
"checkoutSessionId": "cs_...",
"status": "pending" | "ready" | "delivered" | "expired",
"downloadUrl": "https://..." | None,
"downloadCount": int,
"maxDownloads": int | None,
"expiresAt": "..." | None,
"externalSource": "..." | None,
"externalRef": "..." | None,
"createdAt": "...",
"updatedAt": "..."
}
}
Common patterns
Issue on plugipay.checkout.completed webhook. The canonical flow:
def on_checkout_completed(fulkruma, session: dict):
pres = fulkruma.products.get(session["productId"])
product = pres["product"]
if product["type"] != "digital":
return
result = fulkruma.deliveries.create({
"productId": product["id"],
"customerId": session["customerId"],
"checkoutSessionId": session["id"],
})
send_download_email(session["customerId"], result["delivery"]["downloadUrl"])
If the product is licenseEnabled, issue a license too (see licenses.issue) and email both.
Re-send a download link. Buyer lost the email; want to resend:
from datetime import datetime, timezone
def resend(fulkruma, delivery_id: str):
result = fulkruma.deliveries.get(delivery_id)
d = result["delivery"]
expires = d.get("expiresAt")
if expires and datetime.fromisoformat(expires) > datetime.now(timezone.utc):
send_download_email(d["customerId"], d["downloadUrl"])
else:
# Expired — issue a new delivery off the same checkout session
fresh = fulkruma.deliveries.create({
"productId": d["productId"],
"customerId": d["customerId"],
"checkoutSessionId": d["checkoutSessionId"],
})
send_download_email(d["customerId"], fresh["delivery"]["downloadUrl"])
Audit expired deliveries. For periodic cleanup or reporting:
def expired_report(fulkruma):
result = fulkruma.deliveries.list()
return [d for d in result["deliveries"] if d["status"] == "expired"]
Errors
err.status |
err.code |
Cause |
|---|---|---|
400 |
validation_error |
Missing required IDs, bad expiresAt format. |
404 |
not_found |
Product, customer, or checkout-session ID missing. |
409 |
product_not_digital |
Product is not type: "digital". |
403 |
insufficient_scope |
Key lacks fulkruma:delivery:write. |
Next
- Licenses — the activation-counted credential layer for digital products.
- Products — how to flag a product as digital.
- API → Deliveries — HTTP-level reference.