Keep what your scrapers and pipelines collect

Collectors fetch the same pages, images and files again and again. Send everything to Stow (usestow.com) as it arrives: identical files are stored once, each file carries the tags and folder you give it, and every app that uses the data searches one library.

Collected data is easy to lose

  • A crash halfway through a run loses everything that was only held in memory.
  • Running a collector again stores the same files a second time.
  • Raw files end up on one machine’s disk, out of reach of the apps that need them.

How Stow handles it

Store as you go

Upload each file the moment you fetch it. If the run dies at item 500, the first 499 are already stored.

Duplicates stored once

Upload the same bytes again and Stow answers 200 with the file it already has instead of making a copy. To skip the upload entirely, look the file up by its SHA-256 hash first.

Sorted on arrival

Tag each upload with where it came from, like source:filings or ticker:AAPL. Give the collector a subfolder tag and files sort into a folder per value.

Private when it isn’t yours to publish

Collected material you don’t have the right to share goes in as private: no public link, readable only with your keys.

Used by every app

Your analysis jobs, dashboards and AI agents search the same library, each with its own key.

What it looks like

A Python collector that skips files it already stored and keeps the rest private.
import hashlib, json, os, requests

STOW = "https://api.usestow.com"
HEADERS = {"Authorization": f"Bearer {os.environ['STOW_API_KEY']}"}

def store(content: bytes, filename: str, tags: list[str]) -> dict:
    # Already stored? Skip the upload.
    digest = hashlib.sha256(content).hexdigest()
    found = requests.get(f"{STOW}/v1/assets/by-content-hash/{digest}", headers=HEADERS)
    if found.status_code == 200:
        return found.json()

    res = requests.post(
        f"{STOW}/v1/assets",
        headers=HEADERS,
        files={"file": (filename, content)},
        data={"visibility": "private", "metadata": json.dumps({"tags": tags})},
    )
    res.raise_for_status()
    return res.json()

More in the docs: Duplicates · Folders and subfolder tags · Errors and limits

Questions

What happens when a collector uploads a file Stow already has?
Stow answers 200 with the existing file instead of storing a copy. Identical bytes are recognized by their SHA-256 hash, whatever the file is called.
Can I check whether a file is stored before uploading it?
Yes. Hash the bytes with SHA-256 and call GET /v1/assets/by-content-hash/{hash}. A 404 means Stow doesn’t have it yet.
How many requests can a collector make?
Free includes 10,000 API requests a day, Pro 500,000 and Scale 5,000,000. Paid plans can go past their limits with overage billing.
Should collected files be public?
Only if you have the right to publish them. Upload everything else as private: it gets no public link, and only your keys can read it.

Try Stow free

The free plan holds 500 files for up to 2 apps, with no card needed. Upgrade when you want more room, or automatic transcripts, summaries and tags.

More use cases