Skip to main content

paytrace

CI PyPI License

Attribute websites to the legal entities that get paid for them.

25 collectors for attribution-graph, built on one fact: an operator can hide registrant, hosting, DNS and email — but to be paid, a real legal entity must be named to an ad system, and sellers.json publishes that name.

pip install paytrace

The chain

scraper-site.example/ads.txt
  └─ pubmatic.com, 156423, DIRECT
      └─ pubmatic.com/sellers.json
          └─ name: "Example Media Holdings Ltd"
              ├─ GLEIF           → LEI, address, ownership tree
              ├─ SEC EDGAR       → CIK, officers, former names
              ├─ Companies House → directors, beneficial owners
              └─ RDAP / crt.sh   → back to infrastructure

Every hop is free, keyless, and either statutory or self-published.


Commands

paytrace run        --case case.yaml --index paytrace.sqlite --out ./out
paytrace portfolio  scraper-site.example --index paytrace.sqlite --registrants
paytrace registries --jurisdiction IN
paytrace-index build   --domains tranco-top-1m.txt --db paytrace.sqlite
paytrace-index sellers --db paytrace.sqlite
paytrace-index lookup  --db paytrace.sqlite --seller pubmatic.com/156423

Runnable examples:

python examples/end_to_end_domain.py     # full chain, offline
python examples/reference_collector.py   # annotated collector template
python demo/run_demo.py                  # prompt injection demo (below)

Collectors

Name Source Auth
ads_txt_owner /ads.txt v1.1 incl. OWNERDOMAIN none
sellers_json {adsystem}/sellers.json none
analytics_ids AdSense, GA4, UA, GTM, Pixel, Sentry, Yandex none
wayback Internet Archive CDX none
gleif GLEIF LEI index none
sec_edgar EDGAR full-text + submissions none¹
companies_house_uk UK Companies House free key
opencorporates OpenCorporates v0.4 key
uspto_trademark USPTO Open Data free key
imprint /impressum, /legal, /terms none
opensanctions_yente self-hosted yente none
rdap IANA RDAP bootstrap none
crtsh Certificate Transparency none
internetdb internetdb.shodan.io none
mnemonic_pdns mnemonic passive DNS none
favicon_mmh3 local mmh3 none
code_host_org GitHub/GitLab orgs free token
package_registry npm, PyPI, crates.io none
nyc_acris NYC ACRIS none
uk_overseas_property HM Land Registry OCOD bulk

¹ SEC requires a declared User-Agent. Set contact_email in the case file.

Registry catalog — 30 registries across ~20 jurisdictions, with un-automatable ones marked so you know where to search by hand:

paytrace registries --jurisdiction IN
paytrace registries --yields beneficial_owner
paytrace registries --coverage

Planted identifiers

High-selectivity identifiers are also high-forgeability identifiers. Pasting a competitor's ca-pub- into your page source costs nothing.

adversarial.py runs four checks before a shared ID becomes a finding:

Check Question
Reciprocity Does sellers.json name this domain back?
Load-bearing Is the loader present, or is the ID inert text?
Temporal depth Does it have archived history?
Asymmetry Is a tiny site carrying a major property's ID?

Failures demote, never delete — a planted identifier is evidence of someone manufacturing an attribution.


Further reading

The method in depth — sellers.json is not always at the domain root, Expansion from a name, The pivot: the answer is on a sibling, not the seed, The pivot loop — the seed is not the answer, The sibling pivot, Egress and geography, Company registers are not uniform, Source coverage, Mandated disclosures — where the name actually is, Fingerprinting: IPs, hashes, SimHash, DIRECT does not mean direct, Build the corpus first, Replacing paid APIs, Portfolio expansion, Ingest from other tools, Agent + prompt injection demo, Person-scoped collectors — is in docs/GUIDE.md.

Security

  • SSRF guard. adsystem comes from the target's ads.txt, so 169.254.169.254, 1, DIRECT would reach cloud metadata. Every URL is validated before connecting: scheme, userinfo, port, and DNS resolution against private/reserved ranges. Redirects re-checked per hop.
  • ReDoS-bounded regexes, response size caps, parameterised SQL.
  • bandit and pip-audit in CI. Tests in tests/test_security.py.

Deploying

DEPLOYMENT.md. Run investigations outside the repo:

mkdir -p ~/cases/CASE-001 && cd ~/cases/CASE-001
paytrace run --case case.yaml --index ~/corpus/paytrace.sqlite --out .

Known limitations

METHODOLOGY_AUDIT.md is an adversarial read of this toolkit, written as if by a reviewer with no stake in it. Read it before relying on a number.

The governing limitation: calibration is unvalidated. Every probability is a defensible ordering, not a measured frequency. And of nine identified failure modes, four bias toward overconfidence and none bias low — an asymmetry that is a direct consequence of having nothing fitted to catch it.

Status

See CHANGELOG.md. Pre-release; API unstable. is_confidential: 1 suppresses the seller name (you keep seller_type). EDGAR's full-text endpoint is undocumented — pin a contract test.


Author

Tushar Karumudi — github.com/tusharkarumudi

License

Copyright 2026 Tushar Karumudi.

Licensed under the Apache License, Version 2.0. See LICENSE.

Cite via CITATION.cff.

Metadata

Release files for paytrace 2.0.16

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for paytrace 2.0.16
File Size Uploaded
paytrace-2.0.16.tar.gz 242.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for paytrace 2.0.16
File Interpreter ABI Platform
paytrace-2.0.16-py3-none-any.whl Python 3 none any Details

Total release size: 420.5 kB

Release files / paytrace-2.0.16.tar.gz

Download URL paytrace-2.0.16.tar.gz
Size 242.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2b0cbc3ed73152ab311976e5b44f4bf17cfe804ae107561b0cc67b61cdfaa61d
BLAKE2b-256 checksum
How to use checksums
ee5e4898eeee06c6900bff82d12c37b234fa73b799c52eedba4dd5a0609dcfcc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / paytrace-2.0.16-py3-none-any.whl

Download URL paytrace-2.0.16-py3-none-any.whl
Size 177.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d030789ef785fc6a70eb962a706fff1a3d2ab295deeb0b702e2561803acc8c91
BLAKE2b-256 checksum
How to use checksums
69eae0d0609ee9270d7472831dad24691e444905a0d880718f084f691fc763b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

2.0.19

2 release files

2.0.18

2 release files

2.0.17

2 release files

This release

2.0.16 This release

2 release files

2.0.14

2 release files

2.0.11

2 release files

2.0.9

2 release files

2.0.8

2 release files

2.0.7

2 release files

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

2.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page