Fulfillment

How ListBee delivers content to buyers after payment

Fulfillment is what happens after a buyer pays. The behavior is determined by the listing’s content_type, set at creation and locked on publish. There are three modes: ListBee delivers pre-attached content automatically (static), your agent pushes generated content (generated), or your external system takes over entirely (webhook).

How it works

When Stripe confirms payment, ListBee inspects the order’s content_type and takes the appropriate action:

  • static — ListBee immediately creates an access grant from the listing’s pre-attached deliverables, emails the buyer a download link, and marks the order fulfilled. No action required from you.
  • generated — the order transitions to processing and ListBee fires order.paid. Your agent receives the event, generates the content, then calls POST /v1/orders/{id}/fulfill to push it. ListBee delivers it and marks the order fulfilled.
  • webhook — ListBee fires order.paid and marks the order handed_off. Your system is fully responsible for delivery. ListBee does not deliver anything.

order.fulfilled fires for static and generated orders. order.paid fires for all three.

Choosing a content type

staticgeneratedwebhook
Who deliversListBeeListBee (after agent pushes)Your system
Deliverables on listingRequiredNot allowedNot allowed
Webhook requiredNoYes (order.paid)Yes (order.paid)
Order terminal statefulfilledfulfilledhanded_off
Use whenFixed files, URLs, textAI-generated content, per-order reportsPhysical goods, services, SaaS access

Static delivery

Attach up to 3 deliverables to the listing before publishing. On payment, ListBee delivers them automatically.

1from listbee import ListBee
2
3client = ListBee(api_key="lb_...")
4
5# 1. Create a static listing
6listing = client.listings.create(
7 name="Python Crash Course",
8 price=2900,
9 content_type="static",
10)
11
12# 2. Attach content (file, url, or text — up to 3)
13client.listings.set_deliverables(
14 listing_id=listing.id,
15 deliverables=[
16 {"type": "url", "value": "https://cdn.example.com/python-course.pdf"},
17 ],
18)
19
20# 3. Publish — buyers can now pay and receive the PDF automatically
21client.listings.publish(listing_id=listing.id)

Generated delivery

Your agent generates content per order in response to order.paid, then calls fulfill to push it back.

1# 1. Create a generated listing (no deliverables needed)
2listing = client.listings.create(
3 name="Personalized Investment Report",
4 price=4900,
5 content_type="generated",
6)
7
8# Publish (requires an active order.paid webhook first — see readiness)
9client.listings.publish(listing_id=listing.id)
10
11# 2. In your webhook handler — called when order.paid fires:
12def handle_order_paid(order_id: str, checkout_data: dict):
13 # Generate content for this buyer
14 report = generate_report(checkout_data)
15
16 # Push it to ListBee — buyer receives email with download link
17 client.orders.fulfill(
18 order_id=order_id,
19 deliverables=[
20 {"type": "text", "value": report},
21 ],
22 )

Webhook (external) delivery

ListBee fires order.paid and hands off. Your system handles all delivery.

1# 1. Create a webhook listing
2listing = client.listings.create(
3 name="Premium Membership",
4 price=9900,
5 content_type="webhook",
6)
7
8client.listings.publish(listing_id=listing.id)
9
10# 2. Your endpoint receives order.paid and handles delivery:
11# - Provision membership access
12# - Send welcome email
13# - Any delivery mechanism you control

Deliverable types

A deliverable is what the buyer receives after payment. Each has a type and either a token (for files) or a value (for URLs and text). Up to 3 deliverables per listing or per fulfill call. Mixed types allowed.

TypeFieldWhat the buyer getsLimits
filetoken from POST /v1/filesSigned download URL100 MB max, 48h expiry, 10 downloads
urlvalue — any URLRedirect to that URLNo size limit
textvalue — literal stringText rendered on download page10,000 chars

File deliverable

Upload first, then reference the token. Two steps:

1# Step 1: Upload the file
2file = client.files.upload(open("ebook.pdf", "rb"))
3print(file.id) # file_7kQ2xY9mN3pR5tW1vB8a01
4
5# Step 2: Attach to listing
6client.listings.set_deliverables(
7 listing_id="lst_abc123",
8 deliverables=[{"type": "file", "token": file.id}],
9)

After payment, the buyer gets an access grant with a signed download URL. The grant expires after 48 hours or 10 downloads, whichever comes first.

URL deliverable

Direct redirect — the buyer clicks the download link and is sent to your URL. No file hosting needed.

1{"type": "url", "value": "https://cdn.example.com/guide.pdf"}

Use this for content already hosted elsewhere (S3, Google Drive shared links, Notion pages, Gumroad-style external downloads).

Text deliverable

Literal text rendered on the download page. Good for license keys, passwords, short instructions, or generated content.

1{"type": "text", "value": "Your license key: ABC-123-XYZ\n\nActivate at https://example.com/activate"}

Mixing types

A single listing can combine all three:

1{
2 "deliverables": [
3 {"type": "file", "token": "file_7kQ2xY9mN3pR5tW1vB8a01"},
4 {"type": "url", "value": "https://community.example.com/invite/abc"},
5 {"type": "text", "value": "Welcome! Your login: user@example.com / temp-pass-123"}
6 ]
7}

The buyer sees all three on their download page after payment.

  • Listings — setting content type and attaching deliverables
  • Orders — order status lifecycle per content type
  • Webhooks — receiving order.paid to trigger fulfillment
  • Readiness — pre-publish checks for generated and webhook listings