I published four data actors on a marketplace. They pull Korean real estate transaction records from a government open API and normalize them. The point was to test one axis for real: assets whose customer is a machine, not a person.
From the day after launch, a tracking script appended one line per day to a ledger. For three days straight it was the same line.
{"listed": false, "u30": null, "gate": "D-27 · ?/5 · indexed 0/4"}listed: false. Not showing up in store search. I read that as "new actors, indexing lag" and waited three days.
When your ledger says "not there," what exactly isn't there?
On day four I hit the API myself — the same public endpoint the script uses.
curl "https://api.apify.com/v2/store?username=ootssu&limit=50"The response was odd.
{"data": {"total": 4, "items": []}}Total is 4, but items is empty. They aren't missing. They're being counted and withheld.
Back to the docs, and there was a parameter:
curl "https://api.apify.com/v2/store?username=ootssu&limit=50&includeUnrunnableActors=true"{"data": {"total": 4, "items": [
"korea-apartment-transaction-prices",
"korea-commercial-property-prices",
"korea-officetel-prices",
"korea-apartment-rent-prices"
]}}All four. They had been indexed from the start.
The docs spell it out: default results exclude "Actors that are not safe to run automatically" — for example, actors from developers who haven't passed KYC, or full-permission actors without a large user base. Mine were limited-permission, so the remaining reason was account verification.
What I "fixed" during those three days
This is the embarrassing part. Having read listed: false as "not published," here's what I did:
- Compared my actors' public API fields against a well-ranked competitor's, field by field
- Noticed mine had no
pictureUrland theirs did - Designed and uploaded four logos
- Searched again → still 0/4
The logos should exist. That work wasn't waste. But it wasn't the cause. I was fixing a different defect standing next to the symptom, while the actual cause sat in the account settings screen as a sentence:
Billing details and payment method not set
The console had been telling me the whole time. I was staring at API responses instead.
Where would you look?
When your thing isn't in a list, there are usually three explanations:
- My item is deficient — fill in metadata, images, descriptions
- It never went up — redo the publishing flow
- It went up and isn't being shown — check filters, permissions, verification state
I spent three days oscillating between 1 and 2. Checking 3 first would have taken ten minutes. And the way you check 3 is usually one line: does the count match the list? When total and len(items) disagree, that's not absence — that's a filter.
My instrumentation collapsed two states into one value
The real defect wasn't in the API. It was in my tracker. It only ever asked: "Are my items in the search results?" If not, it wrote listed: false.
That single value flattened two completely different states:
- Not published → action: complete the publishing flow
- Published but filtered out → action: finish account verification
Different causes, different work. Log them as the same value and you spend three days doing the wrong thing. Which is exactly what happened.
I split them:
found = store_rows() # discoverable by a human searching
indexed = store_rows(include_hidden=True) # includes indexed-but-filteredAnd the ledger line changed:
gate: "not started · ?/5 · visible 0/4 (indexed 4)"
note: "indexed 4/4 but zero default-search visibility — hidden by the safety filter (KYC presumed)"Now that one line tells me what to do next.
And I moved the decision date
There was a second consequence. These actors carried a verdict: "5 or more external users 30 days after publication." Published 08-19, judge on 09-18.
But as I'd just confirmed, from publication until now they were undiscoverable through search. The entire front of the observation window was a period in which inbound traffic was impossible. Counting users on 09-18 wouldn't measure "do machines use this data" — it would measure "when did verification finish."
So I pulled the decision date off a fixed constant:
# The decision date is not publication + 30. It is **first-visible-day + 30**.
# The first visible day is derived from the oldest ledger row with listed=true.
judge_on = _add_days(exposure_started_on(), OBSERVE_DAYS)Before visibility begins, judge_on is null and the gate reads "not started." The date arithmetic ships with a self-check covering month-end, year-end, and leap-year rollovers — because a decision date that slips by one day is a different experiment.
A three-line self-check
If you've published something to an external platform and you're stuck on "why isn't it showing," check these before touching code.
- Does the response's count match the list length?
total: 4, items: []is a filter, not an absence. - Does that listing API have an "include hidden" parameter? Read the parameter table to the end. A default is usually removing something quietly.
- Does your tracker distinguish "missing" from "hidden"? Collapse them and you'll take the same action for different causes.
The honest part
This misdiagnosis cost three days and four logos. The logos were needed anyway, so the real loss is three days. Not large.
What's unsettling isn't the three days — it's that I trusted the ledger and kept making decisions on top of it. listed: false wasn't lying. It answered exactly the question it had been asked. That just wasn't the question I wanted answered.
When building instrumentation, the first question isn't "what does this value say." It's "is this value writing two different states as the same number?" It's the same disease as letting a failure masquerade as empty data — there, exit 0 looked like success; here, an empty array looked like absence.
Is something in your stack currently logging "not there"? Run one curl today and find out whether it means absence or a filter.