Summary
Let an Actor surface short, human-readable advisory messages — "tips" — about its own run, using a reserved key-value store key (TIP) with the same lightweight convention as OUTPUT. No new platform APIs or schema changes required; any consumer that already knows to read OUTPUT can equally read TIP.
Motivation
Actors sometimes know something useful about a run that isn't itself a result:
- "You pointed Start URLs at
instagram.com — there's a specialized Actor built for scraping that site."
- "You set
maxItems to 1 but maxConcurrency to 50 — these don't interact the way you might expect." (this might be more valid for other actors though)
Today there's no place to put this. It doesn't belong in the dataset (a tip isn't a data row and would corrupt exports/schema validation), and there's no existing "advisory" channel on the KVS. This proposal gives Actors a standard, zero-infrastructure way to emit that message, and gives any downstream reader (Console, MCP tool wrapper, apify-client, custom scripts) a predictable place to look for it.
Proposed solution
- Reserve a KVS key named
TIP (naming TBD — see Open Questions), written via the SDK the same way OUTPUT is today:
await Actor.setValue('TIP', {
message: 'Start URL matches a site with a dedicated Actor: apify/website-content-crawler.',
level: 'info', // e.g. info | warning
});
- No schema is enforced platform-side, matching the
OUTPUT precedent — the shape above is a suggested convention, not a contract.
- Readers fetch it exactly like any other KVS record:
GET /v2/key-value-stores/:id/records/TIP, or via client.keyValueStore(id).getRecord('TIP').
- Consumers decide what to do with it. In particular, an MCP-tool wrapper around Actor runs can prepend the tip as a
content text block ahead of the dataset-items result, since content is the part MCP clients reliably forward into model context.
What this does and doesn't cover
- ✅ Actor-authored tips (contradictory inputs, ecosystem suggestions, anything the Actor's own code can detect).
- ❌ Platform-generated tips (e.g. "this run OOM'd, try more memory") — the Actor process can't reliably self-report if it was killed, so that case needs a separate platform-side writer feeding the same key, or a different delivery route entirely. Out of scope for this proposal.
Example end-to-end flow
- Actor code detects an issue during a run and calls
Actor.setValue('TIP', {...}).
- Run finishes; the KVS record persists as normal.
- A consumer (e.g. the MCP server wrapping this Actor as a tool) fetches the
TIP record after the run completes and surfaces it however fits — inline text before results, a Console banner, etc.
Open questions
- Naming.
TIP vs. TIPS (singular vs. list-shaped) vs. something else — also needs to avoid colliding with the existing "Actor Issues" feature conceptually.
- Single value vs. list. Should this support multiple tips per run, or just the latest overwrite (like
statusMessage)?
- Recommendation: Single value
- Suggested schema. Do we publish a recommended shape (
message, level, maybe code) so consumers can rely on some structure, or leave it fully freeform like OUTPUT?
- Discoverability. How do consumers know an Actor supports tips at all — documentation convention only, or something declared in
actor.json?
- Will be decided after implementation as next step.
Non-goals
- No changes to
apify-core, the Run entity, or dataset-item response shapes.
- No guarantee of visibility outside consumers that explicitly choose to read the
TIP key.
Summary
Let an Actor surface short, human-readable advisory messages — "tips" — about its own run, using a reserved key-value store key (
TIP) with the same lightweight convention asOUTPUT. No new platform APIs or schema changes required; any consumer that already knows to readOUTPUTcan equally readTIP.Motivation
Actors sometimes know something useful about a run that isn't itself a result:
instagram.com— there's a specialized Actor built for scraping that site."maxItemsto1butmaxConcurrencyto50— these don't interact the way you might expect." (this might be more valid for other actors though)Today there's no place to put this. It doesn't belong in the dataset (a tip isn't a data row and would corrupt exports/schema validation), and there's no existing "advisory" channel on the KVS. This proposal gives Actors a standard, zero-infrastructure way to emit that message, and gives any downstream reader (Console, MCP tool wrapper, apify-client, custom scripts) a predictable place to look for it.
Proposed solution
TIP(naming TBD — see Open Questions), written via the SDK the same wayOUTPUTis today:OUTPUTprecedent — the shape above is a suggested convention, not a contract.GET /v2/key-value-stores/:id/records/TIP, or viaclient.keyValueStore(id).getRecord('TIP').contenttext block ahead of the dataset-items result, sincecontentis the part MCP clients reliably forward into model context.What this does and doesn't cover
Example end-to-end flow
Actor.setValue('TIP', {...}).TIPrecord after the run completes and surfaces it however fits — inline text before results, a Console banner, etc.Open questions
TIPvs.TIPS(singular vs. list-shaped) vs. something else — also needs to avoid colliding with the existing "Actor Issues" feature conceptually.TIPstatusMessage)?message,level, maybecode) so consumers can rely on some structure, or leave it fully freeform likeOUTPUT?actor.json?Non-goals
apify-core, the Run entity, or dataset-item response shapes.TIPkey.