{"openapi":"3.1.0","info":{"title":"Los Fomos API","description":"Community-curated place recommendations and paid occasion bundles from Los Fomos.","version":"1.2.0"},"servers":[{"url":"https://www.losfomos.xyz"}],"paths":{"/api/bundles":{"get":{"operationId":"listBundles","summary":"List all occasion bundles","description":"Returns preview metadata for all available occasion bundles. No item details — call getBundlePreview or getBundleFull to get place data.","tags":["Bundles"],"responses":{"200":{"description":"Array of bundle previews","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BundlePreview"}}}}},"500":{"description":"Server error"}}}},"/api/bundles/{slug}":{"get":{"operationId":"getBundlePreview","summary":"Get bundle preview","description":"Returns preview fields for a single bundle plus an unlock_url pointing to the full endpoint. No place names or insider notes.","tags":["Bundles"],"parameters":[{"name":"slug","in":"path","required":true,"description":"Bundle slug (e.g. nyc-date-night)","schema":{"type":"string","example":"nyc-date-night"}}],"responses":{"200":{"description":"Bundle preview with unlock_url","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BundlePreview"},{"type":"object","properties":{"unlock_url":{"type":"string","example":"/api/bundles/nyc-date-night/full"}}}]}}}},"404":{"description":"Bundle not found"},"500":{"description":"Server error"}}}},"/api/bundles/{slug}/full":{"get":{"operationId":"getBundleFull","summary":"Get full bundle content (paid — USDC on Base Sepolia)","description":"Returns the full bundle with resolved place data, arrival hints, and insider notes.\n\n**Payment flow (agent-native, no SDK required):**\n\n1. Call this endpoint. If no payment header is present, you will receive a `402 Payment Required` response with a machine-readable body describing exactly what to send and where.\n2. Send a USDC `transfer(address to, uint256 amount)` call on Base Sepolia to the `recipient` address in the 402 body. The `amount` is given in `amount_atomic` (500000 = 0.5 USDC, 6 decimals).\n3. Retry this endpoint with the header `X-PAYMENT: <tx_hash>`. The server will verify the transfer on-chain and return the full bundle.\n\nAny wallet works — no custodial SDK, no account creation. Each transaction hash unlocks one request (replay-protected).","tags":["Bundles"],"parameters":[{"name":"slug","in":"path","required":true,"description":"Bundle slug","schema":{"type":"string","example":"nyc-date-night"}},{"name":"X-PAYMENT","in":"header","required":false,"description":"On-chain transaction hash of a USDC transfer to the treasury address. Obtain the exact recipient and amount from the 402 response body.","schema":{"type":"string","example":"0xabc123...def456"}}],"responses":{"200":{"description":"Full bundle with resolved places","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BundleFull"}}}},"402":{"description":"Payment required. Body is machine-readable and contains everything needed to complete payment and retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired402"},"example":{"error":"payment_required","price_usd_cents":50,"network":"base-sepolia","asset":"USDC","usdc_contract":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","recipient":"0xYourTreasuryAddressHere","amount_atomic":"500000","instructions":"Send a USDC transfer of amount_atomic to recipient on network. Then retry this request with X-PAYMENT: <tx_hash>","bundle_preview":{"slug":"nyc-date-night","title":"NYC Date Night","city":"New York","occasion":"date-night","curator_fname":"pauline-unik","price_usd_cents":50,"description":"...","preview_summary":"...","item_count":5}}}}},"404":{"description":"Bundle not found"},"500":{"description":"Server error"}}}},"/api/places":{"get":{"operationId":"getPlaces","summary":"Get approved place recommendations","description":"Returns Los Fomos community-curated place recommendations. Optionally filter by city. Places include a name, description, link, and the username of the community member who submitted it.","tags":["Places"],"parameters":[{"name":"city","in":"query","required":false,"description":"Filter by city name (case-insensitive). Available cities include New York, Paris, London, Los Angeles, and Rome.","schema":{"type":"string"}}],"responses":{"200":{"description":"List of approved places","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"city":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"link":{"type":"string","nullable":true},"fname":{"type":"string","nullable":true,"description":"Username of the Los Fomos community member who submitted this place"},"createdAt":{"type":"string","format":"date-time"},"ai_description":{"type":"string","nullable":true,"description":"Enriched description sourced from the place's public website metadata (og:description, JSON-LD). Reviewed by the Los Fomos team before publication. Only present when enrichment_status is 'approved'."},"tags":{"type":"array","items":{"type":"string"},"description":"Derived from JSON-LD @type, servesCuisine, og:type, and URL path. Only present when enrichment_status is 'approved'."},"price_range":{"type":"string","nullable":true,"description":"Price indicator (e.g. '$', '$$', '$$$') from JSON-LD priceRange or text patterns. Only present when enrichment_status is 'approved'."},"neighborhood":{"type":"string","nullable":true,"description":"Neighborhood or locality from JSON-LD address. Only present when enrichment_status is 'approved'."}}}}}}},"500":{"description":"Server error"}}}}},"components":{"schemas":{"BundlePreview":{"type":"object","properties":{"slug":{"type":"string","example":"nyc-date-night"},"title":{"type":"string","example":"NYC Date Night"},"city":{"type":"string","example":"New York"},"occasion":{"type":"string","example":"date-night"},"curator_fname":{"type":"string","example":"pauline-unik"},"price_usd_cents":{"type":"integer","example":50},"description":{"type":"string"},"preview_summary":{"type":"string"},"item_count":{"type":"integer","example":5}}},"BundleFull":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"city":{"type":"string"},"occasion":{"type":"string"},"curator_fname":{"type":"string"},"price_usd_cents":{"type":"integer"},"currency":{"type":"string","example":"USD"},"description":{"type":"string"},"preview_summary":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"position":{"type":"integer"},"name":{"type":"string"},"link":{"type":"string","nullable":true},"ai_description":{"type":"string","nullable":true},"tags":{"type":"array","items":{"type":"string"}},"vibe":{"type":"string","nullable":true},"price_range":{"type":"string","nullable":true},"neighborhood":{"type":"string","nullable":true},"arrival_hint":{"type":"string"},"insider_note":{"type":"string"}}}}}},"PaymentRequired402":{"type":"object","required":["error","price_usd_cents","network","asset","usdc_contract","recipient","amount_atomic","instructions","bundle_preview"],"properties":{"error":{"type":"string","enum":["payment_required","payment_invalid"],"example":"payment_required"},"reason":{"type":"string","description":"Present when error=payment_invalid. Values: tx_not_found, tx_failed_or_pending, no_matching_usdc_transfer, tx_already_used, unsupported_network.","example":"tx_not_found"},"price_usd_cents":{"type":"integer","example":50},"network":{"type":"string","example":"base-sepolia","description":"Chain to send payment on. 'base' in production."},"asset":{"type":"string","example":"USDC"},"usdc_contract":{"type":"string","example":"0x036CbD53842c5426634e7929541eC2318f3dCF7e","description":"USDC contract address on the specified network."},"recipient":{"type":"string","example":"0xYourTreasuryAddress","description":"Treasury wallet to send USDC to."},"amount_atomic":{"type":"string","example":"500000","description":"Amount in USDC atomic units (6 decimals). 500000 = 0.5 USDC."},"instructions":{"type":"string","example":"Send a USDC transfer of amount_atomic to recipient on network. Then retry this request with X-PAYMENT: <tx_hash>"},"bundle_preview":{"$ref":"#/components/schemas/BundlePreview"}}}}}}