{"name":"l402.directory","description":"Machine-readable, health-checked registry of L402 Lightning-gated APIs.","version":"1.3.0","listing_price_sats":1000,"listing_model":"pay-once-forever","protocol":"L402","l402_protocol":{"description":"L402 is a protocol for Lightning-gated API access. Any endpoint returning HTTP 402 with a WWW-Authenticate header can be accessed by paying the Lightning invoice and re-requesting with the token.","flow":["1. Request the protected resource.","2. Server returns 402 with header: WWW-Authenticate: L402 macaroon=\"<base64>\", invoice=\"<bolt11>\"","3. Decode the invoice to verify amount and description.","4. Pay the invoice. Your wallet returns a preimage (hex).","5. Re-request with header: Authorization: L402 <macaroon>:<preimage_hex>","6. Server returns the resource.","7. Deliver the resource to the user. Check the endpoint's consumption field in the service listing for delivery instructions (e.g., player_url template, browser opening)."],"header_format":{"challenge":"WWW-Authenticate: L402 macaroon=\"<base64>\", invoice=\"<bolt11>\"","token":"Authorization: L402 <macaroon_base64>:<preimage_hex>"},"notes":"The macaroon is the base64 string from the challenge header. The preimage is the 64-char hex string your wallet returns after payment. Concatenate with a colon, no spaces.","consumption":{"description":"After obtaining a resource, check the service listing's endpoint consumption field for delivery instructions.","types":{"browser":"Construct a URL from player_url template and open in user's browser","display":"Show the response content directly to the user","download":"Save the response to a file","stream":"The response is a media stream requiring a player application","api_response":"The raw response data is the final result — present it to the user"},"note":"If no consumption field exists, the endpoint returns data that can be displayed directly (api_response is the default)."}},"endpoints":{"services":{"url":"/api/services","method":"GET","description":"Browse L402 service listings. Default returns only live and degraded services. Each service includes endpoints with URLs, pricing, and descriptions.","params":{"q":"Search by keyword across name, description, and categories (e.g. ?q=video)","category":"Filter by category (e.g. video, ai, data)","status":"Filter by status: live, degraded, offline, new. Use \"all\" to include everything.","format":"Use \"minimal\" for compact output (id, name, description, status, categories, endpoint URLs)"},"auth":"none"},"service_detail":{"url":"/api/services/{service_id}","method":"GET","description":"Full details for a single service including L402 probe data, payment verification, and 24h uptime.","auth":"none"},"schema":{"url":"/api/schema","method":"GET","description":"JSON schema for valid submissions. Read this before building a listing.","auth":"none"},"submit":{"url":"/api/submit","method":"POST","description":"Submit a new L402 service listing. Pay once, listed forever.","auth":"L402","price_sats":1000,"flow":["POST your listing JSON to /api/submit. Server validates and returns 402 with a Lightning invoice.","Pay the Lightning invoice. Save the payment preimage.","Re-POST the same JSON with header: Authorization: L402 <macaroon>:<preimage_hex>","The macaroon is from the WWW-Authenticate header. The preimage is from your wallet after paying.","On success, you receive a service_id and your management_key (the preimage). Save the management_key — it is your only way to update the listing."]},"update":{"url":"/api/services/{service_id}","method":"PUT","description":"Update mutable fields (description, contact, docs_url, categories, endpoints).","auth":"Bearer {management_key}"},"status":{"url":"/api/services/{service_id}/status","method":"GET","description":"Public health status. No auth required.","auth":"none"},"report":{"url":"/api/report/{service_id}","method":"GET","description":"Detailed health report — uptime percentages, L402 probe history, response times, and incident log. History accumulates over time.","auth":"L402","price_sats":10,"token_expiry_seconds":600},"health":{"url":"/api/health","method":"GET","description":"Directory health: total services, live count, pricing tiers.","auth":"none"},"claim":{"url":"/api/claim/{service_id}","method":"POST","description":"Initiate a domain claim for a discovered listing. Returns a challenge hash that must be placed at /.well-known/l402-directory-verify.txt on the service domain.","auth":"none","flow":["POST /api/claim/{service_id} to get a challenge_hash and verification_url.","Place the challenge_hash (plain text) at the verification_url on your domain: https://{domain}/.well-known/l402-directory-verify.txt","POST /api/claim/{service_id}/verify to complete verification.","On success, you receive a management_key. Save it — this is your only way to update the listing."],"notes":"Only discovered (unclaimed) listings can be claimed. Challenges expire after 24 hours."},"claim_verify":{"url":"/api/claim/{service_id}/verify","method":"POST","description":"Complete a domain claim by verifying the .well-known file. The directory fetches your verification URL and confirms the challenge hash matches.","auth":"none"}},"example_listing":{"description":"Example listing submission with consumption field. POST this to /api/submit.","body":{"name":"My L402 Service","description":"A brief description of what the service does.","endpoints":[{"url":"https://example.com/api/resource/{id}","method":"GET","description":"Fetch a resource by ID. Returns 402 with Lightning invoice.","pricing":{"amount":10,"currency":"sats","model":"per-request"},"content_type":"application/json","consumption":{"type":"api_response","action":"Display the JSON response to the user."}},{"url":"https://example.com/api/stream/{id}","method":"GET","description":"Stream media content.","pricing":{"amount":5,"currency":"sats","model":"per-request"},"content_type":"application/vnd.apple.mpegurl","consumption":{"type":"browser","action":"URL-encode the L402 token and open the player URL in the user's browser.","player_url":"https://example.com/player?id={id}&token={token}","token_delivery":"query_param","token_encoding":"URL-encode the full macaroon:preimage string as the {token} parameter"}}],"health_url":"https://example.com/api/health","categories":["data","streaming"]}},"getting_started":{"need_a_channel":{"description":"New Lightning node with no channels? Get a free recommendation for your first channel partner based on live graph data.","url":"https://l402.services/ln/suggest/first-channel?budget=50000&use_case=agent","method":"GET","auth":"none"},"browse_services":{"description":"Browse live L402 services. Use ?q=keyword to search, ?category=video to filter, or ?status=all to include offline/new services.","url":"/api/services","method":"GET","auth":"none"},"try_an_api":{"description":"Try an L402-gated API. Request the endpoint, receive a 402 with a Lightning invoice, pay it, re-request with the token.","example":"GET https://l402.services/geoip/8.8.8.8"}},"agent_quickstart":"To find L402 services: GET /api/services (returns live services) or GET /api/services?q=keyword to search. Each service has an endpoints[] array — use endpoints[N].url directly as the API path (do not parse descriptions for URLs). To consume a service: follow the l402_protocol flow (steps 1-7). Check each endpoint's consumption field for delivery instructions. To list your own: GET /api/schema, then POST /api/submit. To claim a discovered listing: POST /api/claim/{service_id}, place the challenge at the .well-known URL, then POST /api/claim/{service_id}/verify."}