{"openapi": "3.0.3", "info": {"title": "Radar API", "version": "1.0", "description": "Official public data as one API. One key for every endpoint. Free plan: 100 calls/month."}, "servers": [{"url": "https://radarbg.com"}], "paths": {"/v1/bank-statement-converter": {"post": {"operationId": "bank_statement_converter", "summary": "Bank Statement Converter", "description": "Convert bank statements without software or AI: camt.053 (ISO 20022, versions .001.02 to .001.08, also camt.052) and MT940 files, single or zipped, to clean JSON, CSV, Excel (xlsx) or back to MT940 for older accounting tools. Every statement gets a balance check (opening + entries = closing). Counterparty name, IBAN, BIC, remittance text, end-to-end ID, mandate and creditor ID, bank transaction code and German ?20-?33 / Dutch /TRTP/ fields are parsed. Files are processed in memory only and never stored. Monitor mode returns only transactions not seen before.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"fileUrl": {"type": "string", "description": "Public http(s) link to a camt.053, camt.052 or MT940 file, or a .zip with several (max 10 MB, 50 files). For example a pre-signed S3/Drive link. Private and local addresses are refused. Leave empty and fill File content instead, or leave bo"}, "fileContent": {"type": "string", "description": "The statement itself: raw XML / MT940 text, or base64 of the file (zip allowed). Max 10 MB. Processed in memory only, never stored or logged."}, "fileName": {"type": "string", "description": "Optional original file name, used as sourceFile in the rows and as the name of the output file (for example statement-2026-11.xml)."}, "format": {"type": "string", "description": "json = one row per statement (balances + balance check) and one row per transaction; csv or xlsx = one row with the file as base64 (contentBase64) plus statement summaries; mt940 = camt converted to MT940 text (also base64)."}, "inputFormat": {"type": "string", "description": "auto detects camt (XML) or MT940 by content. Set it only if detection fails."}, "onlyNew": {"type": "boolean", "description": "With format json: return only transactions not returned before under this Monitor ID (useful when a daily feed repeats yesterday's entries). Only one-way hashes of the transaction keys are kept, never the statement."}, "monitorId": {"type": "string", "description": "Name of the feed for only-new mode, for example account-de-main. Each Monitor ID keeps its own memory."}}}, "example": {"format": "json", "inputFormat": "auto", "onlyNew": false, "monitorId": "default"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/business-check": {"post": {"operationId": "business_check", "summary": "Business Check", "description": "One-call KYB check of a company: EU VAT number validated in the official VIES register (company name and registered address), the address geocoded by the national geocoder, the website domain's age and registrar (RDAP), its email authentication score, and plain risk flags (invalid VAT, domain younger than 180 days, name not matching the domain, spoofable email). ~1-2 s.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"vatNumber": {"type": "string", "description": "EU VAT number with country prefix, e.g. IE6388047V (also NO/CH/GB formats)"}, "domain": {"type": "string", "description": "Company website or e-mail domain, e.g. google.com"}, "address": {"type": "string", "description": "Optional address to geocode instead of the registered one"}}}, "example": {"vatNumber": "IE6388047V", "domain": "google.com"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/federal-register": {"post": {"operationId": "federal_register", "summary": "Federal Register Search", "description": "Search the official US Federal Register: final rules, proposed rules, notices and presidential documents with abstract, agencies, publication date and links. Filter by keyword, type, agency and date.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"query": {"type": "string", "description": "Keywords, e.g. artificial intelligence"}, "type": {"type": "string", "description": "RULE, PRORULE, NOTICE or PRESDOCU"}, "agency": {"type": "string", "description": "Agency slug, e.g. environmental-protection-agency"}, "since": {"type": "string", "description": "Published on or after (YYYY-MM-DD)"}, "order": {"type": "string", "description": "newest or relevance"}, "maxItems": {"type": "integer", "description": "Max results (1-50)"}}}, "example": {"query": "artificial intelligence", "type": "RULE", "order": "newest", "maxItems": 10}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/hs-code-tariff-lookup": {"post": {"operationId": "hs_code_tariff_lookup", "summary": "HS Code Lookup API", "description": "HS code lookup API, no key: product keyword to ranked HS / commodity codes, and any code to its full description chain, import duty (third-country), VAT, preferential rate for an origin country, quotas, anti-dumping and other measures for the UK tariff and the EU Common Customs Tariff. Code validation, non-declarable codes return their declarable children, bulk 50 lookups. Official HMRC data. Usable from AI agents via MCP.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "search = keyword to ranked HS/commodity codes; code = full details of one code (duty, VAT, origin rate, measures, or declarable children); validate = check that codes exist and are declarable; bulk = up to 50 queries in one call."}, "q": {"type": "string", "description": "search mode: product words in English, e.g. cotton t-shirt, lithium battery, roasted coffee."}, "code": {"type": "string", "description": "code mode: HS / commodity code with 2, 4, 6, 8 or 10 digits; dots and spaces are ignored, e.g. 6109.10 or 6109100010."}, "codes": {"type": "array", "description": "validate mode: up to 100 codes.", "items": {}}, "market": {"type": "string", "description": "UK = UK Global Tariff (default); EU = EU Common Customs Tariff as published by the UK Trade Tariff Northern Ireland (XI) service."}, "origin": {"type": "string", "description": "ISO 2-letter country of origin, e.g. CN, VN, US. code mode returns the preferential rate and the duty that applies to this origin."}, "queries": {"type": "array", "description": "bulk mode: up to 50 objects, each one an input of another mode, e.g. {\"mode\":\"code\",\"code\":\"8517130000\",\"origin\":\"VN\"}. A failing query returns an error row; the others still answer.", "items": {}}, "limit": {"type": "integer", "description": "search mode: 1-50, default 10."}, "onlyNew": {"type": "boolean", "description": "Return only rows not returned before for the same Monitor ID. Schedule the run to get changes only."}, "monitorId": {"type": "string", "description": "Name of this monitor; each ID keeps its own memory of rows already returned."}}}, "example": {"mode": "search", "q": "red wine", "market": "UK", "limit": 10}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/sec-edgar-scraper": {"post": {"operationId": "sec_edgar_scraper", "summary": "SEC Filings Scraper", "description": "SEC EDGAR filings for every US public company. No API key, no login, no proxy: official open API. Only-new 8-K alerts with item codes in plain English (5.02 officer change, 1.05 cyber incident...), full-text search, 10-K/10-Q/Form 4 by ticker, XBRL financials.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "Company filings by ticker/CIK, full-text search across all filings, the latest filings from all companies, or yearly/quarterly financials (XBRL)."}, "tickers": {"type": "array", "description": "Stock tickers (AAPL, TSLA) or SEC CIK numbers (320193). Used by 'Company filings' and 'Financials'. Optional filter for search and latest.", "items": {}}, "forms": {"type": "array", "description": "e.g. 10-K, 10-Q, 8-K, S-1, 4, 13F-HR, SC 13D, DEF 14A, D. Empty = all forms. 'Latest filings' defaults to 8-K.", "items": {}}, "keywords": {"type": "array", "description": "Each phrase is one search across the full text of all EDGAR filings since 2001, e.g. \"artificial intelligence\", \"going concern\", \"cybersecurity incident\".", "items": {}}, "postedWithinDays": {"type": "integer", "description": "0 = no limit (company filings) or 30 days (search and latest)."}, "dateFrom": {"type": "string", "description": "Optional. Overrides 'within the last N days'."}, "dateTo": {"type": "string", "description": "Optional. Default today."}, "eightKItems": {"type": "array", "description": "Only 8-Ks with these item codes, e.g. 1.01 (material agreement), 2.02 (results), 5.02 (officer change), 1.05 (cybersecurity incident).", "items": {}}, "periodType": {"type": "string", "description": "For 'Financials' mode."}, "years": {"type": "integer", "description": "How many fiscal years of financials per company."}, "includeCompanyInfo": {"type": "boolean", "description": "Adds industry (SIC), state, exchange, website, phone and business address to each filing."}, "onlyNew": {"type": "boolean", "description": "For alerts: each filing is returned (and paid for) once."}, "monitorId": {"type": "string", "description": "Separate memory for different watch lists (used with only-new mode)."}, "contactEmail": {"type": "string", "description": "SEC asks automated tools to identify themselves. If set, it is sent in the User-Agent header to SEC only."}}}, "example": {"mode": "company_filings", "tickers": ["AAPL", "TSLA"], "forms": ["10-K", "10-Q", "8-K"], "postedWithinDays": 365}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/eu-tenders-ted-monitor": {"post": {"operationId": "eu_tenders_ted_monitor", "summary": "TED Scraper", "description": "EU public tenders from TED (Tenders Electronic Daily). No API key, no login, no proxy: official open API. Search by keyword, CPV code, country, value and deadline; get buyer, contact, value, deadline, CPV codes and document links. Only-new mode for daily tender alerts.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"keywords": {"type": "array", "description": "Words to find in the tender title, e.g. 'software', 'cleaning', 'cybersecurity', 'solar'. English works for tenders in every EU language (titles are translated). Several keywords = any of them. Empty = all tenders.", "items": {}}, "searchIn": {"type": "string", "description": "'Title' gives precise results. 'Full notice text' also matches the description, so you get more (and looser) results."}, "cpvCodes": {"type": "array", "description": "Common Procurement Vocabulary codes. A general code includes all its sub-codes: '72000000' = all IT services, '90910000' = cleaning, '45000000' = construction works, '79' = business services. Empty = any.", "items": {}}, "countries": {"type": "array", "description": "Country of the contracting authority: ISO codes (DE, FR, PL or DEU) or English names (Germany). Empty = all EU/EEA countries.", "items": {}}, "noticeTypes": {"type": "array", "description": "Contract notices = open tenders you can bid on. Prior information = upcoming tenders. Contract awards = who won and for how much.", "items": {}}, "postedWithinDays": {"type": "integer", "description": "Only notices published in the last N days. 0 = any date."}, "onlyOpenTenders": {"type": "boolean", "description": "Skip contract notices whose submission deadline has passed (applies when only 'Contract notices' are selected)."}, "minValue": {"type": "integer", "description": "Skip tenders in EUR with a known estimated value below this. Tenders without a published value are kept. 0 = no limit."}, "language": {"type": "string", "description": "Language for the translated title and names when available."}, "includeDescription": {"type": "boolean", "description": "Add the procedure description (original language)."}, "onlyNewTenders": {"type": "boolean", "description": "Return only notices not seen in previous runs with the same Monitor ID. Use with a Schedule for daily tender alerts."}, "monitorId": {"type": "string", "description": "Name of the monitor for 'only new tenders'. Use different IDs for different searches."}, "maxItems": {"type": "integer", "description": "Hard limit on tenders saved (and paid for)."}}}, "example": {"keywords": ["software"], "searchIn": "title", "noticeTypes": ["contract-notices"], "postedWithinDays": 7}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/uk-visa-sponsors-register": {"post": {"operationId": "uk_visa_sponsors_register", "summary": "UK Visa Sponsor Register Scraper", "description": "Every company licensed to sponsor UK work visas, from the official Home Office register.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"companyNames": {"type": "array", "description": "Keep sponsors whose name contains any of these words (e.g. 'bank', 'NHS', 'software'). Empty = all.", "items": {}}, "towns": {"type": "array", "description": "Exact town or city as in the register, e.g. London, Manchester, Birmingham.", "items": {}}, "counties": {"type": "array", "description": "Exact county, e.g. Greater London, West Midlands.", "items": {}}, "routes": {"type": "array", "description": "Keep only these routes (contains match), e.g. Skilled Worker, Global Business Mobility, Scale-up, Creative Worker, Seasonal Worker.", "items": {}}, "ratings": {"type": "array", "description": "e.g. A rating, B rating, Provisional. Empty = all.", "items": {}}, "onlyNew": {"type": "boolean", "description": "Return only sponsors that were not returned by earlier runs with the same filters. Schedule it daily to get newly licensed sponsors."}, "maxItems": {"type": "integer", "description": "Stop after this many sponsors (caps the cost of a run)."}}}, "example": {"towns": ["London"], "routes": ["Skilled Worker"], "onlyNew": false, "maxItems": 50}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/eu-vat-number-validation": {"post": {"operationId": "eu_vat_number_validation", "summary": "VAT Validation API", "description": "Validate EU VAT numbers in bulk against the official VIES service, plus Norway (Brreg) and Switzerland (UID register): valid/invalid, company name, address and the VIES consultation number as audit proof. A member-state outage is reported as unavailable, never as invalid.", "tags": ["Business & tax"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"vatNumbers": {"type": "array", "description": "VAT numbers with country prefix, up to 100 per run. Spaces, dots and dashes are fine. EU: DE811569869, IE6388047V, EL... for Greece, XI for Northern Ireland. Norway: NO923609016MVA. Switzerland: CHE-116.281.710 MWST.", "items": {}}, "defaultCountry": {"type": "string", "description": "Optional 2-letter country code used for numbers given without a prefix, e.g. DE. Leave empty if every number has its prefix."}, "requesterVatNumber": {"type": "string", "description": "Optional. Your company's EU VAT number with prefix. VIES then returns an official consultation number per check, which you can keep as proof for a tax audit (EU numbers only)."}, "onlyNew": {"type": "boolean", "description": "Return only numbers whose status, name or address changed since the last run with the same Monitor ID (the first run returns all). Use it on a schedule to watch your suppliers or customers."}, "monitorId": {"type": "string", "description": "Name of the watch list for Only changes mode, e.g. suppliers-de. Each Monitor ID keeps its own memory."}}}, "example": {"vatNumbers": ["IE6388047V", "DE811569869", "NO923609016MVA", "CHE-116.281.710 MWST"], "onlyNew": false, "monitorId": "default"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/apify-store-trends-niche-finder": {"post": {"operationId": "apify_store_trends_niche_finder", "summary": "Apify Store Trends API", "description": "Niche Finder, Rising Actors", "tags": ["E-commerce & apps"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "rising = actors whose usage is growing (default). niche = for each search term, how crowded the Store is and whether there is room for a new actor. history = daily usage history of specific actors."}, "search": {"type": "array", "description": "Rising mode only. Optional keywords; only actors whose name, title or category match are returned (all words of one keyword must match; any keyword can match). Leave empty for the whole Store.", "items": {}}, "category": {"type": "string", "description": "Rising mode only. Optional Apify Store category in capitals, for example AI, ECOMMERCE, SOCIAL_MEDIA, LEAD_GENERATION, DEVELOPER_TOOLS. Empty means all categories."}, "minUsers30": {"type": "integer", "description": "Rising mode only. Ignore actors with fewer monthly users than this. Higher values remove noise from brand-new or tiny actors."}, "sortBy": {"type": "string", "description": "Rising mode only. momentum = how much faster the last 7 days grow than the 30-day average (above 1 means accelerating). users30Delta and users30DeltaPct = change in monthly users since the comparison day. users30 = biggest actors first."}, "lookbackDays": {"type": "integer", "description": "Rising mode only. Compare today with the archive snapshot about this many days ago. If the archive is younger, the oldest snapshot is used. Actors added to the archive later are compared with their own first snapshot (see comparedWith and f"}, "searchTerms": {"type": "array", "description": "Niche mode only, required there. Keywords describing a possible actor idea, for example tiktok, company register, pdf. You get one verdict row per term.", "items": {}}, "actors": {"type": "array", "description": "History mode only, required there. Actor IDs in the form username/name, for example apify/website-content-crawler or clockworks/tiktok-scraper.", "items": {}}, "limit": {"type": "integer", "description": "Maximum number of rows returned (1 to 1000). In niche mode it also limits how many top actors are listed per term."}, "onlyNew": {"type": "boolean", "description": "For monitoring in rising mode: output only actors not output before for this Monitor ID. The first run outputs everything. Ignored in niche and history modes."}, "monitorId": {"type": "string", "description": "Separate memory for each watch (used with only-new mode). Use a different ID per keyword, category or filter combination."}}}, "example": {"mode": "rising", "minUsers30": 10, "sortBy": "momentum", "lookbackDays": 30}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/price-drop-monitor": {"post": {"operationId": "price_drop_monitor", "summary": "Price Drop & Back in Stock Alert", "description": "Any Store Price Monitor", "tags": ["E-commerce & apps"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"productUrls": {"type": "array", "description": "Product pages from any online stores (Shopify, WooCommerce, Magento, BigCommerce and most shops with product data).", "items": {}}, "watchlistName": {"type": "string", "description": "Keeps price history per watchlist. Use different names for different product lists. Empty = derived from the URLs."}, "alertOn": {"type": "array", "description": "Changes that trigger an alert: price_drop, price_increase, back_in_stock, out_of_stock.", "items": {}}, "minDropPercent": {"type": "integer", "description": "Ignore price drops smaller than this percentage."}, "discordWebhookUrl": {"type": "string", "description": "Server Settings → Integrations → Webhooks → Copy URL."}, "slackWebhookUrl": {"type": "string", "description": "Slack app → Incoming Webhooks."}, "telegramBotToken": {"type": "string", "description": "Token from @BotFather (use with chat ID)."}, "telegramChatId": {"type": "string", "description": "User, group or channel ID for alerts."}, "webhookUrl": {"type": "string", "description": "Receives a JSON POST with the changes."}, "onlyChanges": {"type": "boolean", "description": "Dataset contains only products whose price or stock changed (cheaper on schedules)."}, "maxItems": {"type": "integer", "description": "Hard limit on dataset rows (and cost)."}, "proxyConfiguration": {"type": "object", "description": "Apify Proxy helps with stores that block servers."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}}}, "example": {"productUrls": ["https://www.allbirds.com/products/mens-tree-runners", "https://www.allbirds.com/products/womens-tree-runners", "https://www.allbirds.com/products/mens-wool-runners", "https://www.allbirds.com/products/mens-canvas-runner-nz", "https://www.allbirds.com/products/womens-canvas-runner-nz", "https://www.allbirds.com/products/mens-cruiser-terry", "https://www.allbirds.com/products/womens-cruiser-slip-on", "https://www.allbirds.com/products/mens-dasher-nz-light-burnt-olive"], "alertOn": ["price_drop", "back_in_stock"], "minDropPercent": 0, "onlyChanges": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/cheapest-price-finder": {"post": {"operationId": "cheapest_price_finder", "summary": "Product Price Checker", "description": "Cheapest Price Across Stores", "tags": ["E-commerce & apps"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"productUrls": {"type": "array", "description": "Product pages from any online stores. The actor reads the real price from each page and sorts all offers from cheapest to most expensive.", "items": {}}, "searchQuery": {"type": "string", "description": "Product name or model, e.g. 'Sony WH-1000XM5'. Product pages are searched in the stores below."}, "stores": {"type": "array", "description": "Store domains for the search, e.g. walmart.com, ebay.com, or any brand store. Some big retailers (Amazon, Target, Best Buy, Newegg) often block automated requests; those are reported, not billed. Empty = amazon.com, walmart.com, bestbuy.com", "items": {}}, "resultsPerStore": {"type": "integer", "description": "How many search results to check in each store."}, "convertTo": {"type": "string", "description": "All prices are also converted to this currency with official ECB rates (USD, EUR, GBP, ...)."}, "onlyInStock": {"type": "boolean", "description": "Skip offers marked out of stock."}, "maxItems": {"type": "integer", "description": "Hard limit on saved offers (and cost)."}, "onlyChanged": {"type": "boolean", "description": "Return only offers whose price or stock changed since the previous run with the same input (or the same monitorId), plus new pages. Unchanged offers are not saved and not billed. Every row gets changeType, previousPrice, priceChange and pri"}, "monitorId": {"type": "string", "description": "Optional name for this price watch, e.g. 'aeropress-eu'. Runs with the same monitorId share the remembered prices even if you add or remove URLs. Setting it also adds the change fields to every row (without filtering, unless 'Only changed o"}, "minChangePercent": {"type": "number", "description": "Price monitoring only: ignore price moves smaller than this percent (they count as unchanged and are not returned in onlyChanged mode). Small moves add up against the last reported price, so a slow drift is still reported once it passes the"}, "mapPrice": {"type": "number", "description": "Optional. Minimum advertised price in the 'Convert prices to' currency. Every row then gets mapPrice, belowMap (true when the converted price is under it), mapGap and mapGapPercent (positive = how far below MAP). Empty = no MAP check."}, "mapPrices": {"type": "object", "description": "Optional. Per-URL MAP prices that override mapPrice, e.g. {\"https://store.com/products/x\": 79.99}. Prices are in the 'Convert prices to' currency."}, "proxyConfiguration": {"type": "object", "description": "Off by default: direct requests with an honest User-Agent work best (Apify proxy IPs are often rate-limited by Shopify stores, HTTP 429). Turn it on only for a store that blocks direct requests."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}}}, "example": {"productUrls": ["https://www.allbirds.com/products/mens-tree-runners", "https://www.mvmt.com/products/odyssey-ii-ceramic-fusion-black-40mm-28000457", "https://www.ugmonk.com/products/ugmonk-utility-tote-olive"], "resultsPerStore": 3, "convertTo": "USD", "onlyInStock": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/shopify-store-products": {"post": {"operationId": "shopify_store_products", "summary": "Shopify Products JSON Scraper", "description": "Variants, Barcode, Discounts", "tags": ["E-commerce & apps"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"storeUrls": {"type": "array", "description": "Store home pages (https://www.allbirds.com), collection pages (https://store.com/collections/sale) or single product pages (https://store.com/products/handle = only that product). Any Shopify store with the standard storefront (headless sto", "items": {}}, "maxProductsPerStore": {"type": "integer", "description": "Stop after this many products in each store."}, "oneRowPerVariant": {"type": "boolean", "description": "Each size/color variant as its own row with SKU, barcode, price and stock (otherwise variants are nested in the product)."}, "onlyAvailable": {"type": "boolean", "description": "Skip sold-out products/variants."}, "onlyOnSale": {"type": "boolean", "description": "Keep only products with a compare-at (original) price higher than the price."}, "keywords": {"type": "array", "description": "Keep only products whose title, type, vendor or tags contain one of these words.", "items": {}}, "includeDescription": {"type": "boolean", "description": "Plain-text product description (first 2000 characters)."}, "maxItems": {"type": "integer", "description": "Hard limit on dataset rows (and cost)."}, "onlyChanges": {"type": "boolean", "description": "Return only products that are new, changed price (price_drop / price_up), went back in stock or out of stock, changed variants, or were removed since the last run with the same monitor ID. Unchanged products are not saved and not billed. Th"}, "monitorId": {"type": "string", "description": "Name of the memory used by monitoring mode. Use a different ID for each store list or schedule."}, "proxyConfiguration": {"type": "object", "description": "Optional Apify Proxy for stores that rate-limit servers."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}, "datasetMaxItems": {"type": "integer", "description": "Upper limit of unique values taken from the dataset, to keep the cost under control."}}}, "example": {"storeUrls": ["https://www.allbirds.com", "https://kith.com/collections/footwear"], "maxProductsPerStore": 30, "oneRowPerVariant": false, "onlyAvailable": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/central-bank-rates-api": {"post": {"operationId": "central_bank_rates_api", "summary": "Central Bank Rates API", "description": "Official central bank policy interest rates as JSON, no API key: Federal Reserve (target range + EFFR), ECB (deposit, MRO, MLF; all 21 euro countries), Bank of England, Bank of Canada, Riksbank, Danmarks Nationalbank, Norges Bank, Banco Central do Brasil, Central Bank of Iceland. Latest rate with last change date, hike/cut, 1-year change, decision history, recent decisions across banks, compare. Monitor mode returns only new rate decisions.", "tags": ["Finance & rates"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "latest = current rate of each bank with effective date, previous rate, hike/cut and 1-year change; history = every rate change of one or more banks (needs Country); decisions = all rate changes across banks in the last N days, newest first;"}, "country": {"type": "array", "description": "ISO codes of the bank's country: US, EA (euro area), GB, CA, SE, DK, NO, BR, IS. Euro member codes (DE, FR, IT, ES, ...) and names like Germany return the ECB row. UK and full names work. Empty = all banks. Required for history.", "items": {}}, "rate": {"type": "string", "description": "policy (default, each bank's headline rate). ECB also: deposit, mro, mlf. Denmark also: lending, current-account, discount. US also: effective (daily effective federal funds rate, history only)."}, "startDate": {"type": "string", "description": "For history: first date, YYYY-MM-DD. Default = full history."}, "endDate": {"type": "string", "description": "For history: last date, YYYY-MM-DD. Default today."}, "days": {"type": "integer", "description": "For decisions: how many days back to list rate changes (1-9000, default 365)."}, "sort": {"type": "string", "description": "For latest: country (default), rate (lowest first), rate_desc, recent (latest change first)."}, "limit": {"type": "integer", "description": "Maximum rows for history (newest kept). Between 1 and 20000."}, "onlyNew": {"type": "boolean", "description": "Return only rate changes newer than the last run with this Monitor ID (per bank and rate). Schedule it daily to get each hike or cut once."}, "monitorId": {"type": "string", "description": "Name of the watch for only-new mode, for example my-dashboard. Each Monitor ID keeps its own last dates."}}}, "example": {"mode": "latest", "country": ["US", "EA", "GB", "CA"], "days": 365, "sort": "country"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/europe-fuel-prices": {"post": {"operationId": "europe_fuel_prices", "summary": "Fuel Prices API", "description": "No API key. Diesel, petrol and LPG prices at fuel stations near any point in France, Spain and Italy (cheapest first, official government feeds) plus the official weekly pump-price averages for all 27 EU countries with history since 2005. Price monitor mode returns only changes.", "tags": ["Finance & rates"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "both = station prices near the point plus the weekly national averages; stations = only stations near the point (France, Spain, Italy); averages = only the official weekly averages per EU country."}, "latitude": {"type": "number", "description": "Latitude of the point to search around (WGS84), e.g. 48.8566 for Paris, 40.4168 for Madrid, 41.9028 for Rome. Station prices cover France, Spain and Italy."}, "longitude": {"type": "number", "description": "Longitude of the point to search around (WGS84), e.g. 2.3522 for Paris."}, "radiusKm": {"type": "number", "description": "Search radius around the point in kilometres, 0.5 to 50."}, "fuel": {"type": "string", "description": "Fuel to price and sort by: diesel, petrol95 (E5), petrol95_e10, petrol98, lpg, e85, cng, lng, diesel_premium, petrol_premium, adblue, hydrogen, or all (every fuel the station sells, sorted by distance). Every row also lists all fuels of the"}, "sortBy": {"type": "string", "description": "price = cheapest first (ties by distance); distance = nearest first."}, "maxStations": {"type": "integer", "description": "Maximum number of stations to return, 1 to 200."}, "averageCountries": {"type": "array", "description": "ISO country codes for the official EU Weekly Oil Bulletin averages (any of the 27 EU countries, plus EU for the EU-27 average and EA for the euro area). Use [\"ALL\"] for all. Leave empty in both mode to skip averages.", "items": {}}, "historyWeeks": {"type": "integer", "description": "Add the last N weekly prices to every average row (0 = none, up to 1,100 weeks back to 2005)."}, "onlyNew": {"type": "boolean", "description": "Return only stations whose price changed (price_down / price_up / new_station) and only new weekly averages since the last run with the same Monitor ID. The first run returns everything. Use it on a schedule."}, "monitorId": {"type": "string", "description": "Name of the watch list for Only changes mode, e.g. paris-diesel. Each Monitor ID keeps its own memory."}}}, "example": {"mode": "both", "latitude": 48.8566, "longitude": 2.3522, "radiusKm": 5}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/us-gas-prices-api": {"post": {"operationId": "us_gas_prices_api", "summary": "Gas Prices API", "description": "Official US gas prices as JSON, no API key: weekly retail regular, midgrade, premium gasoline and diesel prices (USD/gallon) for the US, 10 PADD regions, 9 states and 10 cities from the EIA survey, with week-over-week and year-over-year change, 52-week high/low, history since 1990 (weekly, monthly or yearly averages) and a trip fuel cost calculator. Monitor mode returns only new weeks. Usable from AI agents via MCP.", "tags": ["Finance & rates"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "latest = newest weekly price per area and fuel with weekly/yearly change and 52-week high/low; history = price series between startDate and endDate (weekly, or monthly/yearly averages); trip = fuel cost of a trip from distance and fuel econ"}, "areas": {"type": "array", "description": "US, PADD1..PADD5 (East Coast, Midwest, Gulf Coast, Rocky Mountain, West Coast), PADD1A/1B/1C, PADD5XCA, states CA CO FL MA MN NY OH TX WA, cities BOS CHI CLE DEN HOU LAX MIA NYC SFO SEA, or names like 'California' / 'New York City'. 'all' =", "items": {}}, "fuels": {"type": "array", "description": "regular, midgrade, premium, allGrades, diesel ('all' = every fuel). Empty = regular + diesel for latest, regular for history and trip. Diesel is published for US, PADD regions, CA and PADD5XCA.", "items": {}}, "sort": {"type": "string", "description": "latest mode: area order (default), cheapest first, most expensive first, or biggest weekly rise first."}, "startDate": {"type": "string", "description": "history mode: first week, YYYY-MM-DD (or YYYY / YYYY-MM). Default one year ago. Gasoline from 1990/1994, diesel from 1994."}, "endDate": {"type": "string", "description": "history mode: last week, YYYY-MM-DD. Default latest."}, "interval": {"type": "string", "description": "history mode: weekly survey values, or monthly / yearly averages of the weekly values."}, "distanceMiles": {"type": "number", "description": "trip mode: trip distance in miles (or use distanceKm)."}, "distanceKm": {"type": "number", "description": "trip mode: trip distance in kilometers (used when distanceMiles is empty)."}, "mpg": {"type": "number", "description": "trip mode: vehicle fuel economy in US mpg. Default 25 when litersPer100km is also empty."}, "litersPer100km": {"type": "number", "description": "trip mode: fuel economy in L/100 km (used when mpg is empty)."}, "limit": {"type": "integer", "description": "Maximum rows returned (1-20000). Default 1000."}, "onlyNew": {"type": "boolean", "description": "Return only rows not returned before for this Monitor ID, e.g. schedule weekly to get each new EIA release once."}, "monitorId": {"type": "string", "description": "Name of the monitor state used by onlyNew. Different IDs keep separate memories."}}}, "example": {"mode": "latest", "areas": ["US", "CA", "TX", "NYC"], "fuels": ["regular", "diesel"], "sort": "area"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/inflation-cpi-api": {"post": {"operationId": "inflation_cpi_api", "summary": "Inflation API", "description": "Inflation and CPI data by country as JSON, no API key: yearly inflation, CPI index, GDP, GDP growth, GDP per capita, unemployment, population and lending rate for 217 countries (World Bank, CC BY 4.0), plus monthly HICP inflation (yoy, mom, index) for 37 European countries from Eurostat, including the flash estimate. Adjust any amount for inflation between two years or months. Modes: latest, history, monthly, adjust. Monitor mode returns only new periods.", "tags": ["Finance & rates"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "latest = newest yearly value per country and indicator (EU countries also get the newest monthly HICP); history = one row per country and year; monthly = Eurostat HICP per month (EU/EEA/candidate countries); adjust = what an amount from one"}, "countries": {"type": "array", "description": "ISO2 (US, DE, BG), ISO3 (USA, BGR) or English names (Germany). Up to 50. Empty = US, DE, GB, JP, BG.", "items": {}}, "indicators": {"type": "array", "description": "For latest: inflation, cpi, gdp, gdpGrowth, gdpPerCapita, unemployment, population, interestRate (or the raw World Bank code, e.g. FP.CPI.TOTL.ZG). Empty = inflation.", "items": {}}, "indicator": {"type": "string", "description": "For history: one indicator key, e.g. inflation or gdpGrowth. Default inflation."}, "startYear": {"type": "integer", "description": "For history: first year (1960 or later). Default 10 years ago."}, "endYear": {"type": "integer", "description": "For history: last year. Default the latest year with data."}, "startMonth": {"type": "string", "description": "For monthly: first month YYYY-MM. Default 24 months back."}, "endMonth": {"type": "string", "description": "For monthly: last month YYYY-MM. Default the newest month."}, "amount": {"type": "number", "description": "For adjust: the money amount to convert, e.g. 100. Default 100."}, "country": {"type": "string", "description": "For adjust: one country, e.g. US or Germany. Default US."}, "fromYear": {"type": "integer", "description": "For adjust: the year of the original amount. Default 10 years before To year."}, "toYear": {"type": "integer", "description": "For adjust: the target year. Default the latest year with CPI data."}, "fromMonth": {"type": "string", "description": "For adjust with monthly precision (EU countries, HICP index): YYYY-MM."}, "toMonth": {"type": "string", "description": "For adjust with monthly precision (EU countries, HICP index): YYYY-MM."}}}, "example": {"mode": "latest", "countries": ["US", "DE", "BG"], "indicators": ["inflation", "unemployment"], "limit": 1000}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/mortgage-rates-api": {"post": {"operationId": "mortgage_rates_api", "summary": "Mortgage Rates API", "description": "Official mortgage rates as JSON, no API key: US 30-year and 15-year fixed (Freddie Mac PMMS, weekly since 1971), Canada 1/3/5-year conventional + prime (Bank of Canada), UK 2/3/5/10-year fixed and variable (Bank of England) and the cost of borrowing for house purchase in 21 euro countries by fixation period (ECB). Latest with change and 1-year change, history, cheapest-country compare. Monitor mode returns only new publications.", "tags": ["Finance & rates"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "latest = newest rate of every country/product with previous value, change and 1-year change; history = past observations of the chosen countries (needs Country); compare = one headline rate per country sorted cheapest first (US 30-year fixe"}, "country": {"type": "array", "description": "ISO country codes, for example US, GB, CA, DE, FR, ES, IT, NL. UK, EA (euro area = U2) and full names like Germany also work. Empty = all 25 (latest/compare). Required for history.", "items": {}}, "product": {"type": "array", "description": "Optional filter: 30y-fixed, 15y-fixed, 5-1-arm, 1y-fixed, 2y-fixed, 3y-fixed, 5y-fixed, 10y-fixed, 2y-fixed-95ltv, 2y-variable, tracker, all-fixation, floating-1y, 1-5y-fixed, 5-10y-fixed, over-10y-fixed, prime-rate, policy-rate. US: 30y-fi", "items": {}}, "startDate": {"type": "string", "description": "For history: first date, YYYY-MM-DD or YYYY-MM. Default = full history."}, "endDate": {"type": "string", "description": "For history: last date, YYYY-MM-DD or YYYY-MM. Default today."}, "frequency": {"type": "string", "description": "For history: native (weekly for US/Canada, monthly for UK/euro), monthly or yearly (last observation of each period)."}, "sort": {"type": "string", "description": "For latest: country (default), rate (cheapest first), rate_desc, change (biggest fall first)."}, "limit": {"type": "integer", "description": "Maximum rows returned for history (newest kept). Between 1 and 20000."}, "onlyNew": {"type": "boolean", "description": "Return only rates published after the last run with this Monitor ID (per country and product). Schedule it weekly to get each new Freddie Mac / Bank of Canada week and each new UK / ECB month once."}, "monitorId": {"type": "string", "description": "Name of the watch for only-new mode, for example my-calculator. Each Monitor ID keeps its own last dates."}}}, "example": {"mode": "latest", "country": ["US", "GB", "CA", "DE"], "frequency": "native", "sort": "country"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/treasury-yields-api": {"post": {"operationId": "treasury_yields_api", "summary": "Treasury Yields API", "description": "US Treasury yields as JSON, no API key: the daily par yield curve (1M to 30Y), real yields (TIPS), T-bill rates and long-term rates, with 10Y-2Y, 10Y-3M, 30Y-5Y and 2Y-3M spreads, an inversion flag, day-over-day change in basis points and full history since 1990. Modes: latest, one date (nearest previous business day on holidays), history range (daily, weekly or monthly), spreads, and inversion periods. Source: U.S. Department of the Treasury (public domain). Monitor mode returns only new business days.", "tags": ["Finance & rates"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "latest = the newest yield curve; date = one day (a holiday or weekend returns the previous business day and says so); history = every business day between Start and End date; spreads = spread time series only; inversion = periods when 10Y-2"}, "curve": {"type": "string", "description": "nominal = daily par yield curve (1M-30Y, since 1990); real = real yield curve / TIPS (5Y-30Y, since 2003); bills = T-bill bank discount and coupon equivalent rates (since 2002); longterm = long-term composite and 20Y CMT (since 2000). Sprea"}, "date": {"type": "string", "description": "For mode date: the day you want, YYYY-MM-DD, for example 2024-03-15."}, "startDate": {"type": "string", "description": "For history, spreads and inversion: first day, YYYY-MM-DD. Default 30 days before End date. Max range 40 years."}, "endDate": {"type": "string", "description": "For history, spreads and inversion: last day, YYYY-MM-DD. Default today."}, "maturities": {"type": "array", "description": "Optional filter, for example 2Y, 10Y, 3M, 30Y. Empty = every maturity of the curve.", "items": {}}, "frequency": {"type": "string", "description": "For history and spreads: daily (every business day), weekly (last business day of each week) or monthly (last business day of each month)."}, "limit": {"type": "integer", "description": "Maximum rows returned (newest kept when the range is longer). Between 1 and 20000."}, "onlyNew": {"type": "boolean", "description": "Return only business days newer than the last run with this Monitor ID. Schedule it daily to get each new Treasury curve once."}, "monitorId": {"type": "string", "description": "Name of the watch for only-new mode, for example my-dashboard. Each Monitor ID keeps its own last date."}}}, "example": {"mode": "history", "curve": "nominal", "frequency": "daily", "limit": 1000}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/company-hiring-signals-history": {"post": {"operationId": "company_hiring_signals_history", "summary": "Company Hiring Signals API", "description": "New Jobs, Closed Jobs, History", "tags": ["Jobs & hiring"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "top_hiring = companies ranked by hiring activity; companies = current numbers plus daily history for chosen companies; new_jobs = postings first seen after the archive baseline; closed_jobs = postings that disappeared (with days open); open"}, "sortBy": {"type": "string", "description": "Ranking for top_hiring mode: new postings, open postings, change in open postings, or closed postings over the lookback window."}, "minOpenJobs": {"type": "integer", "description": "Skip companies with fewer open jobs than this (top_hiring mode). Hides tiny boards."}, "lookbackDays": {"type": "integer", "description": "Compare today with this many days ago (top_hiring mode). The archive starts on 2026-11-03, so the maximum useful value is the number of days since then."}, "companies": {"type": "array", "description": "Company board slugs (for example stripe) or company names. Required in companies mode; optional filter in the job modes.", "items": {}}, "keywords": {"type": "array", "description": "Job modes only: keep postings whose title contains any of these words (case-insensitive). Empty = all titles.", "items": {}}, "location": {"type": "array", "description": "Job modes only: keep postings whose location contains any of these texts, for example Berlin or United States. Empty = all locations.", "items": {}}, "department": {"type": "array", "description": "Job modes only: keep postings in these departments, for example Sales or Engineering. Empty = all departments.", "items": {}}, "remoteOnly": {"type": "boolean", "description": "Job modes only: keep only postings marked as remote."}, "ats": {"type": "array", "description": "Limit to companies using these systems. Empty = all three.", "items": {}}, "since": {"type": "string", "description": "Job modes only: postings first seen (or closed) since this date, format YYYY-MM-DD. Empty = since the start of the archive."}, "limit": {"type": "integer", "description": "Maximum number of rows to return (1 to 1000). You pay per result."}, "onlyNew": {"type": "boolean", "description": "For alerts: in the job modes output only postings not reported before; in top_hiring and companies modes output only rows whose open, new or closed job counts changed since the last run with the same Monitor ID. The first run reports everyt"}, "monitorId": {"type": "string", "description": "Separate memory for each watch list (used with only-new mode). Use a different ID per list of companies or keywords."}}}, "example": {"mode": "top_hiring", "sortBy": "newJobs", "minOpenJobs": 5, "lookbackDays": 30}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/ats-jobs-aggregator": {"post": {"operationId": "ats_jobs_aggregator", "summary": "Company Job Postings API", "description": "Jobs from Workday, Greenhouse, Lever, Ashby, Workable and SmartRecruiters in one normalized schema.", "tags": ["Jobs & hiring"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"companies": {"type": "array", "description": "Leave EMPTY to search all 800+ indexed companies by Title keywords / Locations / Departments (search mode). Or one per line: a company name (Stripe, Scale AI), a careers URL (nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite, boards.gre", "items": {}}, "titleKeywords": {"type": "array", "description": "Keep only jobs whose title contains any of these words (e.g. engineer, sales). Empty = all jobs. With an empty company list this searches every indexed company.", "items": {}}, "excludeKeywords": {"type": "array", "description": "Drop jobs whose title contains any of these words (e.g. senior, intern).", "items": {}}, "locations": {"type": "array", "description": "Keep jobs whose location contains any of these (e.g. London, Germany, New York).", "items": {}}, "includeRemoteWithLocations": {"type": "boolean", "description": "When a location filter is set, still include remote jobs."}, "remoteOnly": {"type": "boolean", "description": "Keep only remote jobs."}, "departments": {"type": "array", "description": "Keep jobs whose department or team contains any of these (e.g. Engineering, Marketing).", "items": {}}, "postedWithinDays": {"type": "integer", "description": "Keep only jobs posted in the last N days. 0 = any date."}, "minSalary": {"type": "integer", "description": "Keep jobs whose maximum listed salary is at least this amount (jobs without salary are dropped). 0 = no filter."}, "maxSearchCompanies": {"type": "integer", "description": "Only when Companies is empty: how many best-matching companies (most matching open jobs first) are read live from their job boards. Higher = more results, longer run."}, "onlyNewJobs": {"type": "boolean", "description": "Remember jobs from previous runs with the same company list and return only new ones. Ideal for scheduled monitoring."}, "monitorId": {"type": "string", "description": "Optional name for this monitor, e.g. 'remote-data-jobs'. Runs with the same Monitor ID share their 'already seen' memory, so you can change filters or companies without getting old jobs again. Empty = memory per company list / search."}, "includeDescription": {"type": "boolean", "description": "Add the full plain-text job description."}, "includeHiringHistory": {"type": "boolean", "description": "Adds firstSeenAt, daysOpen and openBeforeIndex to every job, and a 7-day trend per company (open jobs now vs 7 days ago, new and closed postings) to RUN_SUMMARY. Comes from our own daily snapshots of Greenhouse, Lever and Ashby boards (sinc"}}}, "example": {"companies": ["https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite", "greenhouse:stripe", "lever:palantir", "ashby:ramp"], "includeRemoteWithLocations": true, "remoteOnly": false, "postedWithinDays": 0}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/platsbanken-sweden-jobs": {"post": {"operationId": "platsbanken_sweden_jobs", "summary": "Platsbanken Sweden Jobs Scraper", "description": "All job ads from Platsbanken (Arbetsförmedlingen, Sweden's public job board). No API key, no login, no proxy: official open API. Employer, org number, city, occupation, employment type, deadline, apply link and full text. Only-new mode for alerts.", "tags": ["Jobs & hiring"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"searchQueries": {"type": "array", "description": "Job titles, skills or keywords in English or Swedish, e.g. 'python developer', 'sjuksköterska', 'truck driver'. Empty = all jobs.", "items": {}}, "locations": {"type": "array", "description": "Cities, municipalities or regions, e.g. Stockholm, Göteborg, Malmö, Skåne. Empty = all of Sweden.", "items": {}}, "postedWithinDays": {"type": "integer", "description": "Only ads published in the last N days. 0 = any date."}, "remoteOnly": {"type": "boolean", "description": "Only ads that say the work can be done remotely."}, "employmentTypes": {"type": "array", "description": "Keep only these types. Empty = all.", "items": {}}, "englishAdsOnly": {"type": "boolean", "description": "Keep only ads written in English (useful for international candidates)."}, "includeDescription": {"type": "boolean", "description": "Add the full plain-text job description."}, "onlyNewJobs": {"type": "boolean", "description": "Return only ads not seen in previous runs with the same monitor ID. Ideal for daily alerts."}, "monitorId": {"type": "string", "description": "Name of the monitor for 'only new jobs' (use different IDs for different searches)."}, "maxItems": {"type": "integer", "description": "Hard limit on jobs saved (and paid for)."}}}, "example": {"searchQueries": ["developer"], "locations": ["Stockholm"], "postedWithinDays": 14, "remoteOnly": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/audio-podcast-transcriber": {"post": {"operationId": "audio_podcast_transcriber", "summary": "Audio Transcription", "description": "Audio transcription and speech to text with faster-whisper (tiny, base or small model, language auto-detect). Give mp3, m4a, wav, ogg or mp4 URLs or a public podcast RSS feed: one row per audio minute (text, start, end, language) plus the full TXT, SRT and VTT. Only-new mode for feeds.", "tags": ["Media, text & files"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"urls": {"type": "array", "description": "Direct links to audio or video files (mp3, m4a, wav, ogg, flac, mp4, webm, ...) or public podcast RSS feed URLs, or Apple Podcasts show links (podcasts.apple.com/.../id123; the public RSS feed is found automatically). For a feed the newest ", "items": {}}, "maxEpisodes": {"type": "integer", "description": "How many of the newest episodes to transcribe from each podcast RSS feed. Ignored for direct file URLs. Long episodes take long: about 1 hour of audio per few minutes of run time."}, "episodesSince": {"type": "string", "description": "Podcast feeds only: keep episodes published on or after this date (YYYY-MM-DD) or within a period like '30 days', '2 weeks' or '3 months'. Applied before Max episodes per feed. Empty = no date filter."}, "titleIncludes": {"type": "array", "description": "Podcast feeds only: transcribe only episodes whose title contains one of these texts (case-insensitive). * matches anything, e.g. interview*ceo. Empty = all titles.", "items": {}}, "titleExcludes": {"type": "array", "description": "Podcast feeds only: skip episodes whose title contains one of these texts (case-insensitive), e.g. trailer, rerun, best of.", "items": {}}, "model": {"type": "string", "description": "Speech recognition model (faster-whisper, runs on CPU inside the actor). tiny = fastest, base = good English quality at high speed (default), small = better accuracy and other languages, slower."}, "language": {"type": "string", "description": "Two-letter language code of the audio, for example en, de, es, fr, bg. Leave empty to detect the language automatically for each file."}, "vocabulary": {"type": "string", "description": "Names, brands or special terms spoken in the audio, comma separated, e.g. Apify, Kubernetes, Varna. Whisper uses them as a hint to spell them correctly. Max 400 characters. Empty = no hint."}, "maxMinutesPerFile": {"type": "integer", "description": "Transcribe only the first N minutes of each file or episode (0 = the whole file). Use it to limit cost on very long recordings. You pay per transcribed minute."}, "subtitleMaxChars": {"type": "integer", "description": "Max characters per subtitle line in the SRT and VTT files (2 lines per cue, max 7 seconds per cue, cut at sentence ends and pauses, timed from word timestamps). 42 is the broadcast standard; use 30-35 for vertical TikTok/Reels/Shorts videos"}, "onlyNew": {"type": "boolean", "description": "For monitoring feeds: skip every file or episode that was already transcribed in an earlier run with the same Monitor ID and return only new ones. The first run transcribes everything it is asked for. Each minute is paid for once."}, "monitorId": {"type": "string", "description": "Separate memory for each watch list (used with only-new mode). Use a different ID per podcast or feed list."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}}}, "example": {"urls": ["https://archive.org/download/childrensshortworks09_1010_librivox/childrensshortworks009_lionandthehare_ab.mp3"], "maxEpisodes": 1, "model": "base", "maxMinutesPerFile": 0}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/bulk-image-downloader": {"post": {"operationId": "bulk_image_downloader", "summary": "Bulk Image Downloader", "description": "URLs & Pages to ZIP", "tags": ["Media, text & files"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"urls": {"type": "array", "description": "Direct image (or file) links, one per line. Each is downloaded and stored with a public link. Leave empty if you use pages or a dataset.", "items": {}}, "pageUrls": {"type": "array", "description": "Web pages. Every image on the page is collected: <img> src, lazy data-src, the largest srcset size, og:image / twitter:image and links to image files. Small icons are filtered by Min width / Min height.", "items": {}}, "datasetId": {"type": "string", "description": "Optional. A dataset ID or dataset URL, for example the result of a product scraper. In the Integrations tab of another actor set it to {{resource.defaultDatasetId}}. Every image link in every item is downloaded."}, "imageFields": {"type": "array", "description": "Optional. Field names that hold the images, for example images, thumbnailUrl or media.url (dot paths and lists work). Empty = every field that looks like an image link is used.", "items": {}}, "nameField": {"type": "string", "description": "Optional. Dataset field used for file names, for example sku, asin, id or title. Files become <value>_1.jpg, <value>_2.jpg ... Set File naming to 'name' to use it."}, "datasetMaxItems": {"type": "integer", "description": "Upper limit of dataset items read, to keep the cost under control."}, "monitorId": {"type": "string", "description": "Optional. Any name, for example my-shop-images. Runs with the same monitor ID skip every URL stored in earlier runs, so a daily schedule downloads only new images. Empty = download everything every time."}, "fileTypes": {"type": "string", "description": "Images only skips links that turn out not to be images. All files stores any file type."}, "outputFormat": {"type": "string", "description": "Keep the original bytes or convert every image (transparent images get a white background in JPG). SVG and HEIC stay as they are."}, "maxWidth": {"type": "integer", "description": "Wider images are scaled down to this width, keeping the aspect ratio. 0 = no resize."}, "quality": {"type": "integer", "description": "Quality for converted JPG and WebP images (30-100)."}, "minWidth": {"type": "integer", "description": "Images narrower than this are skipped (icons, tracking pixels). 0 = keep all."}, "minHeight": {"type": "integer", "description": "Images lower than this are skipped. 0 = keep all."}, "dedupeByContent": {"type": "boolean", "description": "The same picture under different URLs (CDN sizes, mirrors) is stored once, detected by SHA-256 of the file content. Duplicates are not charged."}}}, "example": {"urls": ["https://www.gstatic.com/webp/gallery/1.jpg", "https://upload.wikimedia.org/wikipedia/commons/3/3a/Cat03.jpg"], "pageUrls": ["https://books.toscrape.com/"], "datasetMaxItems": 1000, "fileTypes": "images"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/image-pdf-ocr": {"post": {"operationId": "image_pdf_ocr", "summary": "Image to Text OCR", "description": "Scanned PDF, Per Line", "tags": ["Media, text & files"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"urls": {"type": "array", "description": "Direct links to images (png, jpg, webp, tiff, bmp, gif) or PDF files, scanned or digital. One result row is produced per image and per PDF page. Links must be public and point straight to the file.", "items": {}}, "languages": {"type": "array", "description": "Languages of the text in your images. Pick one, or several for mixed text (a little slower). Used only when a page has to be read by OCR.", "items": {}}, "outputMode": {"type": "string", "description": "lines = every text line with its confidence and bounding box. words = every single word with confidence and bounding box (bigger output)."}, "maxPagesPerPdf": {"type": "integer", "description": "Read at most this many pages from each PDF (from the first page). You pay per page, so this caps the cost of big documents."}, "forceOcr": {"type": "boolean", "description": "By default, PDF pages that already contain a text layer are read from it (fast, exact). Turn this on to run OCR on every page anyway, for example when the text layer is wrong."}, "onlyNew": {"type": "boolean", "description": "Skip every image or PDF URL that was already processed in an earlier run with the same Monitor ID. Use it for recurring jobs on a folder or feed of files. Each file is paid for once."}, "monitorId": {"type": "string", "description": "Separate memory for each watch list (used with only-new mode). Use a different ID per feed or customer."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}, "datasetMaxItems": {"type": "integer", "description": "Upper limit of unique values taken from the dataset, to keep the cost under control."}}}, "example": {"urls": ["https://www.gutenberg.org/cache/epub/11/pg11.cover.medium.jpg", "https://www.gutenberg.org/cache/epub/84/pg84.cover.medium.jpg", "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"], "languages": ["eng"], "outputMode": "lines", "maxPagesPerPdf": 20}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/google-trends-explorer": {"post": {"operationId": "google_trends_explorer", "summary": "Keyword Trends", "description": "Reliable Google Trends scraper: 57/57 test runs succeeded (Nov 2026), about 14 s per keyword. Drop-in compatible with apify/google-trends-scraper input and output. Interest over time, regions, related", "tags": ["Media, text & files"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"keywords": {"type": "array", "description": "Search terms to analyze, one per line. Any number of keywords; they can also be compared on one common scale.", "items": {}}, "geos": {"type": "array", "description": "Country or region codes such as US, GB, DE or US-CA. Leave empty for worldwide. Each keyword is analyzed for every location.", "items": {}}, "timeframe": {"type": "string", "description": "Period to analyze."}, "customTimeframe": {"type": "string", "description": "Overrides the time range. Format: YYYY-MM-DD YYYY-MM-DD, e.g. 2024-01-01 2024-12-31."}, "searchType": {"type": "string", "description": "Which Google search to analyze."}, "category": {"type": "string", "description": "Google Trends category ID as text, e.g. 7 for Finance. 0 or empty = all categories. Numbers are accepted by the code, the field itself is text so it matches apify/google-trends-scraper."}, "includeRegions": {"type": "boolean", "description": "Add interest by country, region or city."}, "regionResolution": {"type": "string", "description": "Detail of the regional breakdown. Auto uses countries for worldwide and regions for a country."}, "includeRelated": {"type": "boolean", "description": "Add top and rising related queries and topics."}, "maxRelatedItems": {"type": "integer", "description": "How many related queries and topics to keep in each list."}, "compareKeywords": {"type": "boolean", "description": "Adds comparedInterest (0-100) so all keywords are comparable, even more than Google's limit of 5."}, "language": {"type": "string", "description": "Interface language for names of regions and topics, e.g. en-US, de, es."}, "maxItems": {"type": "integer", "description": "Hard limit on rows saved (and paid for). 0 = no limit."}, "maxConcurrency": {"type": "integer", "description": "Keywords processed at the same time (capped at 5 to be gentle on Google; higher values from apify/google-trends-scraper inputs are accepted and capped). Lower is more reliable."}}}, "example": {"keywords": ["chatgpt", "claude ai", "gemini ai"], "geos": ["US"], "timeframe": "past_12_months", "searchType": "web"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/lemmy-posts-comments-scraper": {"post": {"operationId": "lemmy_posts_comments_scraper", "summary": "Lemmy Scraper", "description": "Scrape Lemmy posts, comments, community stats and keyword search from lemmy.world, lemmy.ml and any other instance. No API key, no login, no proxy: official open Lemmy API, so it does not break. Only-new mode for keyword alerts. $0.25 per 1000 results.", "tags": ["Media, text & files"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"instances": {"type": "array", "description": "Lemmy servers to read, as domains (lemmy.world, lemmy.ml, sh.itjust.works, feddit.org). Search and plain community names run on every instance listed.", "items": {}}, "communities": {"type": "array", "description": "Communities to scrape: a name (technology), name@instance (technology@lemmy.world) or a full community URL (https://lemmy.world/c/technology).", "items": {}}, "searchQueries": {"type": "array", "description": "Keywords to search in posts on every listed instance (brand names, products, topics). Combine with Only new results for a keyword monitor.", "items": {}}, "postUrls": {"type": "array", "description": "Single Lemmy post URLs (https://lemmy.world/post/12345). The post is saved, plus its comments when Include comments is on.", "items": {}}, "sort": {"type": "string", "description": "Order of posts for communities and searches. Use New with Only new results for monitoring."}, "includeComments": {"type": "boolean", "description": "Also save comments for every post. Each comment is one result row."}, "maxCommentsPerPost": {"type": "integer", "description": "Upper limit of comments saved for each post."}, "listCommunities": {"type": "boolean", "description": "Output community rows (name, title, subscribers, posts, comments, active users per month, NSFW, URL). Lists the most active communities of each instance, or the stats of the communities you entered."}, "maxItems": {"type": "integer", "description": "Hard limit on rows saved in total (posts + comments + communities), and the most you pay for."}, "onlyNew": {"type": "boolean", "description": "Monitoring mode: return only posts and comments not returned in earlier runs with the same Monitor ID."}, "monitorId": {"type": "string", "description": "Name of the memory used by monitoring mode. Use a different ID for each set of searches."}}}, "example": {"instances": ["lemmy.world"], "communities": ["technology"], "sort": "New", "includeComments": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/mastodon-hashtag-monitor": {"post": {"operationId": "mastodon_hashtag_monitor", "summary": "Mastodon Scraper", "description": "Mastodon scraper for hashtags, accounts, trending tags and links, and replies across several instances. No API key, no login, no proxy: official open Mastodon API. Only-new mode turns it into a brand and keyword monitor for the fediverse. $0.80 per 1000 results.", "tags": ["Media, text & files"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"instances": {"type": "array", "description": "Mastodon servers to read from, for example mastodon.social or fosstodon.org. Hashtag posts are read from each instance's public timeline, so more instances give wider coverage. Accounts without a server use the first instance.", "items": {}}, "hashtags": {"type": "array", "description": "Hashtags to read, with or without the # sign, for example python or opensource. Each hashtag is read on every instance listed above.", "items": {}}, "accounts": {"type": "array", "description": "Accounts whose public posts you want, as user@server (Gargron@mastodon.social) or a profile URL (https://mastodon.social/@Gargron). Boosts and replies are left out.", "items": {}}, "keywords": {"type": "array", "description": "Optional. Keep only posts whose text contains any of these words or phrases (not case sensitive). Mastodon has no public full-text search, so keywords filter the posts fetched from your hashtags and accounts.", "items": {}}, "language": {"type": "string", "description": "Optional. Keep only posts written in this language, for example en, de or bg. Empty = all languages."}, "maxItems": {"type": "integer", "description": "Hard limit on rows saved (and paid for): posts, replies and trend rows together. Posts are shared equally between the hashtags and accounts."}, "includeTrends": {"type": "boolean", "description": "Also save the trending hashtags and trending links of every instance, with their usage in the last days. Trend rows are a snapshot and are not affected by only-new mode."}, "includeLocalTimeline": {"type": "boolean", "description": "Also read the public local timeline of every instance (posts by that server's own users). Many servers require a login for this and are then skipped with a note in the run summary."}, "includeReplies": {"type": "boolean", "description": "Also save the public replies to each post. Each reply is one result."}, "maxRepliesPerPost": {"type": "integer", "description": "Replies saved for each post that has replies."}, "onlyNew": {"type": "boolean", "description": "Return only posts and replies not returned in earlier runs with the same monitor ID. Schedule the actor to track brands, keywords or hashtags."}, "monitorId": {"type": "string", "description": "Name of the memory used by monitoring mode. Use a different ID for each search you track."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}}}, "example": {"instances": ["mastodon.social"], "hashtags": ["python"], "maxItems": 50, "includeTrends": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/video-frame-extractor": {"post": {"operationId": "video_frame_extractor", "summary": "Video Frame Extractor", "description": "No Per-Video Fee", "tags": ["Media, text & files"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"videoUrls": {"type": "array", "description": "Direct links to video files (mp4, mov, webm, mkv, m4v) or Apify key-value store file URLs. Links must be public and point straight to the file. YouTube, TikTok, Instagram and Facebook page links are not supported and are skipped.", "items": {}}, "mode": {"type": "string", "description": "scenes = a frame at every scene change (ffmpeg scene detection). interval = one frame every N seconds. count = N evenly spaced frames. timestamps = exact times you list."}, "frameCount": {"type": "integer", "description": "Used in count mode: how many evenly spaced frames to extract per video (limited by Max frames per video)."}, "everySeconds": {"type": "number", "description": "Used in interval mode: extract one frame every this many seconds, starting at 0."}, "timestamps": {"type": "array", "description": "Used in timestamps mode: times to extract, as seconds (12.5) or HH:MM:SS (00:01:02.5). Times beyond the video end are skipped.", "items": {}}, "sceneThreshold": {"type": "number", "description": "Used in scenes mode: sensitivity from 0.01 to 1. Lower finds more scene changes (0.1 very sensitive), higher only hard cuts. 0.3 is a good default."}, "maxFramesPerVideo": {"type": "integer", "description": "Hard cap on frames per video (any mode). You pay per frame, so this caps the cost. Maximum 500."}, "format": {"type": "string", "description": "Image format of the extracted frames. jpg is smallest, png is lossless, webp is a good compromise."}, "width": {"type": "integer", "description": "Resize frames to this width, keeping the aspect ratio. Never upscales. 0 keeps the original size."}, "quality": {"type": "integer", "description": "Quality for jpg and webp, 1 to 100 (higher = better and bigger files). Ignored for png."}, "contactSheet": {"type": "boolean", "description": "Also create one tiled grid image per video with all frames and their timecodes (one extra result row of type contact_sheet). Handy for a quick overview or for sending one image to an AI vision model."}, "maxVideoMinutes": {"type": "integer", "description": "Skip videos longer than this many minutes. A safety guard against huge files and surprise cost."}, "onlyNew": {"type": "boolean", "description": "Skip every video URL already processed in an earlier run with the same Monitor ID and the same settings. Use it for recurring jobs on a folder or feed of videos. Each video is paid for once."}, "monitorId": {"type": "string", "description": "Separate memory for each watch list (used with only-new mode). Use a different ID per feed or customer."}}}, "example": {"videoUrls": ["https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4"], "mode": "count", "frameCount": 8, "everySeconds": 10}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/carbon-footprint-api": {"post": {"operationId": "carbon_footprint_api", "summary": "Carbon Footprint API", "description": "No API key. CO2e emissions calculator on the official UK government (DESNZ) conversion factors 2023-2026: flights by IATA code (haul, cabin class, radiative forcing, +8% routing uplift), cars by size/segment and fuel incl. EV and hybrid, fuels by litre/kWh/tonne/gallon, UK electricity with grid losses, hotel nights in 40 countries, rail, bus, taxi, ferry, freight tonne-km (truck, van, ship, rail, air). Every answer carries the factor ID, year, Scope 1/2/3 split and CO2/CH4/N2O split. Up to 100 activities per call. Usable from AI agents via MCP.", "tags": ["Other data"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "calculate = CO2e of your activities (one result row per activity); search = find official DESNZ factors by words (e.g. 'diesel litres', 'container ship', 'hotel japan') and get their factorId; categories = all factor categories with Scope, "}, "activities": {"type": "array", "description": "List of activities (max 100). Each object has a 'type': flight {from, to (IATA codes) or distanceKm, cabin: economy|premium_economy|business|first|average, passengers, roundTrip, radiativeForcing (default true)}; car {distance, unit: km|mil", "items": {}}, "query": {"type": "string", "description": "For mode=search: words that must all appear in the factor path, e.g. 'diesel litres', 'hotel japan', 'refrigerant R410A', 'waste landfill'."}, "scope": {"type": "string", "description": "For mode=search: only factors of this GHG Protocol scope. Empty = all scopes."}, "year": {"type": "string", "description": "Which official DESNZ factor set to use. latest = the newest published set (2026). Use an older year to match last year's report."}, "includeTotal": {"type": "boolean", "description": "For mode=calculate with 2+ activities: add one extra row with the total kgCO2e and the Scope 1/2/3 split of all activities."}, "limit": {"type": "integer", "description": "For mode=search: maximum number of factors returned."}, "onlyNew": {"type": "boolean", "description": "Monitor mode: return only activities/factors whose result is new or changed since the last run with the same Monitor ID (for example when DESNZ publishes a new factor set each June)."}, "monitorId": {"type": "string", "description": "Name of the saved state used by 'Only new or changed results'. Use one ID per scheduled report."}}}, "example": {"mode": "calculate", "activities": [{"type": "flight", "from": "LHR", "to": "JFK", "cabin": "economy", "roundTrip": true}, {"type": "car", "distance": 120, "unit": "km", "size": "medium", "fuel": "petrol"}, {"type": "electricity", "kwh": 1000}, {"type": "hotel", "country": "DE", "nights": 3}], "year": "latest", "includeTotal": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/clinical-trials": {"post": {"operationId": "clinical_trials", "summary": "Clinical Trials Search", "description": "Search ClinicalTrials.gov (official v2 API) by keyword, condition, intervention, sponsor or location. Returns NCT id, title, status, phases, enrollment, conditions, interventions, sponsor, dates and countries.", "tags": ["Research"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"query": {"type": "string", "description": "Free-text search"}, "condition": {"type": "string", "description": "Condition, e.g. diabetes"}, "intervention": {"type": "string", "description": "Drug or intervention, e.g. semaglutide"}, "sponsor": {"type": "string", "description": "Sponsor, e.g. Pfizer"}, "location": {"type": "string", "description": "Location, e.g. Germany"}, "status": {"type": "string", "description": "Overall status"}, "maxItems": {"type": "integer", "description": "Max results (1-50)"}}}, "example": {"condition": "obesity", "intervention": "semaglutide", "status": "RECRUITING", "maxItems": 10}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/academic-papers-search": {"post": {"operationId": "academic_papers_search", "summary": "Scientific Papers API", "description": "Search millions of research papers by keyword, author or DOI. No API key needed, no login, no proxy: official open APIs (OpenAlex, Crossref, arXiv). Title, authors, year, venue, abstract, citation count, DOI and open-access PDF link. Only-new mode for literature monitoring.", "tags": ["Research"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"queries": {"type": "array", "description": "Keywords or phrases to search in paper titles and abstracts, one per entry, e.g. 'retrieval augmented generation'. Each query is searched separately and results are de-duplicated.", "items": {}}, "author": {"type": "string", "description": "Only papers by this author, e.g. 'Geoffrey Hinton'. Can be combined with queries, or used alone to list an author's papers."}, "dois": {"type": "array", "description": "Look up specific papers by DOI, e.g. 10.1038/nature14539 (a https://doi.org/ link also works). Returns metadata, abstract and citation count for each.", "items": {}}, "fromYear": {"type": "integer", "description": "Only papers published in this year or later, e.g. 2022. Leave empty for no limit."}, "toYear": {"type": "integer", "description": "Only papers published in this year or earlier, e.g. 2025. Leave empty for no limit."}, "openAccessOnly": {"type": "boolean", "description": "Return only papers that have a free full-text version. Works with OpenAlex and arXiv results (Crossref does not report open access)."}, "sort": {"type": "string", "description": "relevance = best match first, citations = most cited first, newest = most recently published first."}, "source": {"type": "string", "description": "auto = OpenAlex first, falling back to Crossref and then arXiv if a source is unavailable. Or force one source."}, "maxItems": {"type": "integer", "description": "Maximum number of papers in total (you pay per paper returned)."}, "onlyNew": {"type": "boolean", "description": "For monitoring a topic: output only papers not output before for this Monitor ID. The first run outputs everything. Combine with sort 'newest' and a schedule."}, "monitorId": {"type": "string", "description": "Separate memory for each watch (used with only-new mode). Use a different ID per topic, author or filter combination."}}}, "example": {"queries": ["retrieval augmented generation"], "openAccessOnly": false, "sort": "relevance", "source": "auto"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/airports-flight-distance": {"post": {"operationId": "airports_flight_distance", "summary": "Airport Database API", "description": "Airport database + flight distance in one call: IATA/ICAO lookup, airports near a point, great-circle distance, flight time and CO2 per passenger (official UK DEFRA 2025 factors), plus live METAR/TAF. Open data, no API key, no proxy.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "distance = great-circle distance, bearing and estimated flight time for routes like JFK-LHR. lookup = full airport details by IATA/ICAO code. search = find airports by text, country or type. nearby = airports around a latitude/longitude. we"}, "routes": {"type": "array", "description": "Airport pairs as IATA or ICAO codes, for example JFK-LHR, SOF-VAR, LAX-NRT. Accepted separators: dash, 'to', '>' or space.", "items": {}}, "codes": {"type": "array", "description": "IATA (3 letters, e.g. JFK) or ICAO (4 characters, e.g. EGLL) airport codes. For weather mode, ICAO codes of any station also work. For airline mode: airline IATA (BA, W6), ICAO (BAW) codes or names (Ryanair).", "items": {}}, "query": {"type": "string", "description": "Text to find in airport name, city, code or keywords, for example 'heathrow', 'varna' or 'international'. Can be combined with country and type filters. In airline mode: text in the airline name, alias or callsign, e.g. 'wizz' or 'speedbird"}, "country": {"type": "string", "description": "Two-letter ISO country code, for example US, GB, BG, DE. Empty = all countries. In airline mode: ISO 2-letter code lists that country's airlines (e.g. BG)."}, "types": {"type": "array", "description": "Filter by type: large_airport, medium_airport, small_airport, heliport, seaplane_base, balloonport, closed. Empty = all open airport types in search mode, and large/medium/small airports in nearby mode.", "items": {}}, "latitude": {"type": "number", "description": "Latitude of the center point in decimal degrees, for example 43.2321 (Varna)."}, "longitude": {"type": "number", "description": "Longitude of the center point in decimal degrees, for example 27.8251 (Varna)."}, "radiusKm": {"type": "integer", "description": "Search radius around the point in kilometers."}, "scheduledServiceOnly": {"type": "boolean", "description": "Keep only airports that have scheduled passenger flights. Turn off to also see small airfields."}, "includeTaf": {"type": "boolean", "description": "Also return the latest TAF (terminal aerodrome forecast) for each station, raw text."}, "includeFaaDelays": {"type": "boolean", "description": "weather and lookup modes: add faaDelays to every US airport row - official FAA NAS status right now (ground stop, ground delay program with avg/max minutes, arrival/departure delays, closures). Non-US airports are unchanged. One extra free "}, "activeAirlinesOnly": {"type": "boolean", "description": "Airline mode: for name, query and country searches return only airlines marked active. Code lookups always return the best match (active first) and list other airlines that used the same code."}, "onlyNew": {"type": "boolean", "description": "For monitoring: weather mode returns only METARs that changed since the last run, other modes return only airports or routes not seen before for this Monitor ID. Each result is paid for once."}}}, "example": {"mode": "distance", "routes": ["JFK-LHR", "SOF-VAR", "LAX-NRT"], "codes": ["JFK", "LHR", "SOF"], "latitude": 43.2321}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/airport-report": {"post": {"operationId": "airport_report", "summary": "Airport Report", "description": "One call for one airport: airport record (IATA/ICAO, location, time zone), planes arriving and departing right now with airline and route, FAA delays and delay risk for US airports, METAR/TAF weather elsewhere. ~1-3 s.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"airport": {"type": "string", "description": "IATA or ICAO code, e.g. JFK or EGLL"}, "maxFlights": {"type": "integer", "description": "Max live flights"}}}, "example": {"airport": "JFK", "maxFlights": 10}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/official-geocoding-api": {"post": {"operationId": "official_geocoding_api", "summary": "Geocoding API", "description": "No API key, no login. Address to coordinates and back from 10 official government address registers: US Census, Canada NRCan, UK ONS postcodes, France BAN, Spain CartoCiudad, Netherlands BAG, Switzerland, Norway, Estonia, Poland. Open licences: you may store the results.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"addresses": {"type": "array", "description": "Addresses, postcodes or place names, up to 100 per run. The country is detected from the text (postcode format, city or country name). To force it, set Country below or prefix one line like 'FR: 8 bd du Port, 80000 Amiens'. Covered: US, CA,", "items": {}}, "coordinates": {"type": "array", "description": "Optional points as 'lat,lon', e.g. 52.3759,4.8975. Returns the nearest official address (FR, ES, NL, NO, PL), the nearest postcode (GB) or the county and census tract (US).", "items": {}}, "country": {"type": "string", "description": "Optional: one country for all lines (US, CA, GB, FR, ES, NL, CH, NO, EE, PL). Leave 'auto' to detect it per line."}, "includeCensus": {"type": "boolean", "description": "For US addresses also return state, county and census tract FIPS codes (GEOID) from the Census Bureau. Useful for demographics joins, insurance and lending (HMDA/CRA) work."}, "onlyNew": {"type": "boolean", "description": "Return only addresses whose match (coordinates, official address or ID) changed since the last run with the same Monitor ID. The first run returns all. Use it on a schedule to keep a customer or store address list clean."}, "monitorId": {"type": "string", "description": "Name of the address list for Only changes mode, e.g. stores-eu. Each Monitor ID keeps its own memory."}}}, "example": {"addresses": ["1600 Pennsylvania Ave NW, Washington, DC 20500", "Damrak 1, 1012 LG Amsterdam", "Calle Gran Via 28, Madrid", "10 Downing Street, London SW1A 2AA"], "coordinates": ["52.3759,4.8975", "40.4164,-3.7046"], "country": "auto", "includeCensus": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/live-flights-near-airport": {"post": {"operationId": "live_flights_near_airport", "summary": "Live Flights API", "description": "Live aircraft arriving at, leaving or flying over any airport: one row per plane with callsign, route (origin to destination), airline, aircraft type, altitude, speed, distance and ETA. No API key, no login, no proxy: ADSB.lol open data (ODbL) + adsbdb routes.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "airport = live aircraft within the radius of each airport, with arrival/departure/overflight and ETA; area = live aircraft around any latitude/longitude; flight = find specific aircraft by callsign, registration or ICAO hex code."}, "airports": {"type": "array", "description": "Airport mode: IATA (JFK, LHR, SOF) or ICAO (KJFK, EGLL, LBSF) codes, any country, up to 50. Empty = the example airports JFK, LHR and FRA.", "items": {}}, "radiusNm": {"type": "integer", "description": "Airport and area modes: how far around the airport or point to look (1-250 nm). 30 nm covers final approach and initial climb."}, "directions": {"type": "array", "description": "Airport mode filter. Any of: arrival, departure, overflight, likely arrival, likely departure, on ground, unknown. Empty = all aircraft.", "items": {}}, "includeOnGround": {"type": "boolean", "description": "Include aircraft that are taxiing or parked at the airport (they report 'ground' instead of an altitude)."}, "maxAltitudeFt": {"type": "integer", "description": "Optional: skip airborne aircraft above this altitude, e.g. 15000 to drop high overflights. Empty = no limit."}, "maxPerAirport": {"type": "integer", "description": "Upper limit of rows per airport or point (1-1000). Rows are sorted: arrivals by ETA first, then departures, then the rest by distance."}, "latitude": {"type": "string", "description": "Area mode: center latitude in decimal degrees, e.g. 50.03."}, "longitude": {"type": "string", "description": "Area mode: center longitude in decimal degrees, e.g. 8.57."}, "flights": {"type": "array", "description": "Flight mode: ATC callsigns (BAW123, THY3UG), registrations (N123AB, TC-JVK) or ICAO 24-bit hex codes (4baacb). Up to 100.", "items": {}}, "includeRoutes": {"type": "boolean", "description": "Look up each callsign's route and airline (adsbdb.com) and mark the flight as arrival/departure/overflight. Off = positions only (faster)."}, "maxRouteLookups": {"type": "integer", "description": "Upper limit of new callsign route lookups per run (0-1000). Routes are cached for 12 hours, so repeated runs are fast."}, "onlyNew": {"type": "boolean", "description": "Return only aircraft not returned in the last 6 hours by a run with the same Monitor ID. Schedule it every 5-15 minutes to get each new arrival or departure once."}, "monitorId": {"type": "string", "description": "Name of the saved state for Only new mode. Use a different ID for each watchlist."}}}, "example": {"mode": "airport", "airports": ["JFK", "LHR", "FRA"], "radiusNm": 30, "includeOnGround": true}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/us-schools-api": {"post": {"operationId": "us_schools_api", "summary": "Schools API", "description": "Official US K-12 school directory as JSON, no API key: 102,274 public and 22,510 private schools from NCES (2023-24) with NCES id, district, address, lat/lon, locale, grades, enrollment, teachers and student-teacher ratio. Search by name, city, state or ZIP, schools near a point or ZIP within N miles, one school by NCES id, all schools of a district with totals, bulk 50 queries. Usable from AI agents via MCP.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "search = filter by name/city/state/ZIP/district; near = schools within radiusMiles of lat/lon or a ZIP; school = one or more schools by NCES id; district = all schools of a district (LEAID or name) plus a summary row; bulk = up to 50 querie"}, "name": {"type": "string", "description": "Part of the school name, case-insensitive (search mode), e.g. Lincoln."}, "city": {"type": "string", "description": "City name (search mode), e.g. Austin."}, "state": {"type": "string", "description": "2-letter code or full name, e.g. CA or California."}, "zip": {"type": "string", "description": "5-digit ZIP. search: schools in this ZIP; near: centre of the radius."}, "lat": {"type": "number", "description": "near mode: centre latitude (use with lon instead of zip)."}, "lon": {"type": "number", "description": "near mode: centre longitude."}, "radiusMiles": {"type": "number", "description": "near mode: 0.1-50 miles, default 5. Rows are sorted by distanceMiles."}, "district": {"type": "string", "description": "District NCES LEAID (7 digits) or district name (search and district modes), e.g. 0622710 (Los Angeles Unified)."}, "ncesIds": {"type": "array", "description": "school mode: up to 50 NCES school ids (12-digit public NCESSCH or 8-character private PPIN).", "items": {}}, "schoolType": {"type": "string", "description": "public (default), private or all."}, "level": {"type": "array", "description": "Public schools only: elementary, middle, high, secondary, prekindergarten, other.", "items": {}}, "queries": {"type": "array", "description": "bulk mode: up to 50 objects, each one an input of another mode, e.g. {\"mode\":\"near\",\"zip\":\"10001\",\"radiusMiles\":1}. A failing query returns an error row; the others still answer.", "items": {}}, "limit": {"type": "integer", "description": "1-5000, default 100."}}}, "example": {"mode": "search", "name": "Lincoln", "state": "CA", "radiusMiles": 5}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/airport-delays-weather": {"post": {"operationId": "airport_delays_weather", "summary": "US Airport Delays & Weather API", "description": "US airport delays now and in history: FAA ground stops, ground delay programs, arrival/departure delays and closures, plus METAR/TAF weather and a delay-risk level per airport. No API key, no login, no proxy: official FAA and NOAA data.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "status = one row per chosen airport (normal or delayed) with FAA status, METAR, TAF outlook and delay risk; delays = every US airport with an active FAA delay or ground stop right now; history = past FAA delay events from our 5-minute archi"}, "airports": {"type": "array", "description": "US airport codes, IATA/FAA (JFK, ORD) or ICAO (KJFK, PHNL). Empty in status mode = every US airport with an active FAA delay/ground stop/closure right now plus the 10 busiest (always listed). Optional filter in delays/history/summary mode (", "items": {}}, "includeWeather": {"type": "boolean", "description": "Add current METAR (flight category, wind, gusts, visibility, ceiling) and a TAF outlook (worst flight category, thunderstorms, snow, strong wind) for each airport. Live modes only."}, "forecastHours": {"type": "integer", "description": "How many hours of the TAF forecast to use for the outlook and the delay-risk level (1-30)."}, "includeClosures": {"type": "boolean", "description": "FAA also lists long-running NOTAM closures that only restrict some traffic (for example non-scheduled general aviation). Off = only full closures are shown, so airlines' normal operations are not reported as closed."}, "days": {"type": "integer", "description": "History and summary modes: how many days back to look (1-365). Our archive started on 2026-11-08 and grows every 5 minutes."}, "eventTypes": {"type": "array", "description": "Optional filter for history and summary modes: ground_stop, ground_delay, arrival_departure_delay, airspace_flow, closure, deicing. Empty = all except partial closures.", "items": {}}, "onlyNew": {"type": "boolean", "description": "Live modes: return only airports whose FAA delay status changed since the last run with the same Monitor ID (new delay, longer delay, delay cleared). Schedule it every 5-15 minutes for alerts."}, "monitorId": {"type": "string", "description": "Name of the saved state for Only new mode. Use a different ID for each separate alert/watchlist."}}}, "example": {"mode": "status", "airports": ["ATL", "DFW", "DEN", "ORD", "LAX", "JFK", "LAS", "MCO", "MIA", "CLT"], "includeWeather": true, "forecastHours": 12}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/vehicle-recalls-vin-decoder": {"post": {"operationId": "vehicle_recalls_vin_decoder", "summary": "Vehicle Recalls & VIN Decoder API", "description": "Decode up to 50 VINs per call with the official NHTSA vPIC database (make, model, year, trim, engine, drive, plant, safety equipment) and attach the open NHTSA recalls for each vehicle. Also look up recalls by year, make and model. Fleet recall monitor mode returns only recalls not seen before. An NHTSA outage is reported as unavailable, never as no recalls.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"vins": {"type": "array", "description": "Vehicle identification numbers (17 characters, no letters I, O, Q), up to 50 per run. A malformed VIN returns a row with status invalid_format and is not sent upstream. VINs of US market vehicles decode best.", "items": {}}, "vehicles": {"type": "array", "description": "Optional. Vehicles to check for recalls without a VIN, up to 20 per run. Each entry is a text like 2019 honda accord (year, one-word make, model) or an object {\"year\": 2019, \"make\": \"land rover\", \"model\": \"range rover\"} for makes with sever", "items": {}}, "includeRecalls": {"type": "boolean", "description": "If on, every decoded VIN or vehicle gets its NHTSA recalls attached (recallCount and the recalls list). Turn off to get only the decoded specs. Always on in Only new recalls mode."}, "onlyNew": {"type": "boolean", "description": "Return one row per recall that was not seen before for this Monitor ID (the first run returns all current recalls). Use it on a schedule to watch a fleet or a dealer stock."}, "monitorId": {"type": "string", "description": "Name of the fleet watch list for Only new recalls mode, e.g. my-fleet. Each Monitor ID keeps its own memory."}}}, "example": {"vins": ["1HGCV1F35KA000001", "1FTFW1ET9DFC10312"], "vehicles": ["2019 honda accord", {"year": 2021, "make": "ford", "model": "f-150"}], "includeRecalls": true, "onlyNew": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/weather-alerts-api": {"post": {"operationId": "weather_alerts_api", "summary": "Weather Alerts API", "description": "Active official severe weather warnings as JSON, no API key: all US National Weather Service alerts (tornado, flood, winter storm, heat, fire weather, marine) and all German DWD warnings in one CAP-style schema: event, severity, urgency, certainty, onset, expires, headline, instructions, area and states. Filter by state, severity or event, or check up to 25 lat,lon points per call. Monitor mode returns only new warnings.", "tags": ["Travel, vehicles & places"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"mode": {"type": "string", "description": "area = every active warning in a country (US or DE), optionally only some states; point = warnings that cover one or more lat,lon locations (US and Germany)."}, "country": {"type": "string", "description": "For area: US (National Weather Service: states, territories, coastal waters) or DE (Germany, Deutscher Wetterdienst)."}, "states": {"type": "array", "description": "For area: optional state filter. US: TX, FL or Texas; Germany: BY, NW or Bavaria. Empty = whole country.", "items": {}}, "lat": {"type": "number", "description": "For point: latitude, e.g. 39.7392."}, "lon": {"type": "number", "description": "For point: longitude, e.g. -104.9903."}, "locations": {"type": "array", "description": "For point: up to 25 places as 'lat,lon', e.g. 29.7604,-95.3698. A place with no warning returns one row with activeAlerts 0.", "items": {}}, "minSeverity": {"type": "string", "description": "Only warnings at this level or higher (CAP severity: Minor < Moderate < Severe < Extreme). Empty = all."}, "events": {"type": "array", "description": "Only warnings whose event or headline contains one of these words, e.g. tornado, flood, winter, frost, Gewitter.", "items": {}}, "includeGeometry": {"type": "boolean", "description": "Add the warning polygon (GeoJSON) when the source has one (NWS storm-based warnings)."}, "includeTests": {"type": "boolean", "description": "Also return NWS test/keep-alive messages (normally hidden)."}, "limit": {"type": "integer", "description": "Maximum rows returned, most severe first. Between 1 and 5000."}, "onlyNew": {"type": "boolean", "description": "Return only warnings not returned before for this Monitor ID. Schedule every 5-15 minutes to get each new warning once."}, "monitorId": {"type": "string", "description": "Name of the watch for only-new mode, e.g. warehouse-texas. Each Monitor ID keeps its own memory."}}}, "example": {"mode": "area", "country": "US", "states": ["TX", "CA", "FL"], "includeGeometry": false}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/email-dns-dmarc-spf-check": {"post": {"operationId": "email_dns_dmarc_spf_check", "summary": "DMARC SPF MX Lookup API", "description": "Check the email DNS setup of up to 50 domains per call: MX records (do the hosts resolve), SPF (parsed, DNS lookup count against the limit of 10 with includes resolved), DMARC (policy, pct, reports, alignment), DKIM for your selectors and common ones, MTA-STS, TLS-RPT and BIMI, with a score, a grade and a fix for every issue. Change monitor mode returns only domains whose records changed. A resolver outage is reported as unavailable, never as no record.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"domains": {"type": "array", "description": "Domains to check, up to 50 per call, bare names like example.com (no https://, no mailbox). The API answers 400 above 50 (the Actor checks the first 50). Each row shows your input and the checked (lowercased) domain; duplicates are checked ", "items": {}}, "domain": {"type": "string", "description": "Optional: exactly one domain, e.g. example.com. It is never split: a value with spaces, commas, semicolons or new lines returns one invalid_format row. Use domains for a list."}, "dkimSelectors": {"type": "array", "description": "Optional. Your own DKIM selector names (the part before ._domainkey), up to 20 (the API answers 400 above 20 or for an invalid name), for example s1 or mimecast20240101. They are checked in addition to the common ones: google, selector1, se", "items": {}}, "onlyNew": {"type": "boolean", "description": "Return only domains whose MX, SPF, DMARC, DKIM, MTA-STS, TLS-RPT or BIMI records changed since the last run with this Monitor ID (the first run returns all). Use it on a schedule to watch your domains or your customers' domains."}, "monitorId": {"type": "string", "description": "Name of the watch list for the changed-domains mode, e.g. my-domains. Each Monitor ID keeps its own memory."}}}, "example": {"domains": ["google.com", "github.com", "example.com"], "dkimSelectors": ["selector1"], "onlyNew": false, "monitorId": "default"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/domain-security-report": {"post": {"operationId": "domain_security_report", "summary": "Domain Security Report", "description": "One call, one domain, every check: DMARC/SPF/DKIM/MX score with the exact DNS records to fix, security headers grade and SSL certificate days left, WHOIS/RDAP age, expiry and registrar, plus a merged top-issues list. ~1-2 s.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"domain": {"type": "string", "description": "Domain, e.g. example.com"}}}, "example": {"domain": "github.com"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/domain-whois-dns-lookup": {"post": {"operationId": "domain_whois_dns_lookup", "summary": "Domain WHOIS Lookup", "description": "Expiry, SSL Certificate", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"domains": {"type": "array", "description": "Domain names to look up, for example apify.com, github.com, wikipedia.org. URLs are accepted too (the host is used). Unregistered names come back as a row with available: true (domain availability check). Use the registered domain, not a su", "items": {}}, "includeDns": {"type": "boolean", "description": "Add A, AAAA, MX, NS, TXT, CAA records plus parsed SPF and DMARC policy for each domain."}, "includeSsl": {"type": "boolean", "description": "Connect to port 443 and add the TLS certificate issuer, valid-from and valid-until dates, days left and subject alternative names (SANs)."}, "includeRedirects": {"type": "boolean", "description": "Follow HTTP redirects from http://domain and report the chain and the final URL with status code. Uses an honest User-Agent and only GET requests."}, "expiringWithinDays": {"type": "integer", "description": "Keep only domains whose registration expires within this many days (e.g. 30 or 90) - find domains to renew or that may drop soon. 0 = keep all."}, "onlyNew": {"type": "boolean", "description": "For monitoring: output only domains whose registration (registrar, expiry, status, nameservers, DNSSEC), DNS records or SSL certificate changed since the last run with the same Monitor ID. The first run reports every domain as new. Each res"}, "monitorId": {"type": "string", "description": "Separate memory for each watch list (used with only-new mode). Use a different ID per list of domains."}, "trackIpChanges": {"type": "boolean", "description": "Off (default): changing A/AAAA IPs are ignored in change detection, because CDNs and load balancers rotate IPs on every run. Turn on to also flag IP changes (DNS hijack watch)."}, "maxConcurrency": {"type": "integer", "description": "How many domains are looked up in parallel. Lower it if a registry returns rate-limit errors."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}, "datasetMaxItems": {"type": "integer", "description": "Upper limit of unique values taken from the dataset, to keep the cost under control."}}}, "example": {"domains": ["apify.com", "github.com", "wikipedia.org"], "includeDns": true, "includeSsl": true, "includeRedirects": true}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/lighthouse-pagespeed-audit": {"post": {"operationId": "lighthouse_pagespeed_audit", "summary": "Lighthouse PageSpeed Checker", "description": "Core Web Vitals in Bulk", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"urls": {"type": "array", "description": "Pages to audit with Google Lighthouse. One result row is produced per URL and strategy. Use full http(s) links; a link without a scheme gets https:// added.", "items": {}}, "strategy": {"type": "string", "description": "mobile = Lighthouse default mobile emulation (slow 4G, mid-range phone). desktop = desktop preset. both = two audits per URL (two result rows)."}, "categories": {"type": "array", "description": "Lighthouse categories to run. Fewer categories make each audit a little faster. Categories not run come back as null. Leave empty for all four (performance, accessibility, best-practices, seo).", "items": {}}, "maxUrls": {"type": "integer", "description": "Audit at most this many URLs from the list (counted before strategies are applied). Caps the cost of big lists."}, "concurrency": {"type": "integer", "description": "How many audits run at the same time. Each one starts its own Chrome (about 500-800 MB). Keep 2 on the default 2 GB memory; raise it only together with the run memory. Very high values make timings less accurate. With the default 4 GB memor"}, "monitorId": {"type": "string", "description": "Turns on monitoring. Scores of every URL and strategy are remembered under this ID, and the next run with the same ID adds previousPerformance, performanceDelta and alert to each row. Use a different ID per site or customer. Leave empty for"}, "alertDrop": {"type": "integer", "description": "Monitoring only. A row gets alert=true when any audited category score fell by at least this many points (0-100 scale) compared with the previous run with the same Monitor ID."}, "onlyAlerts": {"type": "boolean", "description": "Monitoring only. Push only rows where alert is true (a score drop), so you pay and get notified only when something got worse. Scores are still remembered for the next run."}, "includeErrorRows": {"type": "boolean", "description": "Also write a row (billed) for URLs that could not be audited. Off by default: failed URLs are free and listed in RUN_SUMMARY."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}, "datasetMaxItems": {"type": "integer", "description": "Upper limit of unique values taken from the dataset, to keep the cost under control."}}}, "example": {"urls": ["https://example.com"], "strategy": "mobile", "maxUrls": 50, "concurrency": 2}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/link-preview-open-graph": {"post": {"operationId": "link_preview_open_graph", "summary": "Link Preview API", "description": "Get a link preview for up to 50 URLs per call: title, description, image, site name, favicon, type, language, canonical URL, author, published time, Twitter card, theme colour, oEmbed endpoint and JSON-LD types, read from the page's own Open Graph and meta tags. Image, PDF and video URLs get a preview from their headers. Private and internal addresses are refused. Monitor mode returns only URLs whose preview changed.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"urls": {"type": "array", "description": "Web page, image, PDF or video URLs to preview, up to 50 per run (http or https; a URL without a scheme gets https). Each URL returns one row. Private, internal and localhost addresses are refused with an error row.", "items": {}}, "onlyNew": {"type": "boolean", "description": "Return a row only for URLs whose preview (title, description, image, canonical, type) is new or changed since the last run with this Monitor ID. The first run returns every URL. Errors are always returned. Use it on a schedule to watch page"}, "monitorId": {"type": "string", "description": "Name of the watch list for Only changed previews mode, e.g. my-links. Each Monitor ID keeps its own memory."}}}, "example": {"urls": ["https://example.com", "https://en.wikipedia.org/wiki/Bulgaria"], "onlyNew": false, "monitorId": "default"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/osv-vulns": {"post": {"operationId": "osv_vulns", "summary": "Package Vulnerabilities", "description": "Known vulnerabilities for an open-source package version from OSV.dev (GitHub advisories, PyPI, npm, Go, Maven, crates.io...): id, CVE aliases, summary, severity, fixed versions, references. Plus what plain OSV lacks: CISA KEV 'exploited in the wild' flag + date, FIRST EPSS exploit probability, exploited/most-likely first, and one verified upgrade version that fixes every listed vuln. ~1 s.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"package": {"type": "string", "description": "Package name, e.g. lodash"}, "ecosystem": {"type": "string", "description": "npm, PyPI, Go, Maven, crates.io, RubyGems, NuGet"}, "version": {"type": "string", "description": "Version, e.g. 4.17.15 (empty = all known)"}, "purl": {"type": "string", "description": "Or a package URL, e.g. pkg:npm/lodash@4.17.15"}, "maxItems": {"type": "integer", "description": "Max results"}}}, "example": {"package": "lodash", "ecosystem": "npm", "version": "4.17.15", "maxItems": 50}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/security-headers-ssl-check": {"post": {"operationId": "security_headers_ssl_check", "summary": "Security Headers & SSL Certificate Checker API", "description": "Check the security headers and the SSL certificate of up to 50 websites per call. Grade A+ to F with a documented scoring table, every header with a verdict and an exact fix line (HSTS, CSP, frame protection, nosniff, Referrer-Policy, Permissions-Policy, COOP/CORP/COEP, cookie flags, information leaks), plus certificate issuer, SANs, days left, hostname match, trust verdict, key and signature, and the TLS versions the server accepts. Monitor mode returns only hosts whose grade dropped, whose header disappeared or whose certificate changed. A host that cannot be reached returns an error code, never a false 'header missing'.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"hosts": {"type": "array", "description": "Websites to check, up to 50 per run. Bare domains (example.com), hosts with a port (example.com:8443) or full URLs (https://example.com/) are accepted. Only the front page you give is requested; private, local and our own addresses are refu", "items": {}}, "host": {"type": "string", "description": "Optional shortcut for one website, same as a one-entry Hosts list. Handy for API calls with a single value."}, "url": {"type": "string", "description": "Optional shortcut for one URL, for example https://example.com/. Same as a one-entry Hosts list."}, "certWarnDays": {"type": "integer", "description": "A certificate that expires in fewer days than this is flagged as expiring soon (expiringSoon true, an issue is added, and monitor mode reports it). Between 1 and 365."}, "onlyNew": {"type": "boolean", "description": "Return only hosts whose grade dropped, whose security header disappeared, whose certificate was replaced or that entered the certificate warning window since the last run with this Monitor ID (the first run returns every host). Use it on a "}, "monitorId": {"type": "string", "description": "Name of the watch list for the changes-only mode, for example my-sites. Each Monitor ID keeps its own memory."}}}, "example": {"hosts": ["github.com", "example.com", "google.com"], "certWarnDays": 30, "onlyNew": false, "monitorId": "default"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/security-scan": {"post": {"operationId": "security_scan", "summary": "Security Scan", "description": "External security scan of a website: detects JavaScript libraries and frameworks with their versions and lists their known vulnerabilities (OSV.dev + CISA KEV exploited flag + fix version), security headers + SSL grade and DMARC/SPF spoofing grade. Passive, no intrusive probing. ~2-6 s.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"domain": {"type": "string", "description": "Website domain, e.g. example.com"}}}, "example": {"domain": "jquery.com"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/website-tech-stack-detector": {"post": {"operationId": "website_tech_stack_detector", "summary": "Tech Stack Lookup API", "description": "Detect Technologies, Bulk", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"domains": {"type": "array", "description": "Company websites to analyse, for example shopify.com, stripe.com or https://www.hubspot.com. Bare domains and full URLs are accepted; the homepage is fetched once per site. If left empty, five example sites are used.", "items": {}}, "includeDns": {"type": "boolean", "description": "Also read the domain's MX and TXT records (via DNS) to detect the email provider (Google Workspace, Microsoft 365, ...) and SPF senders."}, "includeCompanyInfo": {"type": "boolean", "description": "Add the page title, meta description, the company's own social profile links found on the homepage (LinkedIn, X/Twitter, Facebook, Instagram, YouTube, TikTok, GitHub) and the generator meta tag."}, "minConfidence": {"type": "integer", "description": "Only report technologies detected with at least this confidence (0-100). 50 hides weak single-signal guesses; use 100 for the strictest list."}, "maxConcurrency": {"type": "integer", "description": "How many websites are fetched in parallel. 10 is polite; lower it if sites rate-limit you."}, "monitorId": {"type": "string", "description": "Optional. If set, the actor remembers the technology set of each domain under this ID and outputs only domains whose stack changed since the last run, with added[] and removed[]. The first run with a new ID reports every domain as new. Leav"}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}, "datasetMaxItems": {"type": "integer", "description": "Upper limit of unique values taken from the dataset, to keep the cost under control."}}}, "example": {"domains": ["shopify.com", "stripe.com", "wordpress.org", "hubspot.com", "notion.so"], "includeDns": true, "includeCompanyInfo": true, "minConfidence": 50}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/url-to-markdown-llm": {"post": {"operationId": "url_to_markdown_llm", "summary": "Web Fetch", "description": "URL to Markdown", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"startUrls": {"type": "array", "description": "Web pages to convert to clean Markdown, one full URL per entry (http or https). Public pages only, no login pages.", "items": {}}, "maxPages": {"type": "integer", "description": "Hard limit on pages fetched in one run (also limits what you pay for). Failed pages count too."}, "crawl": {"type": "boolean", "description": "When on, the actor also follows links that stay on the same domain as each start URL, up to Max crawl depth and Max pages."}, "maxDepth": {"type": "integer", "description": "Only used when crawling. 1 = start URLs plus the pages they link to."}, "includeLinks": {"type": "boolean", "description": "Add the page links to every result as internalLinks and externalLinks lists (absolute URLs, up to 200 each)."}, "includeImages": {"type": "boolean", "description": "Add the page images (absolute URL and alt text, up to 100) to every result."}, "maxCharsPerPage": {"type": "integer", "description": "Cut markdown and text after this many characters to fit LLM context windows. 0 = no limit. The truncated flag tells you when a page was cut."}, "onlyNew": {"type": "boolean", "description": "For monitoring: return (and pay for) a page only when its content is new or changed since the last run with the same Monitor ID."}, "monitorId": {"type": "string", "description": "Separate memory for different watch lists (used with only-new mode)."}, "includeFailed": {"type": "boolean", "description": "When on, pages that fail (blocked by robots.txt, HTTP error, timeout) are also saved with an error message and are charged like normal results. When off, failures are only listed in the RUN_SUMMARY record."}, "timeoutSecs": {"type": "integer", "description": "Give up on a page that does not answer within this time."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}, "datasetField": {"type": "string", "description": "Optional. The item field that holds the value, for example website, url or videoUrl (dot paths like author.url work). Empty = detected automatically."}, "datasetMaxItems": {"type": "integer", "description": "Upper limit of unique values taken from the dataset, to keep the cost under control."}}}, "example": {"startUrls": ["https://en.wikipedia.org/wiki/Web_scraping", "https://blog.apify.com/introducing-x402-agentic-payments/"], "maxPages": 20, "crawl": false, "maxDepth": 1}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/web-page-report": {"post": {"operationId": "web_page_report", "summary": "Web Page Report", "description": "One call for one URL: the main content as clean Markdown for LLMs (word count, language, author) plus title, description, Open Graph image, site name and favicon. Respects robots.txt. ~1-3 s.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"url": {"type": "string", "description": "Page URL, e.g. https://en.wikipedia.org/wiki/Web_scraping"}, "maxChars": {"type": "integer", "description": "Cut the Markdown after this many characters"}}}, "example": {"url": "https://en.wikipedia.org/wiki/Web_scraping", "maxChars": 50000}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/website-intelligence": {"post": {"operationId": "website_intelligence", "summary": "Website Audit API", "description": "WHOIS Alerts, Tech Stack, DNS, TLS", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"domains": {"type": "array", "description": "Company websites to analyse, for example shopify.com, stripe.com or https://www.hubspot.com. Bare domains and full URLs are accepted; each site gets one combined row. If left empty, five example sites are used.", "items": {}}, "includeCompanyInfo": {"type": "boolean", "description": "Add the page title, meta description, generator tag and the company's own social profile links (LinkedIn, X/Twitter, Facebook, Instagram, YouTube, TikTok, GitHub) found on the homepage."}, "includeWhois": {"type": "boolean", "description": "Add registrar, creation and expiry dates, domain age, days to expiry, status, nameservers and DNSSEC from the official RDAP service. No personal registrant data is output."}, "includeTls": {"type": "boolean", "description": "Add the TLS certificate issuer, validity dates and days left until expiry."}, "includeRedirects": {"type": "boolean", "description": "Follow the http:// address of the domain and record the redirect chain and the final URL."}, "includeSitemap": {"type": "boolean", "description": "Read robots.txt and sitemap.xml and count the URLs listed (sitemap indexes are sampled and extrapolated). A light check, not a crawl."}, "includeLighthouse": {"type": "boolean", "description": "Run a real Google Lighthouse audit (headless Chrome) per site and add performance, accessibility, best-practices and SEO scores plus Core Web Vitals. Takes 20-60 seconds per site and needs at least 2 GB of memory, so it is off by default."}, "lighthouseStrategy": {"type": "string", "description": "Only used when Lighthouse is on: audit as a mobile phone (Lighthouse default throttling) or as a desktop."}, "includeScreenshot": {"type": "boolean", "description": "Take a PNG screenshot of the homepage (1366x768 viewport) with headless Chromium and add a download link to each row. Needs at least 2 GB of memory, so it is off by default."}, "minConfidence": {"type": "integer", "description": "Only report technologies detected with at least this confidence (0-100). 50 hides weak single-signal guesses; use 100 for the strictest list."}, "maxConcurrency": {"type": "integer", "description": "How many websites are scanned in parallel. 8 is polite; lower it if sites or RDAP servers rate-limit you."}, "monitorId": {"type": "string", "description": "Optional. If set, the actor remembers the last scan of each domain under this ID and outputs only domains that changed since then, with changes[] (added/removed technologies, MX or nameserver change, registrar or expiry change, TLS issuer c"}, "includeUnchanged": {"type": "boolean", "description": "Only used with a Monitor ID. Off = unchanged domains are skipped (and not charged). On = every domain is output, with an empty changes[] when nothing changed."}, "datasetId": {"type": "string", "description": "Optional. Pick a dataset (or paste its ID) to read the input from, for example the result of Google Maps Scraper. When this actor runs as an integration, the dataset of the triggering run is used automatically (payload.resource.defaultDatas"}}}, "example": {"domains": ["shopify.com", "stripe.com", "wordpress.org", "hubspot.com", "notion.so"], "includeCompanyInfo": true, "includeWhois": true, "includeTls": true}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/website-report": {"post": {"operationId": "website_report", "summary": "Website Report", "description": "One call for one website: technologies (CMS, frameworks, analytics, hosting) with versions, title/description/Open Graph image, security headers + SSL grade, and domain age from RDAP. ~2-5 s.", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"domain": {"type": "string", "description": "Website domain or URL, e.g. stripe.com"}}}, "example": {"domain": "stripe.com"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}, "/v1/website-screenshot-api": {"post": {"operationId": "website_screenshot_api", "summary": "Website Screenshot", "description": "URL to PNG, JPEG, PDF", "tags": ["Websites & security"], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"urls": {"type": "array", "description": "Public web pages to capture, one URL per entry (http or https; a bare domain like example.com also works). Login pages and private network addresses are not supported.", "items": {}}, "device": {"type": "string", "description": "Viewport preset: desktop 1366x768, desktop-hd 1920x1080, laptop 1280x800, tablet 820x1180 (2x), mobile 390x844 (3x, touch). The real Chromium browser is used for all of them."}, "fullPage": {"type": "boolean", "description": "Capture the whole scrollable page (up to Max height). Off = only the visible viewport, like a thumbnail."}, "format": {"type": "string", "description": "PNG (lossless), JPEG (smaller files, set JPEG quality) or PDF (one long page with backgrounds)."}, "jpegQuality": {"type": "integer", "description": "Only for JPEG: 10-100. Lower = smaller file."}, "viewportWidth": {"type": "integer", "description": "Optional. Overrides the device preset width (320-3840). 0 = use the preset."}, "viewportHeight": {"type": "integer", "description": "Optional. Overrides the device preset height (240-2160). 0 = use the preset."}, "maxHeight": {"type": "integer", "description": "Full-page captures are cut at this height (very long pages make huge files). The truncated flag tells you when this happened."}, "waitUntil": {"type": "string", "description": "When the page counts as loaded: load (default), domcontentloaded (fastest), networkidle (no network for 500 ms, best for heavy JavaScript apps)."}, "delayMs": {"type": "integer", "description": "Wait this long after loading before the capture (animations, charts, fonts). 0-30000."}, "waitForSelector": {"type": "string", "description": "Optional. Wait until this element is visible before the capture, for example #main or .chart-ready."}, "elementSelector": {"type": "string", "description": "Optional CSS selector. When set, only the first matching element is captured (PNG/JPEG), for example header, #pricing or .product-card."}, "hideCookieBanners": {"type": "boolean", "description": "Hide common cookie/consent popups (OneTrust, Cookiebot, Usercentrics, Didomi, Quantcast and more) with CSS so they do not cover the page. Nothing is clicked or accepted."}, "hideSelectors": {"type": "array", "description": "Optional CSS selectors to hide before the capture (chat widgets, sticky headers, ads), one per entry.", "items": {}}}}, "example": {"urls": ["https://apify.com", "https://en.wikipedia.org/wiki/Screenshot", "https://www.python.org"], "device": "desktop", "fullPage": true, "format": "png"}}}}, "responses": {"200": {"description": "Results", "content": {"application/json": {"schema": {"type": "object", "properties": {"ok": {"type": "boolean"}, "count": {"type": "integer"}, "items": {"type": "array", "items": {"type": "object"}}}}}}}, "401": {"description": "Missing key"}, "429": {"description": "Quota or rate limit"}, "502": {"description": "Source did not answer (not counted)"}}}}}, "components": {"securitySchemes": {"key": {"type": "apiKey", "in": "header", "name": "X-API-Key"}}}, "security": [{"key": []}]}