{"openapi":"3.1.0","info":{"title":"Link Preview & URL Metadata API","version":"1.0.0","description":"Everything you need to render a rich link card: title, description, preview image, favicon, site name, type, Open Graph and Twitter Card tags, canonical URL, language, feeds, oEmbed and schema.org types. Relative URLs are made absolute; images and PDFs are described too; add `render=auto` to fall back to a real browser for sites that block plain requests.\n\nAll endpoints accept GET (query string) or POST (JSON body). Errors use one shape: `{\"success\": false, \"error\": {\"code\", \"message\", \"retryable\"}}`. When a numeric `Retry-After` header is present, `error.retryAfterSeconds` is included.","contact":{"name":"TidyTools","url":"https://apify.com/tidytools"}},"servers":[{"url":"https://webcapture-api.yukailin.workers.dev","description":"Origin (reachable only through the marketplace gateway)"}],"tags":[{"name":"Metadata"}],"paths":{"/api/v1/metadata":{"get":{"operationId":"metadataGet","summary":"Get link-preview metadata for a URL (GET)","description":"Reads the page's head (Open Graph, Twitter Card, icons, feeds, JSON-LD) and returns normalized preview fields. Missing Open Graph fields fall back to JSON-LD (image, author, dates, publisher, logo); `socialProfiles` lists the site's own profile links; `warning` is `login_wall` or `no_metadata` when the answer is not a useful preview (e.g. a login redirect, or only the site name as title).","tags":["Metadata"],"parameters":[{"name":"url","schema":{"type":"string"},"description":"Page URL. A bare domain such as `example.com` is accepted (https is assumed). Private, local and cloud-metadata addresses are refused.","required":true,"example":"https://example.com","in":"query"},{"name":"render","schema":{"type":"string","default":"never","enum":["auto","never","always"]},"description":"`never` (default): plain HTTP only, fast and cheap. `auto`: a real Chrome browser when the site blocks plain requests or needs JavaScript. `always`: browser only.","required":false,"in":"query"},{"name":"timeoutMs","schema":{"type":"integer","default":15000,"minimum":1000,"maximum":30000},"description":"Page-load timeout in milliseconds.","required":false,"in":"query"}],"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"url":{"type":"string"},"finalUrl":{"type":"string"},"statusCode":{"type":"integer"},"contentType":{"type":"string"},"renderedWith":{"type":"string"},"warning":{"type":"string","nullable":true},"title":{"type":"string"},"htmlTitle":{"type":"string"},"description":{"type":"string"},"siteName":{"type":"string"},"type":{"type":"string"},"image":{"type":"string"},"imageAlt":{"type":"string"},"video":{"type":"string","nullable":true},"favicon":{"type":"string"},"icons":{"type":"array","items":{"type":"object","properties":{"href":{"type":"string"},"rel":{"type":"string"},"sizes":{"type":"string","nullable":true}}}},"canonical":{"type":"string","nullable":true},"language":{"type":"string"},"author":{"type":"string","nullable":true},"publisher":{"type":"string"},"logo":{"type":"string","nullable":true},"keywords":{"type":"string","nullable":true},"themeColor":{"type":"string"},"twitterCard":{"type":"string"},"twitterSite":{"type":"string"},"publishedTime":{"type":"string","nullable":true},"modifiedTime":{"type":"string","nullable":true},"socialProfiles":{"type":"object","properties":{"github":{"type":"string"},"x":{"type":"string"}}},"feeds":{"type":"array","items":{}},"oembed":{"type":"string","nullable":true},"manifest":{"type":"string"},"structuredDataTypes":{"type":"array","items":{"type":"string"}},"openGraph":{"type":"object","properties":{"twitter:image":{"type":"string"},"twitter:site":{"type":"string"},"twitter:title":{"type":"string"},"twitter:description":{"type":"string"},"og:image":{"type":"string"},"og:image:alt":{"type":"string"},"og:image:width":{"type":"string"},"og:image:height":{"type":"string"},"og:site_name":{"type":"string"},"og:type":{"type":"string"},"og:title":{"type":"string"},"og:url":{"type":"string"},"og:description":{"type":"string"}}},"wordCount":{"type":"integer"},"responseMs":{"type":"integer"}}},"example":{"success":true,"url":"https://github.com/cloudflare/workers-sdk","finalUrl":"https://github.com/cloudflare/workers-sdk","statusCode":200,"contentType":"text/html","renderedWith":"http","warning":null,"title":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers®","htmlTitle":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers® · GitHub","description":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","siteName":"GitHub","type":"object","image":"https://opengraph.githubassets.com/256f7955f5ea47db0562d7da5b0c003de363200cc832aaec1620a138abe73bb3/cloudflare/workers-sdk","imageAlt":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","video":null,"favicon":"https://github.githubassets.com/favicons/favicon.svg","icons":[{"href":"https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg","rel":"mask-icon","sizes":null},{"href":"https://github.githubassets.com/favicons/favicon.png","rel":"alternate icon","sizes":null},{"href":"https://github.githubassets.com/favicons/favicon.svg","rel":"icon","sizes":null}],"canonical":null,"language":"en","author":null,"publisher":"GitHub","logo":null,"keywords":null,"themeColor":"#1e2327","twitterCard":"summary_large_image","twitterSite":"@github","publishedTime":null,"modifiedTime":null,"socialProfiles":{"github":"https://github.com/mcp","x":"https://twitter.com/CloudflareDev"},"feeds":[],"oembed":null,"manifest":"https://github.com/manifest.json","structuredDataTypes":["SoftwareSourceCode"],"openGraph":{"twitter:image":"https://opengraph.githubassets.com/256f7955f5ea47db0562d7da5b0c003de363200cc832aaec1620a138abe73bb3/cloudflare/workers-sdk","twitter:site":"@github","twitter:title":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers®","twitter:description":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","og:image":"https://opengraph.githubassets.com/256f7955f5ea47db0562d7da5b0c003de363200cc832aaec1620a138abe73bb3/cloudflare/workers-sdk","og:image:alt":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","og:image:width":"1200","og:image:height":"600","og:site_name":"GitHub","og:type":"object","og:title":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers®","og:url":"https://github.com/cloudflare/workers-sdk","og:description":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk"},"wordCount":819,"responseMs":611}}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"Request body or target document too large (`too_large`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The target site refused (`target_blocked`), could not be reached or its domain does not resolve (`target_unreachable`), the page does not exist (`target_error`, HTTP 404/410), or returned unsupported content.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"target_blocked","message":"The target refused the request: target returned HTTP 403","details":{"targetStatus":403,"finalUrl":"https://www.g2.com/"}}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"metadata","summary":"Get link-preview metadata for a URL","description":"Reads the page's head (Open Graph, Twitter Card, icons, feeds, JSON-LD) and returns normalized preview fields. Missing Open Graph fields fall back to JSON-LD (image, author, dates, publisher, logo); `socialProfiles` lists the site's own profile links; `warning` is `login_wall` or `no_metadata` when the answer is not a useful preview (e.g. a login redirect, or only the site name as title).\n\nThe same parameters as the GET form, sent as a JSON body.","tags":["Metadata"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Page URL. A bare domain such as `example.com` is accepted (https is assumed). Private, local and cloud-metadata addresses are refused."},"render":{"type":"string","default":"never","enum":["auto","never","always"],"description":"`never` (default): plain HTTP only, fast and cheap. `auto`: a real Chrome browser when the site blocks plain requests or needs JavaScript. `always`: browser only."},"timeoutMs":{"type":"integer","default":15000,"minimum":1000,"maximum":30000,"description":"Page-load timeout in milliseconds."}},"required":["url"]}}}},"responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"url":{"type":"string"},"finalUrl":{"type":"string"},"statusCode":{"type":"integer"},"contentType":{"type":"string"},"renderedWith":{"type":"string"},"warning":{"type":"string","nullable":true},"title":{"type":"string"},"htmlTitle":{"type":"string"},"description":{"type":"string"},"siteName":{"type":"string"},"type":{"type":"string"},"image":{"type":"string"},"imageAlt":{"type":"string"},"video":{"type":"string","nullable":true},"favicon":{"type":"string"},"icons":{"type":"array","items":{"type":"object","properties":{"href":{"type":"string"},"rel":{"type":"string"},"sizes":{"type":"string","nullable":true}}}},"canonical":{"type":"string","nullable":true},"language":{"type":"string"},"author":{"type":"string","nullable":true},"publisher":{"type":"string"},"logo":{"type":"string","nullable":true},"keywords":{"type":"string","nullable":true},"themeColor":{"type":"string"},"twitterCard":{"type":"string"},"twitterSite":{"type":"string"},"publishedTime":{"type":"string","nullable":true},"modifiedTime":{"type":"string","nullable":true},"socialProfiles":{"type":"object","properties":{"github":{"type":"string"},"x":{"type":"string"}}},"feeds":{"type":"array","items":{}},"oembed":{"type":"string","nullable":true},"manifest":{"type":"string"},"structuredDataTypes":{"type":"array","items":{"type":"string"}},"openGraph":{"type":"object","properties":{"twitter:image":{"type":"string"},"twitter:site":{"type":"string"},"twitter:title":{"type":"string"},"twitter:description":{"type":"string"},"og:image":{"type":"string"},"og:image:alt":{"type":"string"},"og:image:width":{"type":"string"},"og:image:height":{"type":"string"},"og:site_name":{"type":"string"},"og:type":{"type":"string"},"og:title":{"type":"string"},"og:url":{"type":"string"},"og:description":{"type":"string"}}},"wordCount":{"type":"integer"},"responseMs":{"type":"integer"}}},"example":{"success":true,"url":"https://github.com/cloudflare/workers-sdk","finalUrl":"https://github.com/cloudflare/workers-sdk","statusCode":200,"contentType":"text/html","renderedWith":"http","warning":null,"title":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers®","htmlTitle":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers® · GitHub","description":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","siteName":"GitHub","type":"object","image":"https://opengraph.githubassets.com/256f7955f5ea47db0562d7da5b0c003de363200cc832aaec1620a138abe73bb3/cloudflare/workers-sdk","imageAlt":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","video":null,"favicon":"https://github.githubassets.com/favicons/favicon.svg","icons":[{"href":"https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg","rel":"mask-icon","sizes":null},{"href":"https://github.githubassets.com/favicons/favicon.png","rel":"alternate icon","sizes":null},{"href":"https://github.githubassets.com/favicons/favicon.svg","rel":"icon","sizes":null}],"canonical":null,"language":"en","author":null,"publisher":"GitHub","logo":null,"keywords":null,"themeColor":"#1e2327","twitterCard":"summary_large_image","twitterSite":"@github","publishedTime":null,"modifiedTime":null,"socialProfiles":{"github":"https://github.com/mcp","x":"https://twitter.com/CloudflareDev"},"feeds":[],"oembed":null,"manifest":"https://github.com/manifest.json","structuredDataTypes":["SoftwareSourceCode"],"openGraph":{"twitter:image":"https://opengraph.githubassets.com/256f7955f5ea47db0562d7da5b0c003de363200cc832aaec1620a138abe73bb3/cloudflare/workers-sdk","twitter:site":"@github","twitter:title":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers®","twitter:description":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","og:image":"https://opengraph.githubassets.com/256f7955f5ea47db0562d7da5b0c003de363200cc832aaec1620a138abe73bb3/cloudflare/workers-sdk","og:image:alt":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk","og:image:width":"1200","og:image:height":"600","og:site_name":"GitHub","og:type":"object","og:title":"GitHub - cloudflare/workers-sdk: ⛅️ Home to Wrangler, the CLI for Cloudflare Workers®","og:url":"https://github.com/cloudflare/workers-sdk","og:description":"⛅️ Home to Wrangler, the CLI for Cloudflare Workers® - cloudflare/workers-sdk"},"wordCount":819,"responseMs":611}}}},"400":{"description":"Invalid parameter (`invalid_request`) or a private/local target (`url_not_allowed`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"url_not_allowed","message":"private, local and reserved hosts are not allowed"}}}}},"413":{"description":"Request body or target document too large (`too_large`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The target site refused (`target_blocked`), could not be reached or its domain does not resolve (`target_unreachable`), the page does not exist (`target_error`, HTTP 404/410), or returned unsupported content.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":{"code":"target_blocked","message":"The target refused the request: target returned HTTP 403","details":{"targetStatus":403,"finalUrl":"https://www.g2.com/"}}}}}},"502":{"description":"Temporary failure on our side (`upstream_error`); safe to retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The target did not respond in time (`timeout`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","required":["success","error"],"properties":{"success":{"const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["not_configured","unauthorized","not_found","method_not_allowed","invalid_request","rate_limited","url_not_allowed","target_blocked","target_unreachable","target_error","unsupported_content","too_large","timeout","upstream_error","board_not_found","app_not_found"]},"message":{"type":"string"},"retryable":{"type":"boolean","description":"true for rate_limited, timeout, upstream_error and browser_busy; false for other errors."},"retryAfterSeconds":{"type":"integer","description":"Seconds to wait before retrying, when a numeric Retry-After header is present."},"details":{"type":"object","additionalProperties":true}}}}}}}}