Example: Claude Code

This walkthrough shows a complete Claude Code session where the user asks the agent to sell a file. The agent handles account setup, listing creation, and readiness resolution autonomously — asking the user only when human action is required.


The scenario

The user has an ebook PDF in their S3 bucket and wants to sell it for $19. They have not set up a ListBee account yet. They do have a Stripe account.


Step 1: Check for an existing API key

The agent checks the environment for a ListBee API key before doing anything else.

1import os
2import httpx
3
4BASE = "https://api.listbee.so"
5
6api_key = os.environ.get("LISTBEE_API_KEY")
7
8if api_key:
9 # Verify the key is valid
10 resp = httpx.get(
11 f"{BASE}/v1/account",
12 headers={"Authorization": f"Bearer {api_key}"},
13 )
14 if resp.status_code == 200:
15 print("API key found and valid.")
16 account = resp.json()
17 else:
18 print("API key found but invalid. Will create a new account.")
19 api_key = None
20else:
21 print("No LISTBEE_API_KEY found. Starting account setup.")

Agent says to user:

I don’t see a ListBee API key in your environment. I’ll create an account for you. What’s your email address?

User says:

alex@example.com


Step 2: Create the account

1# Request OTP
2httpx.post(
3 f"{BASE}/v1/account/signup",
4 json={"email": "alex@example.com"},
5)

Agent says:

Check your inbox for a 6-digit code from ListBee. What is it?

User says:

847213

1# Verify and get API key
2resp = httpx.post(
3 f"{BASE}/v1/account/verify",
4 json={"email": "alex@example.com", "code": "847213"},
5)
6data = resp.json()
7
8api_key = data["api_key"] # lb_...
9account = data["account"]
10
11# Persist the key for future sessions
12print(f"Add this to your environment:\nexport LISTBEE_API_KEY={api_key}")

Agent says:

Account created. Add this to your .env file so I can find it next time:

LISTBEE_API_KEY=lb_live_...

Step 3: Check readiness and handle Stripe

1headers = {"Authorization": f"Bearer {api_key}"}
2
3readiness = account["readiness"]
4print(readiness["operational"]) # False — Stripe not connected
5print(readiness["next"]) # "set_stripe_key"
6
7action = next(a for a in readiness["actions"] if a["code"] == readiness["next"])
8print(action["kind"]) # "api"
9print(action["message"]) # "Submit your Stripe secret key to enable payments."

The next action is kind: "api" — the agent can handle it without a browser.

Agent says:

To accept payments, I need your Stripe secret key. You can find it at https://dashboard.stripe.com/apikeys. It starts with sk_live_ or sk_test_.

User says:

sk_live_51Abc123…

1# Submit Stripe key
2resp = httpx.post(
3 f"{BASE}/v1/account/stripe-key",
4 headers=headers,
5 json={"secret_key": "sk_live_51Abc123..."},
6)
7account = resp.json()
8print(account["readiness"]["operational"]) # True

Agent says:

Stripe connected. Your account is ready to accept payments.


Step 4: Create the listing

1import uuid
2
3resp = httpx.post(
4 f"{BASE}/v1/listings",
5 headers={**headers, "Idempotency-Key": str(uuid.uuid4())},
6 json={
7 "name": "Python Async Patterns",
8 "price": 1900, # $19.00
9 "deliverable": "https://alex-bucket.s3.amazonaws.com/python-async.pdf",
10 },
11)
12listing = resp.json()
13
14print(listing["url"]) # https://buy.listbee.so/r7kq2xy9
15print(listing["readiness"]["sellable"]) # True

Step 5: Check listing readiness

1if listing["readiness"]["sellable"]:
2 print(f"Listing is live: {listing['url']}")
3else:
4 # Handle any remaining blockers
5 next_code = listing["readiness"]["next"]
6 action = next(
7 a for a in listing["readiness"]["actions"]
8 if a["code"] == next_code
9 )
10 if action["kind"] == "api":
11 httpx.request(
12 action["resolve"]["method"],
13 f"{BASE}{action['resolve']['endpoint']}",
14 headers=headers,
15 json=action["resolve"]["params"],
16 )
17 else:
18 print(f"Action required: {action['message']}")
19 print(f"Visit: {action['resolve']['url']}")

Agent says to user:

Your ebook is live. Share this URL with buyers:

https://buy.listbee.so/r7kq2xy9

When someone pays $19, they receive the PDF by email automatically.


Full script

1import os
2import uuid
3import httpx
4
5BASE = "https://api.listbee.so"
6
7
8def get_or_create_account() -> tuple[str, dict]:
9 """Return (api_key, account) — create account if no key in env."""
10 api_key = os.environ.get("LISTBEE_API_KEY")
11
12 if api_key:
13 resp = httpx.get(f"{BASE}/v1/account", headers={"Authorization": f"Bearer {api_key}"})
14 if resp.is_success:
15 return api_key, resp.json()
16
17 email = input("ListBee email: ").strip()
18 httpx.post(f"{BASE}/v1/account/signup", json={"email": email})
19
20 code = input("Verification code from inbox: ").strip()
21 data = httpx.post(
22 f"{BASE}/v1/account/verify",
23 json={"email": email, "code": code},
24 ).json()
25
26 api_key = data["api_key"]
27 print(f"\nSave this: export LISTBEE_API_KEY={api_key}\n")
28 return api_key, data["account"]
29
30
31def ensure_stripe(api_key: str, account: dict) -> None:
32 """Submit Stripe key if not connected."""
33 if account["readiness"]["operational"]:
34 return
35
36 headers = {"Authorization": f"Bearer {api_key}"}
37 next_code = account["readiness"]["next"]
38
39 if next_code == "set_stripe_key":
40 stripe_key = input("Stripe secret key (sk_live_...): ").strip()
41 httpx.post(
42 f"{BASE}/v1/account/stripe-key",
43 headers=headers,
44 json={"secret_key": stripe_key},
45 )
46 elif next_code == "connect_stripe":
47 url = httpx.post(f"{BASE}/v1/account/stripe/connect", headers=headers).json()["url"]
48 print(f"Connect Stripe: {url}")
49 input("Press Enter when done...")
50
51
52def create_listing(api_key: str, name: str, price_cents: int, content_url: str) -> dict:
53 """Create listing and return response."""
54 return httpx.post(
55 f"{BASE}/v1/listings",
56 headers={
57 "Authorization": f"Bearer {api_key}",
58 "Idempotency-Key": str(uuid.uuid4()),
59 },
60 json={
61 "name": name,
62 "price": price_cents,
63 "deliverable": content_url,
64 },
65 ).json()
66
67
68# Main
69api_key, account = get_or_create_account()
70ensure_stripe(api_key, account)
71
72listing = create_listing(
73 api_key,
74 name="Python Async Patterns",
75 price_cents=1900,
76 content_url="https://alex-bucket.s3.amazonaws.com/python-async.pdf",
77)
78
79if listing["readiness"]["sellable"]:
80 print(f"\nListing live: {listing['url']}")
81else:
82 print(f"\nNot yet sellable. Next action: {listing['readiness']['next']}")

Next steps


Copy for AI assistants

Cursor / Claude Code
1# ListBee — Claude Code usage pattern
2#
3# Goal: sell a digital file for a user in one session
4#
5# 1. Check LISTBEE_API_KEY in environment
6# GET /v1/account → verify key is valid
7# If missing/invalid: run signup + verify flow (see authentication docs)
8#
9# 2. Check account readiness
10# account.readiness.operational: false → Stripe not connected
11# next == "set_stripe_key" (kind: api) → ask user for sk_live_... → POST /v1/account/stripe-key
12# next == "connect_stripe" (kind: human) → POST /v1/account/stripe/connect → send URL to user
13#
14# 3. Create listing with idempotency key
15# POST /v1/listings { name, price (cents), deliverable (URL or text) }
16# Header: Idempotency-Key: <uuid>
17# → listing.url (share with buyers)
18# → listing.readiness.sellable: true when buyers can purchase
19#
20# 4. If sellable: false, read readiness.next + actions, resolve or surface to user
21#
22# Auth: Authorization: Bearer lb_...
23# Errors: RFC 9457 { type, title, status, detail, code, param }
24# Docs: https://docs.listbee.so
25# Spec: https://api.listbee.so/openapi.json