[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"api-page:linkswatcher-api":3},{"status":4,"api":5,"seo":229},"success",{"blocked":6,"description":7,"about":8,"stats":9,"name":11,"title":12,"slug":13,"logo":14,"created_at":15,"agent":16,"user":28,"endpoint_groups":31,"faqs":163,"features":170,"periodic_plans":171,"payasyougo_plans":212,"releases":226,"last_updated":227,"createdAtText":228},false,"Automate URL scans across websites and pages to monitor link health, detect broken links, and simplify recurring affiliate audits.","## Overview\n\n**LinksWatcher** is a professional affiliate-link intelligence platform. This API lets you:\n\n- **Scan URLs** — submit any list of URLs and get back live availability, price, stock status, and redirect chain data.\n- **Discover links** — point us at a YouTube channel or any blog and we automatically discover, extract, and scan all affiliate links.\n- **Monitor results** — poll a batch endpoint or receive real-time webhook notifications when scans complete.\n\n---\n\n## Authentication\n\nEvery request requires a **Bearer token** issued from your LinksWatcher console.\n\n```\nAuthorization: Bearer \u003Cyour-api-token>\n```\n\nTokens are created under **Console → API Keys**. Keep them secret — they identify your account and are billed accordingly.\n\n---\n\n## Rate limits & quotas\n\n| Plan | Scans / month | Batch size | Req/min |\n|---|---|---|---|\n| Free | 50 | 5 | 10 |\n| Starter | 500 | 20 | 20 |\n| Growth | 2,000 | 50 | 30 |\n| Business | 10,000 | 100 | 60 |\n\nExceeding your plan quota deducts from your credit balance at the overage rate. Top-up credits are available in the console.",{"score":10},"2.29","LinksWatcher","LinksWatcher API","linkswatcher-api","https://cdn.jojapi.com/api/1855baf0-b045-4093-a3b9-3a4dd60aea66","2026-10-31 22:58:17",{"enabled":17,"closed":18,"request_enabled":6,"catalog_url":19,"discovery_url":20,"directory_url":21,"rails":22,"networks":25,"docs":27},true,null,"https://fljdt.jojapi.net/_jojapi/agent/plans","https://fljdt.jojapi.net/.well-known/x402","https://agents.jojapi.net/apis/linkswatcher-api",[23,24],"x402","mpp",[26],"eip155:8453","https://docs.jojapi.com/consumers/agents",{"nick":29,"name":30,"verified":6,"website":18},"lalioui-amine","Lalioui Amine",[32],{"endpoints":33,"name":162,"description":40,"ungrouped":6},[34,111],{"blocked":6,"hidden":6,"deprecation":18,"agent_price":18,"credits":18,"flexible_credits_description":18,"consumptions":35,"description":41,"method":42,"name":43,"url_path":44,"root_url":45,"parameters":46,"responses":61,"result_stats":107},[36],{"name":37,"slug":38,"cost":39,"label":40,"avg":18},"requests billing","requests-billing","1","","Submit a list of URLs to be scanned. Returns a `batchId` immediately — scanning happens asynchronously.\n\n**Workflow:**\n1. POST this endpoint with your URLs → receive `batchId`\n2. Poll `GET /api/batch/{id}` every few seconds until `status === \"COMPLETED\"`\n3. Or configure a webhook to receive push notifications\n\n**Batch size** is capped by your plan (5–100 URLs per request). Split large lists into multiple requests.\n\nIf you want batch results to include page screenshots, poll `GET /api/batch/{id}?includeScreenshot=true`.\n\n**Domains** must be in your plan's allowed domain list. Requests containing disallowed domains will be rejected with `403`.","POST","Submit URLs for scanning","/api/scanurl","https://fljdt.jojapi.net",{"url":47,"header":48,"post":55,"body":56,"path":60},[],[49],{"key":50,"is_auth":17,"example":51,"example_disabled":17,"example_type":52,"name":53,"description":51,"required":17,"always_error":54},"X-JoJAPI-Key","You must log in to get API key","string","JoJ API Key","Please log in to get API key",[],[57],{"key":18,"example":58,"schema":59,"example_disabled":6,"example_type":52,"value_type":52,"enum_values":18,"default_value":40,"required":6,"name":18,"description":18},"{\"urls\":[\"https://amzn.to/3abc123\"]}","{\"type\":\"object\",\"required\":[\"urls\"],\"properties\":{\"urls\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"format\":\"uri\"},\"minItems\":1,\"maxItems\":100,\"description\":\"List of URLs to scan. Maximum count is determined by your plan's batch size.\",\"example\":[\"https://amzn.to/3abc123\",\"https://www.amazon.fr/dp/B08N5WRWNW\"]},\"market\":{\"type\":\"string\",\"default\":\"FR\",\"description\":\"Locale/market code used to interpret prices and availability. Affects the geolocation of the scan request.\\n\\nSupported values: `FR`, `US`, `GB`, `DE`, `ES`, `IT`, `CA`, `JP`, and others.\",\"example\":\"FR\"},\"webhookIds\":{\"type\":\"array\",\"items\":{\"type\":\"string\",\"format\":\"uuid\"},\"description\":\"IDs of webhooks to notify when all jobs in this batch are finished. Webhook IDs are available in your console under **Webhooks**. If omitted, no webhook is triggered.\",\"example\":[\"a1b2c3d4-e5f6-7890-abcd-ef1234567890\"]}}}",[],[62,71,79,86,93,100],{"status":63,"status_code":64,"description":65,"schema":66,"examples":67,"example":70},"202",202,"Batch accepted. Scanning is in progress asynchronously. Use the returned `batchId` to poll for results.","{\"type\":\"object\",\"properties\":{\"batchId\":{\"type\":\"string\",\"format\":\"uuid\",\"description\":\"Unique identifier for this batch. Use it with `GET /api/batch/{id}` to retrieve results.\",\"example\":\"550e8400-e29b-41d4-a716-446655440000\"}}}",[68],{"name":69,"summary":40,"description":40,"example":70},"default","{\"batchId\":\"550e8400-e29b-41d4-a716-446655440000\"}",{"status":72,"status_code":73,"description":74,"schema":75,"examples":76,"example":78},"400",400,"Invalid request body — missing or malformed `urls`, invalid `market`, or invalid `webhookIds`.","{\"type\":\"object\",\"properties\":{\"error\":{\"type\":\"string\",\"description\":\"Human-readable error message\",\"example\":\"Batch not found\"}},\"required\":[\"error\"]}",[77],{"name":69,"summary":40,"description":40,"example":78},"{\"error\":\"urls must be a non-empty array\"}",{"status":80,"status_code":81,"description":82,"schema":75,"examples":83,"example":85},"401",401,"Missing or invalid Bearer token.",[84],{"name":69,"summary":40,"description":40,"example":85},"{\"error\":\"Unauthorized\"}",{"status":87,"status_code":88,"description":89,"schema":75,"examples":90,"example":92},"402",402,"Insufficient credit balance to cover overage costs.",[91],{"name":69,"summary":40,"description":40,"example":92},"{\"error\":\"Insufficient credit balance. Top up at https://console.linkswatcher.com/subscription\"}",{"status":94,"status_code":95,"description":96,"schema":75,"examples":97,"example":99},"403",403,"One or more URLs belong to a domain that is not in your allowed domains list.",[98],{"name":69,"summary":40,"description":40,"example":99},"{\"error\":\"Domain not allowed: example.com\"}",{"status":101,"status_code":102,"description":103,"schema":75,"examples":104,"example":106},"429",429,"Rate limit exceeded. Slow down your request rate or upgrade your plan.",[105],{"name":69,"summary":40,"description":40,"example":106},"{\"error\":\"Rate limit exceeded\"}",{"x2":108,"x3":109,"x4":109,"x5":109,"uptime":108,"avg_latency":110,"avg_credits":109},"100.00","0.00","592",{"blocked":6,"hidden":6,"deprecation":18,"agent_price":18,"credits":18,"flexible_credits_description":18,"consumptions":112,"description":113,"method":114,"name":115,"url_path":116,"root_url":45,"parameters":117,"responses":134,"result_stats":158},[],"Poll this endpoint to check the progress of a batch and retrieve completed results.\n\n**Polling strategy:** We recommend polling every **2–5 seconds**. The batch reaches a terminal state (`COMPLETED` or `FAILED`) once `finishedJobs === expectedJobs`.\n\nSet `includeScreenshot=true` if you also want each completed job to include `result.screenshotBase64`.\n\n**Tip:** Instead of polling, configure a **webhook** on the batch to receive a push notification when it finishes.","GET","Get batch status and results","/api/batch/{id}",{"url":118,"header":125,"post":127,"body":128,"path":129},[119],{"key":120,"example":121,"schema":18,"example_disabled":6,"example_type":52,"value_type":122,"enum_values":18,"default_value":123,"required":6,"name":40,"description":124},"includeScreenshot","true","boolean","false","When `true`, each completed job includes `result.screenshotBase64` with the captured page screenshot.",[126],{"key":50,"is_auth":17,"example":51,"example_disabled":17,"example_type":52,"name":53,"description":51,"required":17,"always_error":54},[],[],[130],{"key":131,"example":132,"example_disabled":6,"example_type":52,"value_type":52,"enum_values":18,"name":40,"description":133,"required":17},"id","550e8400-e29b-41d4-a716-446655440000","The `batchId` returned by `POST /api/scanurl` or `POST /api/discover`.",[135,143,148,151],{"status":136,"status_code":137,"description":138,"schema":139,"examples":140,"example":142},"200",200,"Batch details including all jobs and their scan results.","{\"type\":\"object\",\"properties\":{\"batchId\":{\"type\":\"string\",\"format\":\"uuid\",\"description\":\"Unique identifier of this batch.\"},\"status\":{\"type\":\"string\",\"enum\":[\"PENDING\",\"RUNNING\",\"COMPLETED\",\"FAILED\"],\"description\":\"Overall batch status. Transitions: `PENDING → RUNNING → COMPLETED` (or `FAILED` if all jobs fail).\"},\"expectedJobs\":{\"type\":\"integer\",\"description\":\"Total number of jobs in this batch.\",\"example\":10},\"finishedJobs\":{\"type\":\"integer\",\"description\":\"Number of jobs that have reached a terminal state (COMPLETED or FAILED).\",\"example\":7},\"createdAt\":{\"type\":\"string\",\"format\":\"date-time\"},\"jobs\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\",\"format\":\"uuid\",\"description\":\"Unique job identifier.\"},\"url\":{\"type\":\"string\",\"format\":\"uri\",\"description\":\"The URL that was submitted for scanning.\",\"example\":\"https://amzn.to/3abc123\"},\"market\":{\"type\":\"string\",\"description\":\"Market/locale used for this job.\",\"example\":\"FR\"},\"status\":{\"type\":\"string\",\"enum\":[\"PENDING\",\"RUNNING\",\"COMPLETED\",\"FAILED\"],\"description\":\"Current processing state of the job.\"},\"attemptCount\":{\"type\":\"integer\",\"description\":\"Number of scan attempts made so far (max 3 before marking as FAILED).\",\"example\":1},\"result\":{\"type\":\"object\",\"nullable\":true,\"description\":\"Populated once the job has finished scanning. `null` while the job is still `PENDING` or `RUNNING`.\",\"properties\":{\"state\":{\"type\":\"string\",\"enum\":[\"OK\",\"REDIRECT\",\"BROKEN\",\"OUT_OF_STOCK\",\"UNAVAILABLE\",\"ERROR\"],\"description\":\"High-level outcome of the scan.\\n\\n| Value | Meaning |\\n|---|---|\\n| `OK` | Link is live and the product is in stock |\\n| `REDIRECT` | Link redirects to a different final URL |\\n| `BROKEN` | HTTP 4xx / 5xx or connection error |\\n| `OUT_OF_STOCK` | Product found but not purchasable |\\n| `UNAVAILABLE` | Page exists but product is gone |\\n| `ERROR` | Internal scan error — retry recommended |\"},\"finalUrl\":{\"type\":\"string\",\"format\":\"uri\",\"description\":\"Final URL after all redirects have been followed.\",\"example\":\"https://www.amazon.fr/dp/B08N5WRWNW\"},\"httpStatus\":{\"type\":\"integer\",\"description\":\"HTTP status code of the final response.\",\"example\":200},\"responseMs\":{\"type\":\"integer\",\"description\":\"Total response time in milliseconds.\",\"example\":843},\"productName\":{\"type\":\"string\",\"nullable\":true,\"description\":\"Product title extracted from the page, if detected.\",\"example\":\"Echo Dot (4th Gen) | Smart speaker with Alexa\"},\"productImageUrl\":{\"type\":\"string\",\"format\":\"uri\",\"nullable\":true,\"description\":\"Main product image URL, if detected.\"},\"price\":{\"type\":\"object\",\"nullable\":true,\"description\":\"Current price of the product. `null` if no price was detected.\",\"properties\":{\"amount\":{\"type\":\"number\",\"description\":\"Price value.\",\"example\":29.99},\"currency\":{\"type\":\"string\",\"description\":\"ISO 4217 currency code.\",\"example\":\"EUR\"}}},\"inStock\":{\"type\":\"boolean\",\"nullable\":true,\"description\":\"`true` if the product is available to purchase, `false` if out of stock, `null` if not determinable.\",\"example\":true},\"stockLevel\":{\"type\":\"string\",\"nullable\":true,\"description\":\"Stock availability description returned by the retailer, if available.\",\"example\":\"In Stock\"},\"affiliateDetected\":{\"type\":\"boolean\",\"description\":\"Whether the URL contains a recognised affiliate tracking parameter.\",\"example\":true},\"replacementProduct\":{\"type\":\"object\",\"nullable\":true,\"description\":\"When a product is discontinued or out of stock the retailer sometimes redirects to a replacement. This field captures those details.\",\"properties\":{\"url\":{\"type\":\"string\",\"format\":\"uri\"},\"name\":{\"type\":\"string\",\"nullable\":true}}},\"aiConfidence\":{\"type\":\"number\",\"minimum\":0,\"maximum\":1,\"nullable\":true,\"description\":\"Confidence score (0–1) of the AI extraction model.\",\"example\":0.97},\"diagnostic\":{\"type\":\"string\",\"nullable\":true,\"description\":\"Short diagnostic message from the scanner, useful for debugging unexpected states.\",\"example\":\"Detected 301 redirect chain (3 hops)\"},\"screenshotBase64\":{\"type\":\"string\",\"nullable\":true,\"description\":\"Base64-encoded page screenshot captured during the scan. This field is omitted unless you call `GET /api/batch/{id}?includeScreenshot=true`.\",\"example\":\"/9j/4AAQSkZJRgABAQAAAQABAAD...\"},\"domain\":{\"type\":\"string\",\"description\":\"Effective domain of the final URL.\",\"example\":\"amazon.fr\"},\"market\":{\"type\":\"string\",\"description\":\"Market code used for this scan.\",\"example\":\"FR\"},\"checkedAt\":{\"type\":\"string\",\"format\":\"date-time\",\"description\":\"ISO 8601 timestamp of when the scan completed.\"},\"duration\":{\"type\":\"integer\",\"description\":\"Total scan duration in milliseconds (including retries).\",\"example\":1250}}}}}}}}",[141],{"name":69,"summary":40,"description":40,"example":142},"{\"batchId\":\"550e8400-e29b-41d4-a716-446655440000\",\"status\":\"COMPLETED\",\"expectedJobs\":2,\"finishedJobs\":2,\"createdAt\":\"2026-04-06T10:00:00.000Z\",\"jobs\":[{\"id\":\"661f9511-f30c-42e5-b827-557766551111\",\"url\":\"https://amzn.to/3abc123\",\"market\":\"FR\",\"status\":\"COMPLETED\",\"attemptCount\":1,\"result\":{\"state\":\"OK\",\"finalUrl\":\"https://www.amazon.fr/dp/B08N5WRWNW\",\"httpStatus\":200,\"responseMs\":843,\"productName\":\"Echo Dot (4th Gen)\",\"productImageUrl\":\"https://m.media-amazon.com/images/I/example.jpg\",\"price\":{\"amount\":29.99,\"currency\":\"EUR\"},\"inStock\":true,\"stockLevel\":\"In Stock\",\"affiliateDetected\":true,\"replacementProduct\":null,\"aiConfidence\":0.97,\"diagnostic\":null,\"screenshotBase64\":\"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\"domain\":\"amazon.fr\",\"market\":\"FR\",\"checkedAt\":\"2026-04-06T10:00:03.000Z\",\"duration\":1250}}]}",{"status":72,"status_code":73,"description":144,"schema":75,"examples":145,"example":147},"The provided `id` is not a valid UUID.",[146],{"name":69,"summary":40,"description":40,"example":147},"{\"error\":\"Invalid batch ID format\"}",{"status":80,"status_code":81,"description":82,"schema":75,"examples":149,"example":85},[150],{"name":69,"summary":40,"description":40,"example":85},{"status":152,"status_code":153,"description":154,"schema":75,"examples":155,"example":157},"404",404,"No batch found with this ID for your account.",[156],{"name":69,"summary":40,"description":40,"example":157},"{\"error\":\"Batch not found\"}",{"x2":159,"x3":109,"x4":160,"x5":109,"uptime":108,"avg_latency":161,"avg_credits":109},"75.00","25.00","289","Scanning",[164,167],{"question":165,"answer":166},"How is this different from a broken-link checker?","Broken-link tools usually stop at availability. LinksWatcher goes further and checks the monetization outcome: stock, redirects, affiliate detection, and whether the destination still makes sense for the click.",{"question":168,"answer":169},"Can LinksWatcher detect out-of-stock retailer pages?","Yes. That is one of the main jobs. The goal is to catch pages that still load but are no longer sellable, so teams can update the link before traffic keeps leaking.",[],[172,191,202],{"type":173,"slug":174,"blocked":6,"period":175,"currency":176,"pricing":177,"rate_limit":182,"objects":185,"name":189,"display_name":189,"features":190},"periodic","okvkglu4tj718y50o6olgnz9","1 MONTH","usd",{"price":178,"credits":179,"past_due_timeout_num":180,"past_due_timeout_type":181},19,0,3,"DAY",{"max_requests":183,"time_window":184},20,60,[186],{"id":187,"name":37,"slug":38,"quota":188,"tiers":18},"n13cd1fed",500,"Starter",[],{"type":173,"slug":192,"blocked":6,"period":175,"currency":176,"pricing":193,"rate_limit":195,"objects":197,"name":200,"display_name":200,"features":201},"c2wb3raqdueyviijqm7ptwyd",{"price":194,"credits":179,"past_due_timeout_num":180,"past_due_timeout_type":181},79,{"max_requests":196,"time_window":184},30,[198],{"id":187,"name":37,"slug":38,"quota":199,"tiers":18},2000,"Growth",[],{"type":173,"slug":203,"blocked":6,"period":175,"currency":176,"pricing":204,"rate_limit":206,"objects":207,"name":210,"display_name":210,"features":211},"1apy2x67g09tn5lglrnlbb0d",{"price":205,"credits":179,"past_due_timeout_num":180,"past_due_timeout_type":181},299,{"max_requests":184,"time_window":184},[208],{"id":187,"name":37,"slug":38,"quota":209,"tiers":18},10000,"Business",[],[213],{"type":214,"slug":215,"blocked":6,"period":175,"currency":176,"pricing":216,"rate_limit":217,"objects":218,"name":224,"display_name":224,"features":225},"payasyougo","zx3wo3ykgdoc7tk6brj3ou46",[],{"max_requests":183,"time_window":184},[219],{"id":187,"name":37,"slug":38,"quota":18,"tiers":220},[221],{"start":179,"unit_price":222,"start_text":223},0.05,"0","Standard",[],[],"2026-11-01 18:59:00","2026-10-31",{"canonical":230,"page_title":231,"meta":232},"https://jojapi.com/hub/api/linkswatcher-api","LinksWatcher API Documentation & Playground - JoJ API",{"description":7,"keywords":233},"API,API Documentation,API Playground,Plans & Pricing,LinksWatcher,lalioui-amine"]