Hi {{firstName}},
Your {{plan}} report for {{company}} is ready.
\",\"mode\":\"merge\",\"items\":[{\"email\":\"ann@example.com\",\"firstName\":\"Ann\",\"company\":\"Acme Corp\",\"plan\":\"Pro\"},{\"email\":\"raj@example.org\",\"firstName\":\"Raj\",\"company\":\"Northwind\",\"plan\":\"Team\"}],\"dryRun\":true}`\nDocs: https://apify.com/cybermax/send-email", + "operationId": "remoteJobs", + "summary": "Remote Jobs Scraper: Remote OK & Jobicy Feed — Yonderlist", + "description": "Remote jobs scraper and aggregator: fresh remote job listings from Remote OK and Jobicy in one clean feed, with salary, location, job type, seniority, tags and apply links. Filter by keyword, country, salary and date; de-duplicated; monitor mode for new jobs only. $0.80 per 1,000 jobs.\n\nRuns the CyberMax \"Yonderlist\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~remote-jobs/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.0008 per job delivered.\nKey output fields: title, company, location, salaryMin, salaryMax, salaryCurrency, salaryPeriod, jobType, seniority, category, postedAt, ageDays, applyUrl, source, change.\nMinimal input: `{\"keywords\":[\"engineer\"],\"maxItems\":25}`\nDocs: https://apify.com/cybermax/remote-jobs", "tags": [ "CyberMax Actors" ], "externalDocs": { - "description": "Letterkeel on Apify Store", - "url": "https://apify.com/cybermax/send-email" + "description": "Yonderlist on Apify Store", + "url": "https://apify.com/cybermax/remote-jobs" }, - "x-apify-actor": "cybermax/send-email", + "x-apify-actor": "cybermax/remote-jobs", "parameters": [ { "$ref": "#/components/parameters/timeout" @@ -2897,343 +3261,1567 @@ "application/json": { "schema": { "type": "object", - "title": "Letterkeel — send email via SMTP, Resend, SendGrid, Mailgun or Postmark", + "title": "Yonderlist input", "properties": { - "provider": { - "title": "Provider", - "description": "How to send: your own SMTP server (Gmail/Google Workspace, Microsoft 365, Amazon SES, Zoho, Fastmail, any host) or the API of Resend, SendGrid, Mailgun or Postmark. Letterkeel never sends through shared servers: mail goes out from your account and your domain. Options: \"smtp\" = SMTP server, \"resend\" = Resend API, \"sendgrid\" = SendGrid API, \"mailgun\" = Mailgun API, \"postmark\" = Postmark API.", - "default": "smtp", - "enum": [ - "smtp", - "resend", - "sendgrid", - "mailgun", - "postmark" - ], - "type": "string" - }, - "from": { - "title": "From", - "description": "Sender, e.g. \"Acme AlertsHi {{firstName}},
Your {{plan}} report for {{company}} is ready.
" - ] - }, - "text": { - "title": "Plain-text body", - "description": "Plain-text body (or the only body). Same {{field}} placeholders as HTML.", - "type": "string" - }, - "mode": { - "title": "Mode", - "description": "auto = \"messages\" if given, else digest if a dataset/items are given, else one email to \"to\". single = one email to \"to\". messages = a list of different emails. merge = one personalised email per dataset row (mail merge). digest = one email containing all rows as a table + CSV (e.g. the results of another Actor run). Options: \"auto\" = Auto, \"single\" = Single email, \"messages\" = List of emails (messages), \"merge\" = Mail merge: one email per row, \"digest\" = Digest: all rows in one email.", - "default": "auto", - "enum": [ - "auto", - "single", - "messages", - "merge", - "digest" - ], - "type": "string", - "examples": [ - "merge" - ] - }, - "datasetId": { - "title": "Dataset ID (rows for merge/digest)", - "description": "An Apify dataset to read rows from, e.g. another run's defaultDatasetId. In an Apify webhook or integration use {{resource.defaultDatasetId}} to email the results of any Actor run.", - "type": "string" - }, - "items": { - "title": "Rows (inline)", - "description": "Rows given directly instead of a dataset: a JSON array of objects, e.g. [{\"email\": \"ann@acme.com\", \"firstName\": \"Ann\"}].", + "keywords": { + "title": "Keywords", + "description": "Jobs whose title, company, category or tags contain any of these, e.g. python, designer, customer success. Empty = all jobs.", "type": "array", "items": { "type": "string" }, "examples": [ [ - { - "email": "ann@example.com", - "firstName": "Ann", - "company": "Acme Corp", - "plan": "Pro" - }, - { - "email": "raj@example.org", - "firstName": "Raj", - "company": "Northwind", - "plan": "Team" - } + "engineer" ] ] }, - "toField": { - "title": "Recipient field (merge)", - "description": "Row field holding the recipient address. Default: the first of email, emailAddress, contactEmail, emails.0, Email.", - "type": "string" - }, - "nameField": { - "title": "Recipient name field (merge)", - "description": "Optional row field used as the recipient's display name, e.g. firstName or fullName.", - "type": "string" + "excludeKeywords": { + "title": "Exclude titles containing", + "description": "Optional, e.g. senior, intern, sales.", + "type": "array", + "items": { + "type": "string" + } }, - "digestFields": { - "title": "Digest columns", - "description": "Which fields to show in the digest table (dotted paths allowed, e.g. company.name). Default: the first 6 simple fields. The attached CSV always has every field.", + "locations": { + "title": "Locations", + "description": "Optional. Keep jobs open to any of these, e.g. USA, Europe, UK, LATAM, Anywhere. 'Anywhere' also matches worldwide-remote jobs.", "type": "array", "items": { "type": "string" } }, - "digestTitle": { - "title": "Digest heading", - "description": "Heading above the digest table. Default \"12 rows\" (\"12 new rows\" in monitor mode); placeholders {{count}}, {{total}}, {{date}}.", - "type": "string" + "jobTypes": { + "title": "Job types", + "description": "Optional, e.g. Full-Time, Contract, Part-Time, Internship (types are given by Jobicy listings).", + "type": "array", + "items": { + "type": "string" + } }, - "maxDigestRows": { - "title": "Max rows shown in the digest table", - "description": "Rows beyond this go only into the attached CSV.", - "default": 200, - "minimum": 1, - "maximum": 1000, + "minSalaryYearly": { + "title": "Minimum yearly salary", + "description": "Optional. Hourly and monthly salaries are converted to yearly for this check. Jobs without a salary stay in unless 'Only jobs with salary' is on.", + "minimum": 0, "type": "integer" }, - "attachCsv": { - "title": "Attach the rows as CSV (digest)", - "description": "Adds results-YYYY-MM-DD.csv with every row and field.", - "default": true, + "onlyWithSalary": { + "title": "Only jobs with salary", + "description": "Skip listings that publish no salary.", + "default": false, "type": "boolean" }, - "skipIfEmpty": { - "title": "Don't send an empty digest", - "description": "When there are no rows, send nothing (free).", - "default": true, - "type": "boolean" + "postedWithinDays": { + "title": "Posted within (days)", + "description": "Optional, e.g. 1 for the last 24 hours, 7 for the last week.", + "minimum": 1, + "type": "integer" }, "maxItems": { - "title": "Max rows read from the dataset", - "description": "Upper limit on rows read from the dataset.", - "default": 5000, + "title": "Max jobs", + "description": "Newest first.", + "default": 100, "minimum": 1, - "maximum": 50000, - "type": "integer" + "maximum": 5000, + "type": "integer", + "examples": [ + 25 + ] }, - "onlyNew": { - "title": "Monitor mode: only rows not emailed before", - "description": "Remembers what earlier runs with the same monitor name already emailed. Digest: the email contains only new rows (nothing is sent when there are none). Merge: each address (or idField) gets the email once. Put it on an Apify Schedule for daily \"what's new\" emails.", + "includeDescription": { + "title": "Include full description", + "description": "Adds the job description as plain text.", "default": false, "type": "boolean" }, - "monitorName": { - "title": "Monitor name", - "description": "Keeps separate memories for different schedules, e.g. \"new-leads\" and \"price-drops\".", - "default": "default", - "type": "string" - }, - "idField": { - "title": "Row ID field", - "description": "Field that identifies a row across runs (e.g. url or id). Default: digest compares whole rows; merge compares the recipient address.", - "type": "string" - }, - "messages": { - "title": "Messages (list of different emails)", - "description": "Send several different emails in one run: [{\"to\": \"a@x.com\", \"subject\": \"...\", \"html\": \"...\", \"text\": \"...\", \"cc\": \"...\", \"bcc\": \"...\", \"replyTo\": \"...\", \"attachments\": [{\"filename\": \"a.txt\", \"text\": \"...\"}]}]. Messages with problems are skipped for free and reported.", + "sources": { + "title": "Job boards", + "description": "Both by default. Allowed values: \"remoteok\" = Remote OK, \"jobicy\" = Jobicy.", "type": "array", "items": { + "enum": [ + "remoteok", + "jobicy" + ], "type": "string" } }, - "variables": { - "title": "Variables", - "description": "Extra values for {{placeholders}} in every email, e.g. {\"product\": \"Acme\"}.", - "type": "object" - }, - "sendSeparately": { - "title": "Send separately to each \"to\" address", - "description": "One email per address instead of one email with everyone in To (recipients don't see each other).", + "monitor": { + "title": "Monitor mode: new jobs only", + "description": "For scheduled runs. Returns only jobs not returned in earlier monitor runs with the same filters. Nothing new = nothing charged.", "default": false, "type": "boolean" }, - "cc": { - "title": "Cc", - "description": "Comma-separated addresses.", - "type": "string" - }, - "bcc": { - "title": "Bcc", - "description": "Comma-separated addresses (in merge mode added to every email, e.g. a CRM dropbox).", - "type": "string" - }, - "replyTo": { - "title": "Reply-To", - "description": "Where replies go, if not the From address.", - "type": "string" - }, - "attachments": { - "title": "Attachments", - "description": "Files added to every email: {\"filename\": \"report.pdf\", \"url\": \"https://...\"}, {\"key\": \"OUTPUT\", \"filename\": \"report.pdf\"} (a record from the key-value store set below, e.g. a PDF or screenshot made by another Actor), {\"filename\": \"a.txt\", \"text\": \"...\"} or {\"filename\": \"a.png\", \"contentBase64\": \"...\"}. 20 MB total.", - "type": "array", - "items": { - "type": "string" - } - }, - "keyValueStoreId": { - "title": "Key-value store for attachments", - "description": "An Apify key-value store to read attachment records from (e.g. another run's defaultKeyValueStoreId holding a PDF, screenshot or report). Attachments given as {\"key\": \"OUTPUT\", \"filename\": \"report.pdf\"} are read from here.", - "type": "string" + "monitorKey": { + "title": "Alert name", + "description": "Optional name for this alert's saved state.", + "type": [ + "string", + "null" + ] + } + } + }, + "example": { + "keywords": [ + "engineer" + ], + "maxItems": 25 + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: title, company, location, salaryMin, salaryMax, salaryCurrency, salaryPeriod, jobType, seniority, category, postedAt, ageDays, applyUrl, source, change" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } + }, + "/v2/acts/cybermax~sec-insider-tracker/run-sync-get-dataset-items": { + "post": { + "operationId": "secInsiderTracker", + "summary": "Insider Trading Tracker: SEC Form 4 API — Insidewell", + "description": "See which insiders just bought or sold their own stock. SEC Form 4 insider trading tracker and API: open-market trades from EDGAR as clean JSON for your watchlist or the whole market, cluster-buy flags and daily new-trade alerts. Public data, not advice. $0.004 per trade.\n\nRuns the CyberMax \"Insidewell\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~sec-insider-tracker/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.004 per insider transaction; $0.015 per cluster buy signal.\nKey output fields: issuer.ticker, issuer.name, owner.name, owner.officerTitle, owner.isDirector, transactionDate, transactionCode, acquiredDisposedCode, shares, pricePerShare, totalValueUsd, sharesOwnedAfter, clusterBuy, clusterInsiderCount, filedAt, filingUrl, change.\nMinimal input: `{\"maxItems\":5,\"maxTransactions\":2,\"tickers\":[\"AAPL\",\"NVDA\"]}`\nDocs: https://apify.com/cybermax/sec-insider-tracker", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Insidewell on Apify Store", + "url": "https://apify.com/cybermax/sec-insider-tracker" + }, + "x-apify-actor": "cybermax/sec-insider-tracker", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "SEC Insider Trading Tracker input", + "properties": { + "tickers": { + "title": "Watchlist (tickers or CIKs)", + "description": "US stock tickers to track (e.g. AAPL, TSLA). A purely numeric entry is treated as an SEC CIK (e.g. 320193 for Apple). Leave empty (or enable 'Track whole market' below) to get the latest Form 4 filings for every company instead of a watchlist.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "trackWholeMarket": { + "title": "Track whole market (ignore watchlist)", + "description": "If on, pulls the newest Form 4 filings across all US-listed issuers instead of only the tickers above. Good for a general insider-buying feed; use a watchlist instead if you only care about specific stocks.", + "default": false, + "type": "boolean" + }, + "maxItems": { + "title": "Max filings to fetch", + "description": "Upper bound on how many Form 4 filings to download and parse in this run. The prefilled 5 gives a fast, cheap first try; the default when omitted is 200.", + "default": 200, + "minimum": 1, + "maximum": 5000, + "type": "integer", + "examples": [ + 5 + ] + }, + "maxTransactions": { + "title": "Max transactions to return", + "description": "Stop after returning this many transactions (newest first); 0 = no limit. Useful to cap cost. In monitor mode, transactions over the cap are returned on the next run.", + "default": 0, + "minimum": 0, + "type": "integer", + "examples": [ + 2 + ] + }, + "lookbackDays": { + "title": "Lookback window (days)", + "description": "Only include filings whose transaction date is within this many days of today. Applies to watchlist mode; whole-market mode is naturally limited to the latest filings.", + "default": 14, + "minimum": 1, + "maximum": 365, + "type": "integer" + }, + "onlyOpenMarket": { + "title": "Only open-market buys/sells (codes P and S)", + "description": "Skip option exercises, grants, gifts and other non-open-market transaction codes, keeping only code P (open-market purchase) and S (open-market sale) — the transactions most investors actually care about.", + "default": true, + "type": "boolean" + }, + "minTransactionValueUsd": { + "title": "Minimum transaction value (USD)", + "description": "Drop transactions worth less than this (shares x price). Set to 0 to keep everything.", + "default": 10000, + "minimum": 0, + "type": "integer" + }, + "flagClusterBuys": { + "title": "Flag cluster insider buying", + "description": "Mark a transaction as a cluster buy when 2 or more different insiders at the same company bought on the open market within the cluster window below — a signal some investors watch for.", + "default": true, + "type": "boolean" + }, + "clusterWindowDays": { + "title": "Cluster window (days)", + "description": "Window used to detect cluster buying at the same company.", + "default": 7, + "minimum": 1, + "maximum": 30, + "type": "integer" + }, + "monitor": { + "title": "Monitor mode: only new trades since last run", + "description": "Remembers which transactions this watchlist already returned (by SEC accession number + transaction index) and only returns new ones, plus earlier trades that have just become part of a cluster buy (change: \"changed\"). Unchanged trades are not returned and not charged. The first monitor run returns everything as \"new\". Ideal for a daily schedule.", + "default": false, + "type": "boolean" + }, + "monitorKey": { + "title": "Monitor state name (optional)", + "description": "Name for this watchlist's saved state, so several watchlists can be monitored separately (e.g. \"tech-watchlist\"). Empty = derived automatically from the watchlist and filters. Use a new name to start fresh.", + "type": "string" + } + } + }, + "example": { + "maxItems": 5, + "maxTransactions": 2, + "tickers": [ + "AAPL", + "NVDA" + ] + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: issuer.ticker, issuer.name, owner.name, owner.officerTitle, owner.isDirector, transactionDate, transactionCode, acquiredDisposedCode, shares, pricePerShare, totalValueUsd, sharesOwnedAfter, clusterBuy, clusterInsiderCount, filedAt, filingUrl, change" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } + }, + "/v2/acts/cybermax~send-email/run-sync-get-dataset-items": { + "post": { + "operationId": "sendEmail", + "summary": "Send Email API: SMTP, Resend & SendGrid — Letterkeel", + "description": "Send email to anyone from Apify runs, webhooks and AI agents, from your own domain. Email sender for SMTP, Resend, SendGrid, Mailgun and Postmark: bulk mail merge from datasets, result digests with CSV, attachments, per-recipient status. $0.001 per email; failures free.\n\nRuns the CyberMax \"Letterkeel\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~send-email/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.001 per email sent.\nKey output fields: ok, to, subject, messageId, charged, error, mode, sentAt.\nMinimal input: `{\"from\":\"Acme AlertsHi {{firstName}},
Your {{plan}} report for {{company}} is ready.
\",\"mode\":\"merge\",\"items\":[{\"email\":\"ann@example.com\",\"firstName\":\"Ann\",\"company\":\"Acme Corp\",\"plan\":\"Pro\"},{\"email\":\"raj@example.org\",\"firstName\":\"Raj\",\"company\":\"Northwind\",\"plan\":\"Team\"}],\"dryRun\":true}`\nDocs: https://apify.com/cybermax/send-email", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Letterkeel on Apify Store", + "url": "https://apify.com/cybermax/send-email" + }, + "x-apify-actor": "cybermax/send-email", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Letterkeel — send email via SMTP, Resend, SendGrid, Mailgun or Postmark", + "properties": { + "provider": { + "title": "Provider", + "description": "How to send: your own SMTP server (Gmail/Google Workspace, Microsoft 365, Amazon SES, Zoho, Fastmail, any host) or the API of Resend, SendGrid, Mailgun or Postmark. Letterkeel never sends through shared servers: mail goes out from your account and your domain. Options: \"smtp\" = SMTP server, \"resend\" = Resend API, \"sendgrid\" = SendGrid API, \"mailgun\" = Mailgun API, \"postmark\" = Postmark API.", + "default": "smtp", + "enum": [ + "smtp", + "resend", + "sendgrid", + "mailgun", + "postmark" + ], + "type": "string" + }, + "from": { + "title": "From", + "description": "Sender, e.g. \"Acme AlertsHi {{firstName}},
Your {{plan}} report for {{company}} is ready.
" + ] + }, + "text": { + "title": "Plain-text body", + "description": "Plain-text body (or the only body). Same {{field}} placeholders as HTML.", + "type": "string" + }, + "mode": { + "title": "Mode", + "description": "auto = \"messages\" if given, else digest if a dataset/items are given, else one email to \"to\". single = one email to \"to\". messages = a list of different emails. merge = one personalised email per dataset row (mail merge). digest = one email containing all rows as a table + CSV (e.g. the results of another Actor run). Options: \"auto\" = Auto, \"single\" = Single email, \"messages\" = List of emails (messages), \"merge\" = Mail merge: one email per row, \"digest\" = Digest: all rows in one email.", + "default": "auto", + "enum": [ + "auto", + "single", + "messages", + "merge", + "digest" + ], + "type": "string", + "examples": [ + "merge" + ] + }, + "datasetId": { + "title": "Dataset ID (rows for merge/digest)", + "description": "An Apify dataset to read rows from, e.g. another run's defaultDatasetId. In an Apify webhook or integration use {{resource.defaultDatasetId}} to email the results of any Actor run.", + "type": "string" + }, + "items": { + "title": "Rows (inline)", + "description": "Rows given directly instead of a dataset: a JSON array of objects, e.g. [{\"email\": \"ann@acme.com\", \"firstName\": \"Ann\"}].", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + { + "email": "ann@example.com", + "firstName": "Ann", + "company": "Acme Corp", + "plan": "Pro" + }, + { + "email": "raj@example.org", + "firstName": "Raj", + "company": "Northwind", + "plan": "Team" + } + ] + ] + }, + "toField": { + "title": "Recipient field (merge)", + "description": "Row field holding the recipient address. Default: the first of email, emailAddress, contactEmail, emails.0, Email.", + "type": "string" + }, + "nameField": { + "title": "Recipient name field (merge)", + "description": "Optional row field used as the recipient's display name, e.g. firstName or fullName.", + "type": "string" + }, + "digestFields": { + "title": "Digest columns", + "description": "Which fields to show in the digest table (dotted paths allowed, e.g. company.name). Default: the first 6 simple fields. The attached CSV always has every field.", + "type": "array", + "items": { + "type": "string" + } + }, + "digestTitle": { + "title": "Digest heading", + "description": "Heading above the digest table. Default \"12 rows\" (\"12 new rows\" in monitor mode); placeholders {{count}}, {{total}}, {{date}}.", + "type": "string" + }, + "maxDigestRows": { + "title": "Max rows shown in the digest table", + "description": "Rows beyond this go only into the attached CSV.", + "default": 200, + "minimum": 1, + "maximum": 1000, + "type": "integer" + }, + "attachCsv": { + "title": "Attach the rows as CSV (digest)", + "description": "Adds results-YYYY-MM-DD.csv with every row and field.", + "default": true, + "type": "boolean" + }, + "skipIfEmpty": { + "title": "Don't send an empty digest", + "description": "When there are no rows, send nothing (free).", + "default": true, + "type": "boolean" + }, + "maxItems": { + "title": "Max rows read from the dataset", + "description": "Upper limit on rows read from the dataset.", + "default": 5000, + "minimum": 1, + "maximum": 50000, + "type": "integer" + }, + "onlyNew": { + "title": "Monitor mode: only rows not emailed before", + "description": "Remembers what earlier runs with the same monitor name already emailed. Digest: the email contains only new rows (nothing is sent when there are none). Merge: each address (or idField) gets the email once. Put it on an Apify Schedule for daily \"what's new\" emails.", + "default": false, + "type": "boolean" + }, + "monitorName": { + "title": "Monitor name", + "description": "Keeps separate memories for different schedules, e.g. \"new-leads\" and \"price-drops\".", + "default": "default", + "type": "string" + }, + "idField": { + "title": "Row ID field", + "description": "Field that identifies a row across runs (e.g. url or id). Default: digest compares whole rows; merge compares the recipient address.", + "type": "string" + }, + "messages": { + "title": "Messages (list of different emails)", + "description": "Send several different emails in one run: [{\"to\": \"a@x.com\", \"subject\": \"...\", \"html\": \"...\", \"text\": \"...\", \"cc\": \"...\", \"bcc\": \"...\", \"replyTo\": \"...\", \"attachments\": [{\"filename\": \"a.txt\", \"text\": \"...\"}]}]. Messages with problems are skipped for free and reported.", + "type": "array", + "items": { + "type": "string" + } + }, + "variables": { + "title": "Variables", + "description": "Extra values for {{placeholders}} in every email, e.g. {\"product\": \"Acme\"}.", + "type": "object" + }, + "sendSeparately": { + "title": "Send separately to each \"to\" address", + "description": "One email per address instead of one email with everyone in To (recipients don't see each other).", + "default": false, + "type": "boolean" + }, + "cc": { + "title": "Cc", + "description": "Comma-separated addresses.", + "type": "string" + }, + "bcc": { + "title": "Bcc", + "description": "Comma-separated addresses (in merge mode added to every email, e.g. a CRM dropbox).", + "type": "string" + }, + "replyTo": { + "title": "Reply-To", + "description": "Where replies go, if not the From address.", + "type": "string" + }, + "attachments": { + "title": "Attachments", + "description": "Files added to every email: {\"filename\": \"report.pdf\", \"url\": \"https://...\"}, {\"key\": \"OUTPUT\", \"filename\": \"report.pdf\"} (a record from the key-value store set below, e.g. a PDF or screenshot made by another Actor), {\"filename\": \"a.txt\", \"text\": \"...\"} or {\"filename\": \"a.png\", \"contentBase64\": \"...\"}. 20 MB total.", + "type": "array", + "items": { + "type": "string" + } + }, + "keyValueStoreId": { + "title": "Key-value store for attachments", + "description": "An Apify key-value store to read attachment records from (e.g. another run's defaultKeyValueStoreId holding a PDF, screenshot or report). Attachments given as {\"key\": \"OUTPUT\", \"filename\": \"report.pdf\"} are read from here.", + "type": "string" + }, + "headers": { + "title": "Extra headers", + "description": "Custom headers, e.g. {\"X-Campaign\": \"q3\"}.", + "type": "object" + }, + "unsubscribeUrl": { + "title": "Unsubscribe URL", + "description": "Adds List-Unsubscribe (and one-click List-Unsubscribe-Post for https URLs) so Gmail/Yahoo show an unsubscribe button. Placeholders allowed: https://acme.com/unsub?e={{email}}.", + "type": "string" + }, + "smtpHost": { + "title": "SMTP host", + "description": "e.g. smtp.gmail.com, smtp.office365.com, email-smtp.us-east-1.amazonaws.com, smtp.zoho.com, smtp.resend.com, smtp.sendgrid.net.", + "type": "string" + }, + "smtpPort": { + "title": "SMTP port", + "description": "587 (STARTTLS, default) or 465 (TLS). Port 25 is usually blocked in the cloud.", + "default": 587, + "type": "integer" + }, + "smtpSecure": { + "title": "Use TLS from the start", + "description": "Default: on for port 465, off (STARTTLS) otherwise.", + "type": "boolean" + }, + "smtpUser": { + "title": "SMTP username", + "description": "Usually your full email address.", + "type": "string" + }, + "smtpPassword": { + "title": "SMTP password", + "description": "Stored encrypted by Apify (secret input). Gmail/Google Workspace and Outlook need an app password, not your normal password.", + "type": "string" + }, + "smtpAllowSelfSigned": { + "title": "Allow self-signed TLS certificates", + "description": "Only for your own mail server with a self-signed certificate.", + "default": false, + "type": "boolean" + }, + "apiKey": { + "title": "API key (Resend, SendGrid, Mailgun, Postmark)", + "description": "Your provider API key (Postmark: server token). Stored encrypted by Apify (secret input).", + "type": "string" + }, + "mailgunDomain": { + "title": "Mailgun sending domain", + "description": "e.g. mg.acme.com (Mailgun only).", + "type": "string" + }, + "region": { + "title": "Region (Mailgun/SendGrid)", + "description": "eu for Mailgun EU domains or SendGrid EU subusers.", + "default": "us", + "enum": [ + "us", + "eu" + ], + "type": "string" + }, + "postmarkStream": { + "title": "Postmark message stream", + "description": "Default outbound (transactional).", + "type": "string" + }, + "dryRun": { + "title": "Dry run (preview, send nothing, free)", + "description": "Renders every email (recipients, subject, text and HTML) into the dataset without sending or charging. No credentials needed. Turn it off to send.", + "default": false, + "type": "boolean", + "examples": [ + true + ] + }, + "maxEmails": { + "title": "Max emails per run", + "description": "Safety cap on emails sent in one run.", + "default": 100, + "minimum": 1, + "maximum": 5000, + "type": "integer" + }, + "maxConcurrency": { + "title": "Parallel sends", + "description": "How many emails are sent at the same time.", + "default": 3, + "minimum": 1, + "maximum": 10, + "type": "integer" + }, + "delayBetweenEmailsMs": { + "title": "Pause between emails (ms)", + "description": "Per parallel sender; use it to stay under your provider's rate limit (e.g. Gmail).", + "default": 0, + "minimum": 0, + "maximum": 60000, + "type": "integer" + }, + "autoText": { + "title": "Generate a plain-text part from HTML", + "description": "Adds a plain-text version of HTML emails (better deliverability).", + "default": true, + "type": "boolean" + } + } + }, + "example": { + "from": "Acme AlertsHi {{firstName}},
Your {{plan}} report for {{company}} is ready.
", + "mode": "merge", + "items": [ + { + "email": "ann@example.com", + "firstName": "Ann", + "company": "Acme Corp", + "plan": "Pro" + }, + { + "email": "raj@example.org", + "firstName": "Raj", + "company": "Northwind", + "plan": "Team" + } + ], + "dryRun": true + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: ok, to, subject, messageId, charged, error, mode, sentAt" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } + }, + "/v2/acts/cybermax~seo-audit/run-sync-get-dataset-items": { + "post": { + "operationId": "seoAudit", + "summary": "SEO Audit Crawler & Broken Link Checker — Auditmoss", + "description": "SEO audit crawler: crawl any website and get every page's on-page SEO issues, broken links, redirects, duplicate titles and meta descriptions, missing H1/alt/canonical, speed and a 0-100 score, plus a site summary. Monitor mode flags new issues. $4 per 1,000 pages.\n\nRuns the CyberMax \"Auditmoss\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~seo-audit/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.004 per page audited.\nKey output fields: score, url, statusCode, issueCount, errors, warnings, issues, brokenLinkCount, title, titleLength, metaDescriptionLength, h1Count, wordCount, imagesMissingAlt, responseTimeMs, depth, inlinks, change.\nMinimal input: `{\"startUrls\":[\"https://books.toscrape.com\"],\"maxPages\":20,\"proxyConfiguration\":{\"useApifyProxy\":false}}`\nDocs: https://apify.com/cybermax/seo-audit", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Auditmoss on Apify Store", + "url": "https://apify.com/cybermax/seo-audit" + }, + "x-apify-actor": "cybermax/seo-audit", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Auditmoss input", + "properties": { + "startUrls": { + "title": "Websites to audit", + "description": "Home page (or any start page) of each site, e.g. https://example.com. Pages are found from the sitemap and by following internal links.", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + "https://books.toscrape.com" + ] + ] + }, + "maxPages": { + "title": "Max pages per site", + "description": "Pages audited (and charged) per site.", + "default": 100, + "minimum": 1, + "maximum": 10000, + "type": "integer", + "examples": [ + 20 + ] + }, + "maxDepth": { + "title": "Max link depth", + "description": "How many clicks from the start page to follow. 0 = only the start page and sitemap URLs.", + "default": 5, + "minimum": 0, + "maximum": 20, + "type": "integer" + }, + "useSitemap": { + "title": "Use the sitemap", + "description": "Seed the crawl from robots.txt sitemaps or /sitemap.xml, so pages that nothing links to are audited too.", + "default": true, + "type": "boolean" + }, + "includeSubdomains": { + "title": "Include subdomains", + "description": "Also crawl blog.example.com, shop.example.com and so on.", + "default": false, + "type": "boolean" + }, + "checkExternalLinks": { + "title": "Check external links too", + "description": "Also test links to other websites for errors (internal links are always checked).", + "default": false, + "type": "boolean" + }, + "maxConcurrency": { + "title": "Parallel requests", + "description": "Lower it for small or slow servers.", + "default": 5, + "minimum": 1, + "maximum": 10, + "type": "integer" + }, + "monitor": { + "title": "Monitor mode: only changes", + "description": "For scheduled runs. Returns only new pages and pages whose issues changed since the last run, with newIssues and fixedIssues. Nothing changed = nothing charged.", + "default": false, + "type": "boolean" + }, + "monitorKey": { + "title": "Watchlist name", + "description": "Optional name for this audit's saved state.", + "type": [ + "string", + "null" + ] + }, + "proxyConfiguration": { + "title": "Proxy", + "description": "Optional. Only needed if a site blocks or rate-limits you.", + "type": "object", + "properties": { + "useApifyProxy": { + "type": "boolean" + }, + "apifyProxyGroups": { + "type": "array", + "items": { + "type": "string" + } + }, + "apifyProxyCountry": { + "type": "string" + } + }, + "examples": [ + { + "useApifyProxy": false + } + ] + } + } + }, + "example": { + "startUrls": [ + "https://books.toscrape.com" + ], + "maxPages": 20, + "proxyConfiguration": { + "useApifyProxy": false + } + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: score, url, statusCode, issueCount, errors, warnings, issues, brokenLinkCount, title, titleLength, metaDescriptionLength, h1Count, wordCount, imagesMissingAlt, responseTimeMs, depth, inlinks, change" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } + }, + "/v2/acts/cybermax~shopify-scraper/run-sync-get-dataset-items": { + "post": { + "operationId": "shopifyScraper", + "summary": "Shopify Scraper: Products, Prices & Stock Monitor — Cartlark", + "description": "Shopify and WooCommerce product scraper: every product of any store with prices, compare-at (sale) prices, discount %, stock per variant, SKU, vendor, tags and images. Monitor mode returns only price drops, new products and stock changes. $0.80 per 1,000 products, no start fee.\n\nRuns the CyberMax \"Cartlark\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~shopify-scraper/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.0008 per product delivered.\nKey output fields: title, price, priceMax, compareAtPrice, discountPercent, currency, available, variantCount, vendor, productType, url, image, platform, change, previousPrice.\nMinimal input: `{\"stores\":[\"https://www.allbirds.com\"],\"maxProductsPerStore\":20,\"proxyConfiguration\":{\"useApifyProxy\":false}}`\nDocs: https://apify.com/cybermax/shopify-scraper", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Cartlark on Apify Store", + "url": "https://apify.com/cybermax/shopify-scraper" + }, + "x-apify-actor": "cybermax/shopify-scraper", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Cartlark input", + "properties": { + "stores": { + "title": "Store URLs or domains", + "description": "Shopify or WooCommerce stores, e.g. allbirds.com or https://www.allbirds.com. A Shopify collection URL (…/collections/mens) scrapes just that collection. The platform is detected for you.", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + "https://www.allbirds.com" + ] + ] + }, + "maxProductsPerStore": { + "title": "Max products per store", + "description": "In monitor mode: how many products per store are watched.", + "default": 250, + "minimum": 1, + "maximum": 50000, + "type": "integer", + "examples": [ + 20 + ] + }, + "keywords": { + "title": "Only products matching", + "description": "Optional. Keep products whose title, vendor, type or tags contain any of these words.", + "type": "array", + "items": { + "type": "string" + } + }, + "minPrice": { + "title": "Min price", + "description": "Optional, in the store's currency.", + "minimum": 0, + "type": "integer" + }, + "maxPrice": { + "title": "Max price", + "description": "Optional, in the store's currency.", + "minimum": 0, + "type": "integer" + }, + "onlyAvailable": { + "title": "In stock only", + "description": "Skip products with no variant in stock.", + "default": false, + "type": "boolean" + }, + "onlyOnSale": { + "title": "On sale only", + "description": "Keep products priced below their compare-at (regular) price.", + "default": false, + "type": "boolean" + }, + "includeVariants": { + "title": "Include variants", + "description": "Each product row lists its variants (size/colour) with price, compare-at price, SKU and stock. Off = one compact row per product.", + "default": true, + "type": "boolean" + }, + "includeDescription": { + "title": "Include description text", + "description": "Adds the product description as plain text (up to 5,000 characters).", + "default": false, + "type": "boolean" + }, + "platform": { + "title": "Platform", + "description": "Leave on auto unless you know the platform. Options: \"auto\" = Detect automatically, \"shopify\" = Shopify only, \"woocommerce\" = WooCommerce only.", + "default": "auto", + "enum": [ + "auto", + "shopify", + "woocommerce" + ], + "type": "string" + }, + "monitor": { + "title": "Monitor mode: only changes", + "description": "For scheduled runs. Remembers every product it saw and returns only new products, price changes (with previous price and % change), compare-at changes, out-of-stock and back-in-stock events. Nothing changed = nothing charged.", + "default": false, + "type": "boolean" + }, + "monitorKey": { + "title": "Watchlist name", + "description": "Optional name for this watchlist's saved state (use different names for different watchlists).", + "type": [ + "string", + "null" + ] + }, + "proxyConfiguration": { + "title": "Proxy", + "description": "Optional. Only needed if a store rate-limits your requests.", + "type": "object", + "properties": { + "useApifyProxy": { + "type": "boolean" + }, + "apifyProxyGroups": { + "type": "array", + "items": { + "type": "string" + } + }, + "apifyProxyCountry": { + "type": "string" + } + }, + "examples": [ + { + "useApifyProxy": false + } + ] + } + } + }, + "example": { + "stores": [ + "https://www.allbirds.com" + ], + "maxProductsPerStore": 20, + "proxyConfiguration": { + "useApifyProxy": false + } + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: title, price, priceMax, compareAtPrice, discountPercent, currency, available, variantCount, vendor, productType, url, image, platform, change, previousPrice" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } + }, + "/v2/acts/cybermax~sitemap-url-extractor/run-sync-get-dataset-items": { + "post": { + "operationId": "sitemapUrlExtractor", + "summary": "Sitemap URL Extractor: Get All Website URLs — Sitemoss", + "description": "Sitemap URL extractor: get all URLs of a website from its XML sitemaps. Finds sitemaps via robots.txt, follows sitemap indexes and .gz files, returns lastmod, changefreq, priority, hreflang and image counts. Monitor mode returns only new and updated pages. $0.40 per 1,000 URLs, no start fee.\n\nRuns the CyberMax \"Sitemoss\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~sitemap-url-extractor/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.0004 per uRL extracted.\nKey output fields: url, lastmod, changefreq, priority, imageCount, videoCount, alternates, newsTitle, site, sitemap, sitemapDepth, change.\nMinimal input: `{\"urls\":[\"https://apify.com/sitemap.xml\"],\"maxUrlsPerSite\":20}`\nDocs: https://apify.com/cybermax/sitemap-url-extractor", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Sitemoss on Apify Store", + "url": "https://apify.com/cybermax/sitemap-url-extractor" + }, + "x-apify-actor": "cybermax/sitemap-url-extractor", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Sitemoss input", + "properties": { + "urls": { + "title": "Websites or sitemap URLs", + "description": "One per line: a domain (example.com), any page of the site (https://www.example.com/blog) or a sitemap URL (https://example.com/post-sitemap.xml, .xml.gz or .txt). For a domain, Sitemoss reads the Sitemap: lines in robots.txt, then tries /sitemap.xml, /sitemap_index.xml and /wp-sitemap.xml, and follows every sitemap index.", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + "https://apify.com/sitemap.xml" + ] + ] + }, + "maxUrlsPerSite": { + "title": "Max URLs per site", + "description": "Stop after this many URLs for one site. Each delivered URL is one charged result.", + "default": 1000, + "minimum": 1, + "maximum": 1000000, + "type": "integer", + "examples": [ + 20 + ] + }, + "urlPattern": { + "title": "Only URLs matching (regex)", + "description": "Optional, e.g. /blog/|/products/ . Skipped URLs are free.", + "type": "string" + }, + "excludePattern": { + "title": "Skip URLs matching (regex)", + "description": "Optional, e.g. /tag/|/author/|\\?page=", + "type": "string" + }, + "lastmodAfter": { + "title": "Only pages modified after", + "description": "Optional date (2026-10-01). Keeps only URLs whose sitemap lastmod is on or after it; URLs without a lastmod are skipped (free).", + "type": "string" + }, + "sameSiteOnly": { + "title": "Only URLs on the site's own domain", + "description": "Drop sitemap entries that point to other domains.", + "default": false, + "type": "boolean" + }, + "maxSitemapsPerSite": { + "title": "Max sitemap files per site", + "description": "Safety limit for huge sitemap indexes.", + "default": 200, + "minimum": 1, + "maximum": 5000, + "type": "integer" + }, + "timeoutSecs": { + "title": "Request timeout (s)", + "description": "Timeout per sitemap download (retried twice on errors).", + "default": 30, + "minimum": 5, + "maximum": 120, + "type": "integer" + }, + "maxConcurrency": { + "title": "Sites in parallel", + "description": "How many sites to read at the same time.", + "default": 5, + "minimum": 1, + "maximum": 20, + "type": "integer" }, - "headers": { - "title": "Extra headers", - "description": "Custom headers, e.g. {\"X-Campaign\": \"q3\"}.", - "type": "object" + "monitor": { + "title": "Monitor mode: new and updated pages only", + "description": "For scheduled runs. Remembers every URL and its lastmod per site and returns only URLs that are new or whose lastmod changed since the last monitor run (field change = new | updated). Unchanged URLs are not returned and not charged. The first monitor run returns everything as new.", + "default": false, + "type": "boolean" }, - "unsubscribeUrl": { - "title": "Unsubscribe URL", - "description": "Adds List-Unsubscribe (and one-click List-Unsubscribe-Post for https URLs) so Gmail/Yahoo show an unsubscribe button. Placeholders allowed: https://acme.com/unsub?e={{email}}.", + "monitorKey": { + "title": "Watchlist name", + "description": "Optional name for this watchlist's saved state (e.g. competitor-blogs), so you can change the site list without starting over.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "urls" + ] + }, + "example": { + "urls": [ + "https://apify.com/sitemap.xml" + ], + "maxUrlsPerSite": 20 + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: url, lastmod, changefreq, priority, imageCount, videoCount, alternates, newsTitle, site, sitemap, sitemapDepth, change" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } + }, + "/v2/acts/cybermax~url-status-checker/run-sync-get-dataset-items": { + "post": { + "operationId": "urlStatusChecker", + "summary": "Bulk URL Status Code & Redirect Checker — Bouncefern", + "description": "Bulk HTTP status code checker and redirect checker: paste URLs or an old -> new redirect map, get status, final URL, every redirect hop, broken links (404), loops, 302s and HTTPS downgrades. Verify site migrations, find broken links, alert on changes. $1 per 1,000 URLs, no start fee.\n\nRuns the CyberMax \"Bouncefern\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~url-status-checker/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.001 per uRL checked.\nKey output fields: url, status, finalStatus, finalUrl, category, redirectCount, issues, ok, matchesExpected, expectedUrl, redirectChain, contentType, server, xRobotsTag, responseMs, error, change, changedFields.\nMinimal input: `{\"urls\":[\"http://apify.com\",\"https://apify.com/store\",\"https://apify.com/this-page-does-not-exist-404\"]}`\nDocs: https://apify.com/cybermax/url-status-checker", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Bouncefern on Apify Store", + "url": "https://apify.com/cybermax/url-status-checker" + }, + "x-apify-actor": "cybermax/url-status-checker", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Bouncefern input", + "properties": { + "urls": { + "title": "URLs to check", + "description": "One per line. Plain URLs or domains (example.com), or a redirect map line \"old-url -> expected-new-url\" (also \"old,new\") to verify a site migration: Bouncefern then reports matchesExpected for each line. Duplicates are removed.", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + "http://apify.com", + "https://apify.com/store", + "https://apify.com/this-page-does-not-exist-404" + ] + ] + }, + "method": { + "title": "HTTP method", + "description": "HEAD is fastest. Servers that reject or mishandle HEAD are retried with GET automatically. Bodies are never downloaded. Options: \"HEAD\" = HEAD (fast; falls back to GET when a server refuses HEAD), \"GET\" = GET (always).", + "default": "HEAD", + "enum": [ + "HEAD", + "GET" + ], "type": "string" }, - "smtpHost": { - "title": "SMTP host", - "description": "e.g. smtp.gmail.com, smtp.office365.com, email-smtp.us-east-1.amazonaws.com, smtp.zoho.com, smtp.resend.com, smtp.sendgrid.net.", + "userAgent": { + "title": "User agent", + "description": "Some sites answer differently to browsers and bots. Options: \"browser\" = Desktop browser (Chrome), \"bot\" = Bouncefern bot, \"googlebot\" = Googlebot user agent (to see what Google is served).", + "default": "browser", + "enum": [ + "browser", + "bot", + "googlebot" + ], "type": "string" }, - "smtpPort": { - "title": "SMTP port", - "description": "587 (STARTTLS, default) or 465 (TLS). Port 25 is usually blocked in the cloud.", - "default": 587, + "maxRedirects": { + "title": "Max redirects to follow", + "description": "0 = report only the first response.", + "default": 10, + "minimum": 0, + "maximum": 30, "type": "integer" }, - "smtpSecure": { - "title": "Use TLS from the start", - "description": "Default: on for port 465, off (STARTTLS) otherwise.", - "type": "boolean" + "timeoutSecs": { + "title": "Timeout per request (s)", + "description": "Timeouts are reported as category timeout.", + "default": 15, + "minimum": 3, + "maximum": 60, + "type": "integer" }, - "smtpUser": { - "title": "SMTP username", - "description": "Usually your full email address.", - "type": "string" + "maxConcurrency": { + "title": "URLs in parallel", + "description": "Lower it for one fragile server.", + "default": 10, + "minimum": 1, + "maximum": 50, + "type": "integer" }, - "smtpPassword": { - "title": "SMTP password", - "description": "Stored encrypted by Apify (secret input). Gmail/Google Workspace and Outlook need an app password, not your normal password.", - "type": "string" + "onlyProblems": { + "title": "Only return problem URLs", + "description": "Skip URLs that are fine (status under 400, no issues). Skipped URLs are not charged.", + "default": false, + "type": "boolean" }, - "smtpAllowSelfSigned": { - "title": "Allow self-signed TLS certificates", - "description": "Only for your own mail server with a self-signed certificate.", + "monitor": { + "title": "Monitor mode: changes only", + "description": "For scheduled runs. Remembers each URL's status, final URL and redirect count and returns only URLs that are new or changed since the last monitor run (change, changedFields, previous). Unchanged URLs are not returned and not charged.", "default": false, "type": "boolean" }, - "apiKey": { - "title": "API key (Resend, SendGrid, Mailgun, Postmark)", - "description": "Your provider API key (Postmark: server token). Stored encrypted by Apify (secret input).", - "type": "string" + "monitorKey": { + "title": "Watchlist name", + "description": "Optional name for this watchlist's saved state (e.g. top-landing-pages).", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "urls" + ] + }, + "example": { + "urls": [ + "http://apify.com", + "https://apify.com/store", + "https://apify.com/this-page-does-not-exist-404" + ] + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: url, status, finalStatus, finalUrl, category, redirectCount, issues, ok, matchesExpected, expectedUrl, redirectChain, contentType, server, xRobotsTag, responseMs, error, change, changedFields" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } + }, + "/v2/acts/cybermax~wayback-machine/run-sync-get-dataset-items": { + "post": { + "operationId": "waybackMachine", + "summary": "Wayback Machine Scraper: Website History & Snapshots — Eldwren", + "description": "Wayback Machine scraper and website history checker: get a site's first and last archive capture, archive age, years online, every snapshot (status, type, digest, link) or every archived URL of a domain. Official Internet Archive CDX API. $3 per 1,000 histories; snapshots $0.80 per 1,000.\n\nRuns the CyberMax \"Eldwren\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~wayback-machine/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.003 per website history summarized; $0.0008 per snapshot or archived URL listed.\nKey output fields: target, archived, firstCapture, lastCapture, archiveAgeYears, daysSinceLastCapture, monthsWithCaptures, yearsWithCaptures, gapYears, lastStatus, firstCaptureUrl, lastCaptureUrl, change, error.\nMinimal input: `{\"urls\":[\"apify.com\"],\"maxResultsPerUrl\":20}`\nDocs: https://apify.com/cybermax/wayback-machine", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Eldwren on Apify Store", + "url": "https://apify.com/cybermax/wayback-machine" + }, + "x-apify-actor": "cybermax/wayback-machine", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Eldwren input", + "properties": { + "urls": { + "title": "Domains or URLs", + "description": "One per line: a domain (example.com) or a page (example.com/pricing). The scheme and www. are ignored, as in the Wayback Machine.", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + "apify.com" + ] + ] }, - "mailgunDomain": { - "title": "Mailgun sending domain", - "description": "e.g. mg.acme.com (Mailgun only).", + "mode": { + "title": "What to return", + "description": "summary is charged per URL with captures ($0.003); snapshots and archived URLs are charged per row ($0.0008). Options: \"summary\" = History summary: one record per URL (first/last capture, archive age, years online), \"captures\" = Snapshots: every capture of the URL (status, type, digest, archive link), \"urls\" = Archived URLs: every URL of the domain the archive holds.", + "default": "summary", + "enum": [ + "summary", + "captures", + "urls" + ], "type": "string" }, - "region": { - "title": "Region (Mailgun/SendGrid)", - "description": "eu for Mailgun EU domains or SendGrid EU subusers.", - "default": "us", + "maxResultsPerUrl": { + "title": "Max rows per URL", + "description": "For snapshots and archived URLs: stop after this many rows per input.", + "default": 100, + "minimum": 1, + "maximum": 1000000, + "type": "integer", + "examples": [ + 20 + ] + }, + "collapse": { + "title": "One snapshot per", + "description": "Snapshots mode: thin out captures. 'Content change' returns a capture only when the page content changed. Options: \"none\" = Every capture, \"hour\" = Hour, \"day\" = Day, \"month\" = Month, \"year\" = Year, \"digest\" = Content change (new digest).", + "default": "day", "enum": [ - "us", - "eu" + "none", + "hour", + "day", + "month", + "year", + "digest" ], "type": "string" }, - "postmarkStream": { - "title": "Postmark message stream", - "description": "Default outbound (transactional).", + "from": { + "title": "From date", + "description": "Optional, e.g. 2015 or 2020-06-01.", + "type": "string" + }, + "to": { + "title": "To date", + "description": "Optional, e.g. 2023-12-31.", + "type": "string" + }, + "statusFilter": { + "title": "HTTP status filter", + "description": "Optional: 200, 2xx, 3xx, !404 (comma-separated).", "type": "string" }, - "dryRun": { - "title": "Dry run (preview, send nothing, free)", - "description": "Renders every email (recipients, subject, text and HTML) into the dataset without sending or charging. No credentials needed. Turn it off to send.", - "default": false, - "type": "boolean", - "examples": [ - true - ] + "mimeFilter": { + "title": "MIME type filter", + "description": "Optional, e.g. text/html or application/pdf (archived URLs mode: find every archived PDF of a domain).", + "type": "string" }, - "maxEmails": { - "title": "Max emails per run", - "description": "Safety cap on emails sent in one run.", - "default": 100, - "minimum": 1, - "maximum": 5000, + "matchType": { + "title": "URL match", + "description": "Archived URLs mode defaults to domain. Options: \"exact\" = Exact URL, \"prefix\" = Everything under this path (prefix), \"host\" = Whole host, \"domain\" = Host and all subdomains.", + "default": "exact", + "enum": [ + "exact", + "prefix", + "host", + "domain" + ], + "type": "string" + }, + "timeoutSecs": { + "title": "Timeout per archive request (s)", + "description": "The archive is slow for very large domains; requests are retried with back-off.", + "default": 90, + "minimum": 20, + "maximum": 300, "type": "integer" }, "maxConcurrency": { - "title": "Parallel sends", - "description": "How many emails are sent at the same time.", - "default": 3, + "title": "URLs in parallel", + "description": "Kept low to stay within the archive's rate limits.", + "default": 2, "minimum": 1, - "maximum": 10, - "type": "integer" - }, - "delayBetweenEmailsMs": { - "title": "Pause between emails (ms)", - "description": "Per parallel sender; use it to stay under your provider's rate limit (e.g. Gmail).", - "default": 0, - "minimum": 0, - "maximum": 60000, + "maximum": 4, "type": "integer" }, - "autoText": { - "title": "Generate a plain-text part from HTML", - "description": "Adds a plain-text version of HTML emails (better deliverability).", - "default": true, + "monitor": { + "title": "Monitor mode: new captures only", + "description": "For scheduled runs. Summary mode returns a URL only when it has a capture newer than last time; snapshots and archived-URL modes return only rows newer than the last monitor run. Nothing new = nothing charged.", + "default": false, "type": "boolean" + }, + "monitorKey": { + "title": "Watchlist name", + "description": "Optional name for this watchlist's saved state.", + "type": [ + "string", + "null" + ] } - } + }, + "required": [ + "urls" + ] }, "example": { - "from": "Acme AlertsHi {{firstName}},
Your {{plan}} report for {{company}} is ready.
", - "mode": "merge", - "items": [ - { - "email": "ann@example.com", - "firstName": "Ann", - "company": "Acme Corp", - "plan": "Pro" - }, - { - "email": "raj@example.org", - "firstName": "Raj", - "company": "Northwind", - "plan": "Team" - } + "urls": [ + "apify.com" ], - "dryRun": true + "maxResultsPerUrl": 20 } } } @@ -3248,7 +4836,7 @@ "items": { "type": "object", "additionalProperties": true, - "description": "Typical fields: ok, to, subject, messageId, charged, error, mode, sentAt" + "description": "Typical fields: target, archived, firstCapture, lastCapture, archiveAgeYears, daysSinceLastCapture, monthsWithCaptures, yearsWithCaptures, gapYears, lastStatus, firstCaptureUrl, lastCaptureUrl, change, error" } } } @@ -3273,7 +4861,7 @@ "post": { "operationId": "websiteContacts", "summary": "Contact Details & Email Scraper by Domain — Hollerdex", - "description": "Get any company's best email, phone and social profiles from its domain. Contact details scraper and email scraper: labelled emails (sales, support, press), E.164 phones, LinkedIn, X, Instagram, contact page and form. Monitor mode flags changes. $0.004 per domain with contacts; misses free.\n\nRuns the CyberMax \"Hollerdex\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~website-contacts/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.004 per domain with contacts found.\nKey output fields: domain, companyName, summary, primaryEmail, primaryPhone, socials, contactPageUrl, contactFormUrl, emails, addresses, blocked, errors, change, changedFields, changes.\nMinimal input: `{\"domains\":[\"apify.com\",\"basecamp.com\"]}`\nDocs: https://apify.com/cybermax/website-contacts", + "description": "Get any company's best email, phone and social profiles from its domain. Contact details scraper and email scraper: labelled emails (sales, support, press), E.164 phones, LinkedIn, X, Instagram, contact page and form. One card per domain, charged only when contacts are found. Change alerts.\n\nRuns the CyberMax \"Hollerdex\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~website-contacts/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.004 per domain with contacts found.\nKey output fields: domain, companyName, summary, primaryEmail, primaryPhone, socials, contactPageUrl, contactFormUrl, emails, addresses, blocked, errors, change, changedFields, changes.\nMinimal input: `{\"domains\":[\"apify.com\",\"basecamp.com\"]}`\nDocs: https://apify.com/cybermax/website-contacts", "tags": [ "CyberMax Actors" ], @@ -3433,7 +5021,7 @@ "/v2/acts/cybermax~website-screenshot/run-sync-get-dataset-items": { "post": { "operationId": "websiteScreenshot", - "summary": "Capturewren — Website Screenshot API: See & Read Any Web Page", + "summary": "Website Screenshot API: Full Page & Mobile — Capturewren", "description": "See and read any web page in one call. Website screenshot API and generator: full-page, element or mobile PNG/JPEG screenshot plus HTTP status, title, meta and clean page text. Cookie banners removed; monitor mode for page change alerts. $0.003 per screenshot, failures free.\n\nRuns the CyberMax \"Capturewren\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~website-screenshot/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.003 per screenshot captured.\nKey output fields: screenshotUrl, url, ok, change, httpStatus, title, finalUrl, description, cookieBannerDismissed, bytes, loadMs, warning, error.\nMinimal input: `{\"urls\":[\"https://apify.com\",\"https://example.com\"]}`\nDocs: https://apify.com/cybermax/website-screenshot", "tags": [ "CyberMax Actors" @@ -3658,6 +5246,263 @@ } } } + }, + "/v2/acts/cybermax~website-to-markdown/run-sync-get-dataset-items": { + "post": { + "operationId": "websiteToMarkdown", + "summary": "Website to Markdown Crawler for RAG & llms.txt — Docsieve", + "description": "Website to Markdown crawler for RAG and LLMs: crawl any website or docs site and get clean Markdown per page (no menus or footers), RAG-ready chunks with token counts, and llms.txt + llms-full.txt. Monitor mode returns only changed pages. $1 per 1,000 pages.\n\nRuns the CyberMax \"Docsieve\" Apify Actor synchronously and returns its dataset items as a JSON array (one object per result). Waits up to 300 s; for longer jobs use the async POST /v2/acts/cybermax~website-to-markdown/runs endpoint.\nPricing (pay per event, billed to the caller's Apify account): $0.001 per page converted.\nKey output fields: url, title, wordCount, tokens, chunkCount, chunkIndex, heading, markdown, text, change, crawledAt.\nMinimal input: `{\"startUrls\":[\"https://docs.apify.com/academy\"],\"maxPages\":10,\"includePaths\":[\"/academy*\"],\"proxyConfiguration\":{\"useApifyProxy\":false}}`\nDocs: https://apify.com/cybermax/website-to-markdown", + "tags": [ + "CyberMax Actors" + ], + "externalDocs": { + "description": "Docsieve on Apify Store", + "url": "https://apify.com/cybermax/website-to-markdown" + }, + "x-apify-actor": "cybermax/website-to-markdown", + "parameters": [ + { + "$ref": "#/components/parameters/timeout" + }, + { + "$ref": "#/components/parameters/memory" + }, + { + "$ref": "#/components/parameters/maxItems" + }, + { + "$ref": "#/components/parameters/maxTotalChargeUsd" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "title": "Docsieve input", + "properties": { + "startUrls": { + "title": "Websites or docs to convert", + "description": "Start page of each site, e.g. https://docs.example.com. Pages are found from the sitemap and by following internal links.", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + "https://docs.apify.com/academy" + ] + ] + }, + "maxPages": { + "title": "Max pages per site", + "description": "Pages converted (and charged) per site.", + "default": 50, + "minimum": 1, + "maximum": 20000, + "type": "integer", + "examples": [ + 10 + ] + }, + "includePaths": { + "title": "Only paths matching", + "description": "Optional, * = anything. E.g. /docs/* or /blog/*. The start page is always read.", + "type": "array", + "items": { + "type": "string" + }, + "examples": [ + [ + "/academy*" + ] + ] + }, + "excludePaths": { + "title": "Skip paths matching", + "description": "Optional, e.g. /tag/*, /author/*, /changelog/*.", + "type": "array", + "items": { + "type": "string" + } + }, + "maxDepth": { + "title": "Max link depth", + "description": "Clicks from the start page to follow.", + "default": 10, + "minimum": 0, + "maximum": 50, + "type": "integer" + }, + "outputMode": { + "title": "Output rows", + "description": "Chunk rows carry the page URL, title and heading path, so you can load them straight into Pinecone, Qdrant, Weaviate, pgvector or Chroma. Charged per page either way. Options: \"pages\" = One row per page (Markdown + chunks), \"chunks\" = One row per chunk (ready for a vector database).", + "default": "pages", + "enum": [ + "pages", + "chunks" + ], + "type": "string" + }, + "chunking": { + "title": "Split into chunks", + "description": "Heading-aware chunks with token estimates.", + "default": true, + "type": "boolean" + }, + "chunkSize": { + "title": "Chunk size (characters)", + "description": "About 500 tokens at the default.", + "default": 2000, + "minimum": 200, + "maximum": 20000, + "type": "integer" + }, + "chunkOverlap": { + "title": "Chunk overlap (characters)", + "description": "Text repeated from the previous chunk for context.", + "default": 200, + "minimum": 0, + "maximum": 10000, + "type": "integer" + }, + "llmsTxt": { + "title": "Build llms.txt and llms-full.txt", + "description": "Saved in the run's key-value store (free).", + "default": true, + "type": "boolean" + }, + "includeLinks": { + "title": "Keep links", + "description": "Keep [text](url) links in the Markdown.", + "default": true, + "type": "boolean" + }, + "includeImages": { + "title": "Keep images", + "description": "Keep  images in the Markdown.", + "default": false, + "type": "boolean" + }, + "minWords": { + "title": "Skip pages under (words)", + "description": "Skips empty and redirect-only pages (not charged).", + "default": 30, + "minimum": 0, + "type": "integer" + }, + "useSitemap": { + "title": "Use the sitemap", + "description": "Seed the crawl from robots.txt sitemaps or /sitemap.xml.", + "default": true, + "type": "boolean" + }, + "includeSubdomains": { + "title": "Include subdomains", + "description": "Also crawl docs.example.com when starting at example.com.", + "default": false, + "type": "boolean" + }, + "includeNoindex": { + "title": "Include noindex pages", + "description": "Pages marked noindex are skipped unless this is on.", + "default": false, + "type": "boolean" + }, + "maxConcurrency": { + "title": "Parallel requests", + "description": "Lower it for small servers.", + "default": 5, + "minimum": 1, + "maximum": 10, + "type": "integer" + }, + "monitor": { + "title": "Monitor mode: changed pages only", + "description": "For scheduled runs. Returns only new and changed pages (by content hash) and lists removed pages in the summary. Unchanged pages are free.", + "default": false, + "type": "boolean" + }, + "monitorKey": { + "title": "Watchlist name", + "description": "Optional name for this crawl's saved state.", + "type": [ + "string", + "null" + ] + }, + "proxyConfiguration": { + "title": "Proxy", + "description": "Optional. Only needed if a site blocks or rate-limits you.", + "type": "object", + "properties": { + "useApifyProxy": { + "type": "boolean" + }, + "apifyProxyGroups": { + "type": "array", + "items": { + "type": "string" + } + }, + "apifyProxyCountry": { + "type": "string" + } + }, + "examples": [ + { + "useApifyProxy": false + } + ] + } + } + }, + "example": { + "startUrls": [ + "https://docs.apify.com/academy" + ], + "maxPages": 10, + "includePaths": [ + "/academy*" + ], + "proxyConfiguration": { + "useApifyProxy": false + } + } + } + } + }, + "responses": { + "201": { + "description": "Run finished. Body is the list of dataset items the run produced.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true, + "description": "Typical fields: url, title, wordCount, tokens, chunkCount, chunkIndex, heading, markdown, text, change, crawledAt" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "408": { + "$ref": "#/components/responses/Timeout" + } + } + } } }, "components": {