{"openapi":"3.1.0","info":{"title":"Landfall","version":"1.0","description":"Website intelligence for AI agents, paid per call with x402. Three paid tools: a landing page audit for paid ads (readiness score, verdict, tags with IDs, conversion paths, top 5 fixes), business contact details from a website (phones, emails, address, hours, socials, company and VAT numbers), and a tracking check (ad pixels, analytics, tag managers, consent, site platform). Deterministic, evidence-based, typical response 1-3 seconds, never charged if a call fails.","contact":{"name":"Landfall","url":"https://landfall-production-74ad.up.railway.app"}},"servers":[{"url":"https://landfall-production-74ad.up.railway.app"}],"paths":{"/v1/audit":{"get":{"operationId":"auditLandingPage","summary":"Full ad-readiness audit of one landing page (paid via x402)","description":"Costs 0.05 USDC per completed audit. Without a PAYMENT-SIGNATURE header the response is 402 with a PAYMENT-REQUIRED header.","x-payment-info":{"price_usd":0.05,"prices_usd":{"/v1/audit":0.05,"/v1/business":0.02,"/v1/tracking":0.01},"currency":"USDC","network":"eip155:8453","network_name":"Base mainnet","pay_to":"0xccff8b62b1738d65052d0780ed4665fb48d18cd0","protocol":"x402","x402_version":2,"scheme":"exact","charged_only_on_success":true},"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string"},"description":"Public http(s) URL of the landing page.","example":"https://example.com/landing"},{"name":"keyword","in":"query","required":false,"schema":{"type":"string","maxLength":120},"description":"Ad keyword or headline to check the page against."}],"responses":{"200":{"description":"Audit report","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditReport"},"example":{"sample":true,"note":"Example output for a fictional page. Real audits have the same shape.","schema_version":"1.0","url":"https://sample-plumbing.example/emergency-plumber-leeds","final_url":"https://sample-plumbing.example/emergency-plumber-leeds","fetched_at":"2026-01-01T00:00:00.000Z","http":{"status":200,"redirects":0,"redirect_chain":[],"time_to_first_byte_ms":840,"html_download_ms":1120,"html_bytes":1359,"compression":null},"verdict":"not_ready","summary":"Not ready: 56/100. Blocking issue(s): ad_platform_tag, mobile_viewport. Paid traffic here is unlikely to convert or be measured.","score":{"overall":56,"grade":"D","by_category":{"conversion":81,"tracking":38,"trust":57,"mobile":50,"speed":40}},"blockers":["ad_platform_tag","mobile_viewport"],"top_fixes":[{"priority":1,"check_id":"ad_platform_tag","severity":"critical","category":"tracking","fix":"Install the pixel/tag for each platform you will advertise on before spending. Without it the platform cannot optimise for leads or report results.","evidence":"No Meta Pixel, Google Ads tag or TikTok Pixel found, and no tag manager to load them"},{"priority":2,"check_id":"mobile_viewport","severity":"critical","category":"mobile","fix":"Add <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">. Most paid social traffic is on phones.","evidence":"No viewport meta tag found"},{"priority":3,"check_id":"click_to_call","severity":"medium","category":"conversion","fix":"Wrap the phone number in a tel: link so mobile visitors can call with one tap.","evidence":"Phone number \"0113 496 0000\" is plain text, not a tel: link"},{"priority":4,"check_id":"social_proof","severity":"high","category":"trust","fix":"Show real reviews near the call to action, ideally from a third-party source visitors can check (Google, Trustpilot, Checkatrade).","evidence":"Review/testimonial wording found, but no verifiable review source or rating markup"},{"priority":5,"check_id":"server_response","severity":"high","category":"speed","fix":"Cut server response time below 600 ms: enable page caching, use a CDN, or move to faster hosting.","evidence":"First byte after 840 ms (single measurement from the audit server)"}],"ad_platform_readiness":{"meta":{"status":"not_detected","ids":[]},"google_ads":{"status":"not_detected","ids":[]},"tiktok":{"status":"not_detected","ids":[]},"google_analytics_4":{"status":"detected","ids":["G-SAMPLE1234"]},"tag_manager":{"status":"not_detected","ids":[],"managers":[]},"other_tags":[],"conversion_events_in_page":[],"consent":{"tools":[],"google_consent_mode":false}},"conversion_paths":{"lead_forms":1,"email_capture_forms":0,"shortest_lead_form_fields":8,"longest_lead_form_fields":8,"click_to_call":false,"phone_numbers":[],"phone_in_text_not_clickable":"0113 496 0000","whatsapp_link":false,"sms_link":false,"email_links":0,"booking_tools":[],"chat_tools":[],"cta_texts":["Get a free quote","Request a callback"],"ecommerce":false},"page":{"title":"Emergency Plumber in Leeds | Sample Plumbing Co","headline":"Emergency Plumber in Leeds","meta_description":"24/7 emergency plumber covering Leeds. Fixed prices, no call-out fee. Get a free quote in 60 seconds.","word_count":44,"client_rendered_suspected":false},"checks":[{"id":"conversion_path","category":"conversion","status":"pass","severity":"critical","title":"Visitor has a way to convert","evidence":"Found: lead form","fix":null},{"id":"cta_clarity","category":"conversion","status":"pass","severity":"high","title":"Clear call-to-action wording","evidence":"Calls to action: \"Get a free quote\", \"Request a callback\"","fix":null},{"id":"form_length","category":"conversion","status":"warn","severity":"medium","title":"Lead form is short","evidence":"Shortest lead form has 8 visible fields","fix":"Cut the form to the fields needed for a first reply (name, contact, one question). Each extra field lowers completion."},{"id":"click_to_call","category":"conversion","status":"fail","severity":"medium","title":"Phone number is tappable on mobile","evidence":"Phone number \"0113 496 0000\" is plain text, not a tel: link","fix":"Wrap the phone number in a tel: link so mobile visitors can call with one tap."},{"id":"headline","category":"conversion","status":"pass","severity":"medium","title":"One clear main headline","evidence":"Headline: \"Emergency Plumber in Leeds\"","fix":null},{"id":"message_match","category":"conversion","status":"pass","severity":"high","title":"Page matches the ad keyword","evidence":"3 of 3 keyword terms appear in the title/headline; 3 of 3 appear anywhere on the page","fix":null},{"id":"ad_platform_tag","category":"tracking","status":"fail","severity":"critical","title":"An ad platform tag is installed","evidence":"No Meta Pixel, Google Ads tag or TikTok Pixel found, and no tag manager to load them","fix":"Install the pixel/tag for each platform you will advertise on before spending. Without it the platform cannot optimise for leads or report results."},{"id":"analytics","category":"tracking","status":"pass","severity":"medium","title":"Analytics is installed","evidence":"Google Analytics 4 found (G-SAMPLE1234)","fix":null},{"id":"consent","category":"tracking","status":"warn","severity":"medium","title":"Cookie consent is handled","evidence":"Tracking tags are present but no known consent tool or Google Consent Mode call was found","fix":"For UK/EU visitors, add a consent banner and connect it to Google Consent Mode; Google Ads restricts measurement and remarketing for those visitors without it."},{"id":"https","category":"trust","status":"pass","severity":"critical","title":"Page is served over HTTPS","evidence":"Final URL uses HTTPS","fix":null},{"id":"social_proof","category":"trust","status":"warn","severity":"high","title":"Reviews or testimonials are shown","evidence":"Review/testimonial wording found, but no verifiable review source or rating markup","fix":"Show real reviews near the call to action, ideally from a third-party source visitors can check (Google, Trustpilot, Checkatrade)."},{"id":"business_identity","category":"trust","status":"warn","severity":"low","title":"Business details are machine-readable","evidence":"No schema.org business markup (LocalBusiness/Organization) found","fix":"Add LocalBusiness structured data with name, address, phone and opening hours."},{"id":"privacy_policy","category":"trust","status":"fail","severity":"medium","title":"Privacy policy is linked","evidence":"No privacy policy link found","fix":"Link a privacy policy from the page. Meta and Google both require one on pages that collect personal details."},{"id":"mobile_viewport","category":"mobile","status":"fail","severity":"critical","title":"Page is set up for mobile screens","evidence":"No viewport meta tag found","fix":"Add <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">. Most paid social traffic is on phones."},{"id":"title","category":"mobile","status":"pass","severity":"low","title":"Page title is present and a sensible length","evidence":"Title (47 chars): \"Emergency Plumber in Leeds | Sample Plumbing Co\"","fix":null},{"id":"meta_description","category":"mobile","status":"pass","severity":"low","title":"Meta description is present","evidence":"Description is 101 characters","fix":null},{"id":"link_preview","category":"mobile","status":"warn","severity":"medium","title":"Link preview is set for social sharing","evidence":"og:title present, og:image missing","fix":"Add og:title and og:image so the page shows a proper preview when shared or used in a link ad."},{"id":"language","category":"mobile","status":"pass","severity":"low","title":"Page language is declared","evidence":"lang=\"en-GB\"","fix":null},{"id":"mixed_content","category":"mobile","status":"pass","severity":"medium","title":"No insecure resources on a secure page","evidence":"No http:// resources found","fix":null},{"id":"server_response","category":"speed","status":"warn","severity":"high","title":"Server responds quickly","evidence":"First byte after 840 ms (single measurement from the audit server)","fix":"Cut server response time below 600 ms: enable page caching, use a CDN, or move to faster hosting."},{"id":"html_size","category":"speed","status":"pass","severity":"low","title":"HTML document is a reasonable size","evidence":"HTML is 1 KB uncompressed","fix":null},{"id":"compression","category":"speed","status":"fail","severity":"medium","title":"Text compression is enabled","evidence":"The HTML was sent uncompressed","fix":"Enable gzip or Brotli compression on the server or CDN."},{"id":"render_blocking_scripts","category":"speed","status":"warn","severity":"medium","title":"Few scripts block the first paint","evidence":"4 render-blocking script(s) in <head> out of 5 external scripts","fix":"Add defer or async to scripts in the <head>, or move them to the end of the page."},{"id":"image_loading","category":"speed","status":"fail","severity":"medium","title":"Images further down the page load lazily","evidence":"0 of 3 images after the first three use lazy loading","fix":"Add loading=\"lazy\" to images that are not visible when the page first opens."}],"counts":{"pass":11,"warn":7,"fail":6,"unknown":0},"limitations":["Based on the HTML the server returns. Content added later by JavaScript is not seen.","Speed figures are one measurement from the audit server, not a field measurement from real visitors."]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"charged":{"type":"boolean"}},"required":["code","message"]}}}}}},"402":{"description":"Payment required. Read the PAYMENT-REQUIRED header."},"422":{"description":"The page could not be audited. Not charged.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"charged":{"type":"boolean"}},"required":["code","message"]}}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"charged":{"type":"boolean"}},"required":["code","message"]}}}}}}}}},"/v1/business":{"get":{"operationId":"getBusinessDetails","summary":"Contact and business details from a website (paid via x402)","description":"Costs 0.02 USDC per completed call. Without a PAYMENT-SIGNATURE header the response is 402 with a PAYMENT-REQUIRED header.","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string"},"description":"Public http(s) URL of the landing page.","example":"https://example.com/landing"}],"responses":{"200":{"description":"Business details"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"charged":{"type":"boolean"}},"required":["code","message"]}}}}}},"402":{"description":"Payment required."},"422":{"description":"Could not read the site. Not charged.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"charged":{"type":"boolean"}},"required":["code","message"]}}}}}}}}},"/v1/tracking":{"get":{"operationId":"checkTracking","summary":"Ad pixels, analytics, tag managers and site platform (paid via x402)","description":"Costs 0.01 USDC per completed call. Without a PAYMENT-SIGNATURE header the response is 402 with a PAYMENT-REQUIRED header.","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string"},"description":"Public http(s) URL of the landing page.","example":"https://example.com/landing"}],"responses":{"200":{"description":"Tracking report"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"charged":{"type":"boolean"}},"required":["code","message"]}}}}}},"402":{"description":"Payment required."},"422":{"description":"Could not read the site. Not charged.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"charged":{"type":"boolean"}},"required":["code","message"]}}}}}}}}},"/v1/preview":{"get":{"operationId":"previewLandingPage","summary":"Free preview: verdict, overall score and issue counts","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string"},"description":"Public http(s) URL of the landing page.","example":"https://example.com/landing"}],"responses":{"200":{"description":"Preview"},"429":{"description":"Rate limited"}}}},"/v1/sample":{"get":{"operationId":"sampleAudit","summary":"Free example of a full audit report","responses":{"200":{"description":"Sample report"}}}}},"components":{"schemas":{"AuditReport":{"type":"object","required":["schema_version","url","final_url","verdict","score","top_fixes","checks"],"properties":{"schema_version":{"type":"string"},"url":{"type":"string"},"final_url":{"type":"string"},"fetched_at":{"type":"string","format":"date-time"},"verdict":{"type":"string","enum":["ready","fix_first","not_ready"]},"summary":{"type":"string"},"score":{"type":"object","properties":{"overall":{"type":"integer","minimum":0,"maximum":100},"grade":{"type":"string","enum":["A","B","C","D","F"]},"by_category":{"type":"object","additionalProperties":{"type":["integer","null"]}}}},"blockers":{"type":"array","items":{"type":"string"}},"top_fixes":{"type":"array","items":{"type":"object","properties":{"priority":{"type":"integer"},"check_id":{"type":"string"},"severity":{"type":"string","enum":["critical","high","medium","low"]},"category":{"type":"string"},"fix":{"type":"string"},"evidence":{"type":"string"}}}},"ad_platform_readiness":{"type":"object"},"conversion_paths":{"type":"object"},"page":{"type":"object"},"http":{"type":"object"},"checks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string","enum":["conversion","tracking","trust","mobile","speed"]},"status":{"type":"string","enum":["pass","warn","fail","unknown"]},"severity":{"type":"string"},"title":{"type":"string"},"evidence":{"type":"string"},"fix":{"type":["string","null"]}}}},"counts":{"type":"object"},"limitations":{"type":"array","items":{"type":"string"}}}}}}}