{
  "openapi": "3.0.1",
  "info": {
    "title": "UK Trading Disclosure Scraper - Company No, VAT & Contact",
    "description": "Turn UK company domains into registry-grade B2B leads from each site's statutory trading disclosure (Companies Act 2006 s.82): registered name, Companies House number, jurisdiction, registered office, mod-97-checked VAT number, charity and ICO numbers, regulator, email, phone. $0.006 per disclosure.",
    "version": "0.1",
    "x-build-id": "v0heroL4089qorkuy"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapersdelight~uk-trading-disclosures-contact-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapersdelight-uk-trading-disclosures-contact-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/scrapersdelight~uk-trading-disclosures-contact-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scrapersdelight-uk-trading-disclosures-contact-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/scrapersdelight~uk-trading-disclosures-contact-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scrapersdelight-uk-trading-disclosures-contact-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "domains": {
            "title": "UK domains (or legal/terms page URLs)",
            "type": "array",
            "description": "One entry per company. Accepts all three shapes: a bare domain (\"rox.co.uk\"), a homepage URL (\"https://www.nq64.co.uk\") or a direct legal/terms page URL (\"https://x.co.uk/terms-and-conditions\"). ANY TLD is accepted — a third of real UK business domains are .com, and filtering to .uk would silently drop them. The Actor finds each site's statutory trading disclosure and parses it into one lead per domain. Leave empty to run the built-in UK demo batch.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs (list source)",
            "type": "array",
            "description": "The same domain list handed over as URLs, so Make, Zapier, Clay or a Google Sheet can pass it natively (a link to a text/CSV file of URLs also works). Merged with \"UK domains\".",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "sourceDatasetId": {
            "title": "Enrich an existing dataset",
            "type": "string",
            "description": "Dataset ID of a previous Actor run. Each item's domain/website column is read and enriched — the real agency workflow: run a directory, Maps or Companies House scraper first, then pipe its output here."
          },
          "domainFieldName": {
            "title": "Domain field / CSV column",
            "type": "string",
            "description": "Which field of the source dataset (or which CSV column of the list file) holds the domain. Leave empty to auto-detect domain / website / websiteUrl / url / site / homepage. Dotted paths like \"company.website\" work."
          },
          "domainsFileUrl": {
            "title": "Domain list file URL",
            "type": "string",
            "description": "URL of a CSV, TXT, JSON or JSONL file holding the domains — for lists too big to paste into the editor. The column is picked with \"Domain field / CSV column\"."
          },
          "skipDomains": {
            "title": "Suppression list",
            "type": "array",
            "description": "Domains to skip outright — accounts you already own, competitors, do-not-contact entries. Matched on the registrable domain, so \"www.x.co.uk/page\" and \"x.co.uk\" are the same entry.",
            "items": {
              "type": "string"
            }
          },
          "previousDatasetId": {
            "title": "Skip rows already delivered (dataset ID)",
            "type": "string",
            "description": "Dataset ID of an earlier run of THIS Actor. Its stableId / companyNumber / domain values are loaded as a suppression list, so a monthly re-run never re-delivers — and never re-charges you for — a company you already bought."
          },
          "maxItems": {
            "title": "Max results (billed rows)",
            "minimum": 0,
            "type": "integer",
            "description": "Hard cap on rows DELIVERED AND BILLED this run. Distinct from \"Max domains\": measured on 896 random real UK business domains, about 1 domain in 4 published a findable statutory disclosure, so 1,000 domains yield roughly 250 billed rows. 0 = unlimited.",
            "default": 1000
          },
          "maxDomains": {
            "title": "Max domains attempted",
            "minimum": 0,
            "type": "integer",
            "description": "Cap on domains ATTEMPTED, applied before any request. Use it to sample a big list cheaply. 0 = attempt every domain supplied.",
            "default": 0
          },
          "maxDiscoveryRequestsPerDomain": {
            "title": "Max discovery requests per domain",
            "minimum": 0,
            "maximum": 40,
            "type": "integer",
            "description": "Hard cap on discovery + confirmation requests per domain, counted AFTER the homepage. This is the knob that stops one slow host burning a minute of a run. Measured average across the whole cascade: 6.5 requests per domain.",
            "default": 8
          },
          "maxPagesParsed": {
            "title": "Max pages parsed per domain",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many fetched pages may be parsed and merged for one domain. The homepage counts as one. Raising it finds more fields on sites that split the disclosure across terms/contact/privacy pages; lowering it to 1 makes the run homepage-only and very cheap.",
            "default": 3
          },
          "perDomainTimeoutSecs": {
            "title": "Per-domain timeout (seconds)",
            "minimum": 5,
            "maximum": 600,
            "type": "integer",
            "description": "Wall-clock deadline for one domain, discovery included.",
            "default": 60
          },
          "requestConcurrency": {
            "title": "Request concurrency",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "How many domains are worked in parallel. Higher is faster; keep it modest to stay polite to small business sites, and remember memory scales with it.",
            "default": 10
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 120,
            "type": "integer",
            "description": "Timeout for a single HTTP request.",
            "default": 25
          },
          "maxRequestRetries": {
            "title": "Max request retries",
            "minimum": 0,
            "maximum": 6,
            "type": "integer",
            "description": "Retries per request, each on a FRESH proxy IP (got-scraping's own retry reuses the flagged IP, which is useless against a soft block).",
            "default": 2
          },
          "discoveryChannels": {
            "title": "Discovery channels",
            "type": "array",
            "description": "Which channels may be used to locate the disclosure, tried in this order. MEASURED over 598 real UK domains on the platform, counting which channel found the winning page: ranked footer links 74, homepage footer 71, XML sitemap 2, guessed paths 1. The homepage footer is free (that page is already fetched). Guessed paths cost 769 of the run's 3,822 requests (fast 404s) and won once — keep them for sites whose footer carries no legal link at all, or switch them off as a speed lever on a big list.",
            "items": {
              "type": "string",
              "enum": [
                "homepage",
                "anchor",
                "sitemap",
                "wpJson",
                "pathGuess"
              ],
              "enumTitles": [
                "Homepage footer (free)",
                "Ranked footer links (terms / legal / privacy)",
                "XML sitemap",
                "WordPress REST page index",
                "Guessed paths"
              ]
            },
            "default": [
              "homepage",
              "anchor",
              "sitemap",
              "wpJson",
              "pathGuess"
            ]
          },
          "followWwwAndRootVariants": {
            "title": "Try www and apex variants",
            "type": "boolean",
            "description": "If the homepage fails, retry the other host form (www.x.co.uk to x.co.uk and back) before declaring the domain unreachable.",
            "default": true
          },
          "deepJsDiscovery": {
            "title": "Deep JS fallback (JS-only footers)",
            "type": "boolean",
            "description": "Last-resort channel for a footer that only exists after client-side render. No Chromium is launched — this build is deliberately browser-free, because a browser image would multiply the compute cost of every run. Instead the Actor reads what a render would have read FROM: the page's inline JSON payloads and its external JavaScript bundles, searching them for a legal-page URL. Costs up to 6 extra requests per domain and is never charged separately.",
            "default": false
          },
          "respectRobotsTxt": {
            "title": "Respect robots.txt",
            "type": "boolean",
            "description": "Fetch and honour each site's robots.txt before requesting anything. Off by default because it costs one extra request per domain and these pages exist to be indexed. Turn it on if your own compliance policy requires it.",
            "default": false
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Proxy settings. Apify DATACENTER is the default and is the measured winner on this corpus: usable transport on the large majority of reachable UK domains, with a residential retry only when a host actually challenges us.",
            "default": {
              "useApifyProxy": true
            }
          },
          "proxyCountry": {
            "title": "Proxy country",
            "enum": [
              "none",
              "GB",
              "IE",
              "US"
            ],
            "type": "string",
            "description": "Pin the exit country for sites that geo-tailor their content. MEASURED: Apify datacenter proxies cannot be pinned to a country (they answer HTTP 407), so choosing a country here switches the run to RESIDENTIAL exit nodes in that country. Leave on None for the cheaper, faster datacenter path.",
            "default": "none"
          },
          "escalateToResidentialOnBlock": {
            "title": "Escalate to residential on a block",
            "type": "boolean",
            "description": "On a 403 / challenge (never on a dead host and never on a 404), retry the request once on RESIDENTIAL + country-GB. Measured: recovers a real slice of the CDN-fronted tail at no cost on a clean SME list, because it only fires on an actual refusal.",
            "default": true
          },
          "escalateToUnblockerOnBlock": {
            "title": "Escalate to Apify Unblocker on a block",
            "type": "boolean",
            "description": "A SECOND escalation, after residential, for the Cloudflare-managed-challenge tail. MEASURED on the domains that both datacenter and residential were refused by: Unblocker recovered 4 of 5 (the same hosts also serve the operator's own home IP a 202 challenge, so the wall is real and is not the Apify proxy). Off by default because Unblocker requests are billed to your Apify account on top of the row price.",
            "default": false
          },
          "customUserAgent": {
            "title": "Custom User-Agent",
            "type": "string",
            "description": "Override the browser User-Agent sent on every request. Leave empty for the built-in Chrome 124 fingerprint."
          },
          "extraHttpHeaders": {
            "title": "Extra HTTP headers",
            "type": "object",
            "description": "Additional request headers, merged over the defaults (e.g. a From: header identifying your crawler)."
          },
          "tldFilterMode": {
            "title": "TLD filter mode",
            "enum": [
              "none",
              "include",
              "exclude"
            ],
            "type": "string",
            "description": "No TLD filter is applied by default, deliberately: of 14,041 real UK business domains sourced from OpenStreetMap across 18 UK cities, only 8,398 are .uk of any kind and 4,614 are .com. Filtering to .uk would discard 40% of the corpus. Use this only when your own list really is single-TLD.",
            "default": "none"
          },
          "tldFilter": {
            "title": "TLDs",
            "type": "array",
            "description": "The TLD list the mode above applies to, without the dot: uk, co.uk, com, org.uk, scot, wales.",
            "items": {
              "type": "string"
            }
          },
          "requireRegistryId": {
            "title": "Only rows with a registry ID",
            "type": "boolean",
            "description": "Deliver (and bill) only companies whose disclosure carries a Companies House number, a VAT number or a charity number.",
            "default": false
          },
          "requireValidVat": {
            "title": "Only rows with a checksum-valid VAT number",
            "type": "boolean",
            "description": "Deliver (and bill) only rows whose GB VAT number passes the mod-97 checksum. A row with no VAT number, or one that fails the checksum, is filtered out here and never billed.",
            "default": false
          },
          "requireContact": {
            "title": "Only rows with a contact",
            "type": "boolean",
            "description": "Deliver (and bill) only companies with an email or a phone number.",
            "default": false
          },
          "jurisdictionFilter": {
            "title": "Jurisdictions",
            "type": "array",
            "description": "Keep only companies registered in these parts of the UK. Derived from the Companies House number prefix (SC = Scotland, NI = Northern Ireland, no prefix = England and Wales) and from the wording of the disclosure. Leave empty for all.",
            "items": {
              "type": "string",
              "enum": [
                "England and Wales",
                "Scotland",
                "Northern Ireland",
                "Overseas"
              ],
              "enumTitles": [
                "England and Wales",
                "Scotland",
                "Northern Ireland",
                "Overseas-registered"
              ]
            },
            "default": []
          },
          "minFieldsRequired": {
            "title": "Minimum populated fields",
            "minimum": 0,
            "maximum": 19,
            "type": "integer",
            "description": "Quality floor: a row must carry at least this many of the 19 value fields before it is delivered and billed. 0 = no floor.",
            "default": 0
          },
          "emailPolicy": {
            "title": "Email policy",
            "enum": [
              "all",
              "role-only",
              "exclude-role"
            ],
            "type": "string",
            "description": "Agencies split hard on whether info@ / enquiries@ counts as a lead. \"Role only\" keeps just those; \"Exclude role\" keeps only named mailboxes.",
            "default": "all"
          },
          "dedupeBy": {
            "title": "Deduplicate by",
            "enum": [
              "company-number-then-domain",
              "domain",
              "company-number",
              "none"
            ],
            "type": "string",
            "description": "Which key collapses duplicates BEFORE anything is pushed or charged. The default uses a well-formed Companies House number when the page carries one and the registrable domain otherwise, so two domains owned by the same company collapse to one billed row — and a repeated input line is dropped at queue time, before it costs a request.",
            "default": "company-number-then-domain"
          },
          "validateTaxId": {
            "title": "Checksum-validate the VAT number",
            "type": "boolean",
            "description": "Run the published GB VAT mod-97 checksum (both the standard and the 97-55 variant) on every VAT number found and emit vatNumberValid plus which variant it passed. Note that Companies House numbers carry NO checksum, so companyNumberFormatValid is a format and known-prefix check, never a checksum.",
            "default": true
          },
          "extractRegulator": {
            "title": "Extract the regulator",
            "type": "boolean",
            "description": "The UK regulatory body a professional-services site must name (FCA, SRA, RICS, GDC, GMC, CQC, Ofsted, Gambling Commission, ATOL, Gas Safe and others) plus its reference number where published.",
            "default": true
          },
          "extractIco": {
            "title": "Extract the ICO registration",
            "type": "boolean",
            "description": "The Information Commissioner's Office data-protection registration number (ZA######) where the site publishes it.",
            "default": true
          },
          "extractCharity": {
            "title": "Extract the charity number",
            "type": "boolean",
            "description": "Registered charity number, including the Scottish OSCR form. Kept in its OWN field: a Scottish charity number has the same SC###### shape as a Scottish company number and must never be mistaken for one.",
            "default": true
          },
          "extractOfficer": {
            "title": "Extract a named officer",
            "type": "boolean",
            "description": "A director, proprietor or company secretary named next to a label on the page. Honest expectation: UK sites rarely publish one — measured about 1% fill. Unlike a German Impressum, reg. 25 does not require it.",
            "default": true
          },
          "extractSocials": {
            "title": "Extract social profiles",
            "type": "boolean",
            "description": "LinkedIn, Facebook, Instagram, X, YouTube and TikTok links present on the pages read.",
            "default": true
          },
          "extractPolicyUrls": {
            "title": "Extract terms & privacy-policy URLs",
            "type": "boolean",
            "description": "The site's terms and privacy-policy URLs, linked from the pages read.",
            "default": true
          },
          "includeMissRows": {
            "title": "Include unbilled miss rows",
            "type": "boolean",
            "description": "Emit a row for every domain that produced no lead — dead host, blocked, publishes no disclosure, filtered out, a duplicate, or suppressed — with its status and missReason, so you can do coverage accounting. These rows are NEVER charged.",
            "default": false
          },
          "includeFieldSources": {
            "title": "Include per-field provenance",
            "type": "boolean",
            "description": "Add a fieldSources object naming the exact URL each field was read from. Useful when a disclosure is split across a terms page and a contact page and you need to audit which said what.",
            "default": false
          },
          "flattenOutput": {
            "title": "Flat columns",
            "type": "boolean",
            "description": "On: one flat row, ready for Google Sheets, Clay or a CSV export. Off: fields grouped into company {}, registry {}, contact {}, people {} and policies {} objects.",
            "default": true
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}