{"openapi":"3.2.0","info":{"title":"Email and SEO Metadata Extraction API","description":"Fast API to validate email syntax, detect disposable domains, and extract SEO Open Graph tags.","version":"1.0.0"},"servers":[{"url":"https://zlwwz.jojapi.net"}],"security":[{"ApiKeyAuth":[]}],"x-agent-commerce":{"catalog_url":"https://zlwwz.jojapi.net/_jojapi/agent/plans","discovery_url":"https://zlwwz.jojapi.net/.well-known/x402","directory_url":"https://agents.jojapi.net/apis/email-and-seo-metadata-extraction-api","docs":"https://docs.jojapi.com/consumers/agents"},"paths":{"/validate-email":{"get":{"operationId":"get_validate_email","summary":"Validate Email","description":"Checks email syntax and flags known disposable-email domains. It does not verify mailbox existence.","responses":{"200":{"description":"Email syntax and disposable-domain assessment. This is not mailbox verification.","content":{"application/json":{"examples":{"default":{"summary":"Syntactically valid non-disposable address","value":{"success":true,"data":{"email":"hello@example.com","domain":"example.com","validSyntax":true,"isDisposable":false},"error":null}}}}}},"400":{"description":"Missing or empty email query parameter.","content":{"application/json":{"example":{"success":false,"data":null,"error":{"code":"MISSING_PARAMETER","message":"Query parameter \"email\" is required."}}}}}},"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","example":"hello@example.com","default":"hello@example.com"}}]}},"/extract-seo":{"get":{"operationId":"get_extract_seo","summary":"Extract SEO Metadata","description":"Fetches a public HTML page and extracts its title, meta description, og:title, and og:image. Eligible successful results may be cached internally for up to 5 minutes (shorter when required by the target cache policy). Set optional fresh=true to bypass cache reads and writes; false or omission allows caching. Only exact true/false are accepted; invalid or duplicate fresh parameters return HTTP 400. Response headers X-SEO-Cache (HIT, MISS, BYPASS) and X-SEO-Cache-Age (whole seconds; 0 for MISS/BYPASS) report cache use. Reading can stop once all four non-empty fields are complete. Missing fields remain null; JavaScript is not executed. Authentication and marketplace request quotas still apply to cache hits.","responses":{"200":{"description":"HTML metadata extracted successfully. Missing tags return null; JavaScript is not executed. X-SEO-Cache reports HIT, MISS or BYPASS; X-SEO-Cache-Age reports whole seconds (0 for MISS/BYPASS). Client Cache-Control remains no-store.","content":{"application/json":{"example":{"success":true,"data":{"url":"https://example.com/","title":"Example Domain","description":null,"openGraph":{"title":null,"image":null}},"error":null}}}},"400":{"description":"The url parameter is missing, empty or invalid (MISSING_PARAMETER / INVALID_URL), or fresh is not exactly true or false or is repeated (INVALID_PARAMETER).","content":{"application/json":{"example":{"success":false,"data":null,"error":{"code":"MISSING_PARAMETER","message":"Query parameter \"url\" is required."}}}}},"403":{"description":"Target URL is not allowed: credentials, custom ports, IP literals, local hostnames or this service are rejected."},"422":{"description":"The target returned a non-HTML content type."},"502":{"description":"Unable to retrieve the target page, unsuccessful upstream HTTP status, invalid redirect, too many redirects, or empty upstream body."},"504":{"description":"The target request exceeded the 8-second timeout."}},"parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string","example":"https://example.com/","default":"https://example.com/"}},{"name":"fresh","in":"query","required":false,"schema":{"type":"boolean","example":false}}]}},"/health":{"get":{"operationId":"get_health","summary":"Health Check","description":"Returns the current API status and server timestamp.","responses":{"200":{"description":"Service is responding. timestamp is the current UTC time in ISO 8601 format.","content":{"application/json":{"example":{"status":"ok","timestamp":"2026-09-05T18:00:00.000Z"}}}},"401":{"description":"Generated by the JoJ API gateway when the consumer API key is missing or invalid, or the required subscription is absent. Include your own X-JoJAPI-Key header. Gateway errors use a message field, not the origin JSON envelope.","content":{"application/json":{"example":{"message":"Unauthorized"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-JoJAPI-Key","description":"Your JoJ API key."}}}}