Wayback Machine Snapshots and Archived Page Content
Pricing
from $0.40 / 1,000 archived snapshots
Wayback Machine Snapshots and Archived Page Content
List every Internet Archive capture of a URL, host or domain from the Wayback Machine CDX index, and optionally pull the archived page text for the latest, earliest or all snapshots.
Pricing
from $0.40 / 1,000 archived snapshots
Rating
0.0
(0)
Developer
Code Craft Colorado
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 hours ago
Last modified
Categories
Share
Find out when the Internet Archive captured a page and what the page said at the time. Give this actor a list of URLs, hosts or whole domains and it returns the matching captures from the Wayback Machine's CDX index, one row per snapshot, with the capture time, HTTP status, content type, compressed size, a content digest and two direct links: the browsable Wayback page and the raw archived copy. Turn on content fetching and it also downloads the archived page and extracts its visible text, for the latest capture of each URL, the earliest, or all of them.
It is built to be left running. Every request goes to the Internet Archive's public CDX and Wayback endpoints over plain HTTP: no API key, no login, no browser, no proxies. The actor identifies itself with a User-Agent that names the operator and a contact address, spaces its requests 500 ms apart, works at most two URLs at a time and retries transient errors with backoff. It reads the index live on every run, so you get whatever the archive holds at that moment, and one URL failing never stops the others.
At a glance
Three consecutive daily captures of apple.com, from a run with fetchContent on and
contentMode set to latest. Only the newest row carries text; the two newest rows share a
digest, which means the archive stored identical content on both days.
capturedAt | statusCode | length | digest | contentText | waybackUrl |
|---|---|---|---|---|---|
2026-09-26T02:58:15Z | 200 | 44288 | 7W6JR7MTQOWG76ALW2DPODITZRH5HS56 | Apple\nApple\nStore\nMac\niPad\niPhone... | https://web.archive.org/web/20260926025815/https://www.apple.com/ |
2026-09-25T11:53:45Z | 200 | 44290 | 7W6JR7MTQOWG76ALW2DPODITZRH5HS56 | null | https://web.archive.org/web/20260925115345/https://www.apple.com/ |
2026-09-24T15:31:13Z | 200 | 44240 | MGCLIVMS3VKWNIWA7MHYHVQDZLQSAJLG | null | https://web.archive.org/web/20260924153113/https://www.apple.com/ |
What data does it extract?
Every row describes one capture. Field names below are exactly as they appear in the dataset.
Which page and when
inputUrl: the URL, host or domain exactly as you gave it.original: the URL the archive actually captured. Withhostordomainmatching this varies from row to row; even withexactit is the archive's canonical form, so an input ofapple.comcomes back ashttps://www.apple.com/.timestamp: the capture time in the archive's 14-digitYYYYMMDDhhmmssform, UTC.capturedAt: the same instant as ISO 8601, for example2026-09-26T02:58:15Z. Null only if the index returned a malformed timestamp.
What was captured
mimetype: the content type recorded at capture time, such astext/htmlorapplication/pdf.statusCode: the HTTP status the archive received when it captured the page. Null when the index has no status for the record.digest: a hash of the captured content. Identical digests mean identical content, so comparing digests across rows tells you which captures actually differ.length: the compressed size of the capture in the archive, in bytes.
Where to see it
waybackUrl: the browsable Wayback Machine page for this capture, with the archive's toolbar.rawUrl: the same capture served without the toolbar, using the archive'sid_form. This is what the actor downloads when fetching content.sourceUrl: the same value aswaybackUrl, kept for consistency with the other actors in this collection.
The page text, when requested
contentText: the visible text of the archived page. Null on rows where content was not requested or not selected bycontentMode.contentSkipped: true when content was requested for this row but not fetched, for example a PDF or an image, or a download that failed.contentSkipReason: why it was skipped, such asunsupported mimetype application/pdf, or the error message from a failed download.
Wayback options explained
matchType: what counts as a match
The value is passed straight to the CDX API's matchType parameter.
| Value | What you get |
|---|---|
exact | Captures of this one URL, in the archive's canonical form. Default. |
prefix | Captures of this URL and every URL that starts with it, such as everything under /blog/. |
host | Captures of every URL on this hostname. |
domain | Captures of every URL on this hostname and all of its subdomains. |
collapse: one capture per period
Popular pages are captured many times a day. Collapsing asks the index to keep only the first capture whose timestamp starts with a given number of digits, so consecutive captures within the same hour, day, month or year fold into one row.
| Value | Timestamp digits compared | Effect |
|---|---|---|
none | none | Every capture the index holds. Default. |
hourly | 10 (YYYYMMDDhh) | At most one capture per hour. |
daily | 8 (YYYYMMDD) | At most one capture per day. |
monthly | 6 (YYYYMM) | At most one capture per month. |
yearly | 4 (YYYY) | At most one capture per year. |
The index compares each capture with the one before it, and it is ordered by URL and then by
time, so with host or domain matching the collapse applies within each URL rather than
across the whole site.
timestamp and capturedAt
The archive addresses every capture by a 14-digit UTC timestamp, YYYYMMDDhhmmss; the
capture at 20260926025815 was taken on 26 September 2026 at 02:58:15 UTC. The row keeps
that string as timestamp, because it is the key you need to build archive URLs, and adds
capturedAt as ISO 8601 for sorting and date arithmetic. The from and to inputs use the
same digits and accept any prefix from YYYY to the full 14.
waybackUrl versus rawUrl
| Field | Shape | Use it for |
|---|---|---|
waybackUrl | https://web.archive.org/web/{timestamp}/{original} | Opening in a browser. The archive rewrites links and adds its toolbar. |
rawUrl | https://web.archive.org/web/{timestamp}id_/{original} | Programmatic access. The id_ flag returns the archived bytes as captured, without the toolbar or rewriting. |
newestFirst and maxSnapshotsPerUrl
maxSnapshotsPerUrl, when set, caps the rows for each input URL after from, to,
onlySuccessful and collapse have been applied. newestFirst decides which end of the
history that cap keeps, and the row order either way.
newestFirst | Rows you get | How the index is read |
|---|---|---|
true (default) | The most recent captures, newest row first; the most recent maxSnapshotsPerUrl of them when a count is set. | One request per URL when a count is set; otherwise the index is walked and the result reversed. |
false | Oldest row first; the oldest maxSnapshotsPerUrl of them when a count is set. | Pages forward through the index with resume keys until the cap is reached or the history ends. |
contentMode: which rows get text
Only used when fetchContent is on. Selection happens among the rows returned for each URL,
so earliest with newestFirst on means the oldest of the most recent captures, not the
oldest capture in the archive. Set newestFirst to false or narrow from and to if you
want the true first capture.
| Value | Text is fetched for |
|---|---|
latest | The single most recent row per input URL. Default. |
earliest | The single oldest row per input URL. |
all | Every row. One download per row, so this is where cost and run time add up. |
onlySuccessful
On by default, this sends filter=statuscode:200 to the index so you only see captures where
the archive received a normal page. Turn it off to see redirects (301, 302), errors (404, 500)
and revisit records, which the archive writes when a capture was byte-identical to an earlier
one. Revisit records have no status of their own, so statusCode is null on those rows.
Input
| Field | Meaning | Default | When to change it |
|---|---|---|---|
urls | URLs, hosts or domains to look up. Required, at least one, no duplicates. | none | Always. |
matchType | exact, prefix, host or domain. | exact | Surveying a section, a site or a domain family rather than one page. |
from | Earliest capture to include, YYYY to YYYYMMDDhhmmss. With no dates and no count, the actor returns the last 30 days. | last 30 days | Limiting the history to a window. |
to | Latest capture to include, same format. | unset | Same. |
onlySuccessful | Keep only HTTP 200 captures. | true | Turn off to see redirects, errors and revisit records. |
collapse | none, hourly, daily, monthly or yearly. | none | daily to thin a busy page; monthly or yearly for a long, sparse timeline. |
maxSnapshotsPerUrl | Stop after this many captures per URL. Applies only when set, and combines with dates to cap a window. | none | Set to 1 for "the latest capture". |
newestFirst | Take the cap from the recent end of the history. | true | Turn off to walk forward from the first capture. |
fetchContent | Download the archived page and add its text. Charged per page fetched. | false | Whenever you need what the page said, not just when it was captured. |
contentMode | latest, earliest or all. | latest | all only when you need every version's text. |
The latest archived text of a few pages, one row per URL. This is the saved task "Latest archived text of a web page"; schedule it to keep a running record.
{"urls": ["apple.com", "https://example.com/pricing"],"maxSnapshotsPerUrl": 1,"fetchContent": true,"contentMode": "latest"}
A change history of one page, one capture per month since 2020, oldest first, with the text of the first capture in the window.
{"urls": ["https://example.com/pricing"],"from": "2020","collapse": "monthly","newestFirst": false,"maxSnapshotsPerUrl": 200,"fetchContent": true,"contentMode": "earliest"}
Everything the archive holds for a site section, including redirects and errors, without content.
{"urls": ["https://example.com/blog/"],"matchType": "prefix","collapse": "none","onlySuccessful": false,"maxSnapshotsPerUrl": 5000}
Listing snapshots costs one request per URL when a count is set with newestFirst on, and
a page of index results per few thousand captures otherwise, so a run over a handful of URLs
finishes in seconds. Content is one extra request per selected row, and all
requests are spaced 500 ms apart, so fetching text for every row of a 1,000-row history takes
at least eight to nine minutes plus the archive's own response time.
Output example
One row from the run shown above; contentText is shortened here.
{"inputUrl": "apple.com","original": "https://www.apple.com/","timestamp": "20260926025815","capturedAt": "2026-09-26T02:58:15Z","mimetype": "text/html","statusCode": 200,"digest": "7W6JR7MTQOWG76ALW2DPODITZRH5HS56","length": 44288,"waybackUrl": "https://web.archive.org/web/20260926025815/https://www.apple.com/","rawUrl": "https://web.archive.org/web/20260926025815id_/https://www.apple.com/","contentText": "Apple\nApple\nStore\nMac\niPad\niPhone\nWatch\nVision\nAirPods\nTV & Home\nEntertainment\nAccessories\nSupport\n0\n+\nGet 3 months of Apple One free with any new iPhone, iPad, or Mac.\n1\nLearn more\niPhone 18 Pro\nPro further.\nLearn more\nBuy\n...","contentSkipped": false,"contentSkipReason": null,"sourceUrl": "https://web.archive.org/web/20260926025815/https://www.apple.com/"}
Rows land in the run's default dataset, which you can view in Console under the Snapshots
tab or download as JSON, CSV, Excel or XML from the dataset's Export menu and the API. Text
extraction drops script, style, noscript and template elements, joins the remaining
text with newlines and collapses runs of whitespace, so contentText is ready for search,
diffing or a language model without further cleanup.
Errors and edge cases
Anything that fails is recorded in a JSON record named ERRORS in the run's default
key-value store, as a list of {"url": ..., "error": ...} objects. The record exists only
when something failed, so its absence means a clean run. The run's status message also
reports the number of errors. Nothing that fails is charged.
- URL with no captures. The index returns nothing, the actor writes zero rows for that
URL and moves on. This is not an error and appears nowhere in
ERRORS. - Index request fails. On 429 or 5xx responses and network errors the actor retries up to
four more times with 1, 2, 4 and 8 second waits. If the last attempt fails, or the index
returns another error immediately, the URL is skipped, an entry goes into
ERRORS, the other URLs continue and no row is charged for it. - Content download fails. The snapshot row is still written and charged as a row, but
with
contentSkippedtrue and the error message incontentSkipReason. TherawUrland the error also go intoERRORS. Thepage-contentevent is not charged. - Binary content. PDFs, images, archives and anything else that is not
text/*or XHTML are not downloaded. The row hascontentSkippedtrue andcontentSkipReasonsuch asunsupported mimetype application/pdf. Not charged as a page fetch. - Non-200 captures and revisit records. Hidden by default. With
onlySuccessfuloff they appear as ordinary rows;statusCodeis null where the index has no status, as it does for revisit records. Content fetching treats them like any other row, so a revisit record selected bycontentModeis skipped as an unsupported type rather than downloaded. - Charge limit reached. If the run hits the maximum charge you set, it stops cleanly and keeps every row already written.
- Empty
urls. The run fails immediately with a message and writes nothing.
How much does it cost?
This actor uses pay-per-event pricing with three events.
- One dataset row per snapshot. Every capture returned counts as one row, whether or not it carries text.
page-content, once per page actually fetched. Charged only whenfetchContentis on, the row was selected bycontentMode, and text was extracted. Skipped binaries, failed downloads and rows outside thecontentModeselection are not charged.- Actor start, Apify's standard per-run event.
Not charged: URLs with no captures, URLs that failed at the index, retries, the ERRORS
record and platform compute, which is included in the event price. The cheapest way to read
a page's history is to list it without content and fetch text only for the rows you need;
contentMode: "all" on a long history is where cost grows. Current rates are on the Pricing
tab of this page.
Use cases
- Find the month a competitor changed its pricing page and read the previous version.
- Recover the text of pages, documentation or announcements that have since gone offline.
- Build a change timeline for a URL by grouping rows on
digestand keeping the first capture of each distinct value. - Check how often a site or domain is being archived and which of its URLs are covered.
- Keep a running record of a page on a schedule, one new row per day, for compliance or research.
- Give an AI agent a tool for questions like "what did this page say in 2021?".
Run it on a schedule, from the API, or from an agent
Create a schedule in Apify Console to run the actor daily or weekly and read the results from the dataset, or start runs from the Apify API and the JavaScript and Python clients with the same input JSON shown above. The actor is also available through Apify's MCP server, so an agent can call it as a tool. Inputs are identical everywhere, and the saved task "Latest archived text of a web page" is a ready-made starting point for a scheduled record.
Related actors
- SEC Form 4 Insider Trades by Ticker: every insider transaction from Form 4 filings, one row per transaction, with role, price, shares, holdings after, and the 10b5-1 flag.
- SEC 13F Holdings by Fund with Quarterly Changes: every position in a fund's 13F filing with the change from the prior quarter, in dollars.
- SEC 8-K Filings by Ticker with Item Codes: 8-K filings with item codes and titles, exhibits, and optional extracted text.
All four run against official public APIs with no proxies or credentials.
FAQ
Is this legal? Yes. The Wayback Machine is a public archive operated by the Internet Archive, and its CDX index and archive URLs are public endpoints. This actor identifies itself with a User-Agent that names the operator and a contact address, spaces requests 500 ms apart, works at most two URLs at a time, retries with backoff rather than hammering, and downloads only the pages you ask for. What you do with archived content of a third party's site is governed by that content's copyright as it would be if you read it in a browser.
Why do I get fewer rows than expected? Three inputs thin the history: collapse keeps
one capture per period when set, onlySuccessful drops redirects, errors and revisit
records, and with no dates and no count only the last 30 days are returned. Set from, turn
onlySuccessful off and leave collapse at none to see everything the archive holds.
Why is original different from the URL I entered? The index matches on the archive's
canonical form of a URL, so apple.com matches captures stored as https://www.apple.com/.
inputUrl always keeps what you typed; original tells you what was actually captured.
Why is contentText null on most rows? Text is fetched only for the rows selected by
contentMode, which by default is the latest capture per URL. Other rows keep
contentSkipped false and contentText null because content was never requested for them.
Rows where content was requested but could not be fetched have contentSkipped true and a
reason.
Can I get the archived HTML instead of the text? Not from this actor; it returns
extracted text. Every row carries rawUrl, which serves the archived bytes exactly as
captured, so you can download the HTML yourself for any capture you care about.
Does it save new pages to the archive? No. It only reads the index and existing captures. It never asks the Wayback Machine to capture anything.
How do I tell which captures actually changed? Compare digest. In the sample above the
captures of 26 and 25 September share a digest, so the page was byte-identical on both days,
while the 24 September capture differs.
Do I need an API key, a proxy or a browser? No. All requests are plain HTTP to the Internet Archive's public endpoints from Apify's own infrastructure.
What happens when the Wayback Machine is slow or returns errors? Requests use a 60 second
timeout and retry on 429 and 5xx responses and network failures, five attempts in total with
exponential backoff. A URL that still fails is recorded in ERRORS, not charged, and does not
stop the rest of the run.
Something is missing or wrong? Open an issue on this actor's Issues tab with the input you used and the run ID, and it will be looked at.