PHP SDK: One scenario, multiple sources
Yes. One scenario can read several websites and process an incoming message in the same run. The websites do not have to be registered as separate entries under Sites.
Why you still select one site
The selected site determines where results are stored, which record fields apply, who can access the scenario, which agent runs it, and which request settings are used. It is the result location, not an allowlist of domains. A scenario attached to one of your ten registered sites may request pages from the other nine. Even a plan with a one-site limit can request several public domains from that scenario: requests do not create site entries or consume the site-count allowance.
There is a boundary: all records from that run belong to the selected site. They are not automatically distributed to the tables of your other site entries. For a combined table, add Source type, Source ID, and Title fields. Include the source in every emit() key so that the same product ID from two sites cannot overwrite itself.
The selected site's settings, such as loading mode, proxy, timeout, and request rate, apply to the whole scenario. Requesting another URL does not automatically switch to the second site's settings. Use separate scenarios if each site needs independent settings and tables. Every address still passes network safety checks, website rules, and per-domain rate limits.
How to include an email
Publish the scenario and bind an incoming address to it in the mail settings. When a message arrives, the platform starts the same scenario. In that run, mail().available() returns true and mail().current() returns the message that triggered it. The same run function can call http() or browser() for several websites and combine the results.
A manual run, scheduled run, or trial has no incoming message: mail().available() returns false, and the website portion can still run. A scenario cannot browse the entire workspace mailbox at will. It receives only the message tied to its run. For previously collected records or a message supplied as a named input of a composite workflow, use JavaScript Sources or PHP Sources.
PHP and JavaScript examples
Add string fields source_type, source_id, and title to the result site. Set source_urls to an array of addresses in run parameters. This example reads the HTML title for clarity; replace it with product-card fields for a real catalog. Record keys start with the source type so websites and messages remain distinct.
PHP
<?php
function run(\Sdk\Context $ctx): void
{
$urls = $ctx->param('source_urls', []);
if (!is_array($urls)) {
$ctx->abort('Provide a URL list');
}
foreach ($urls as $url) {
$address = (string) $url;
$response = $ctx->http()->get($address);
if (!$response->ok()) {
$ctx->log('Website did not respond', ['url' => $address], 'warning');
continue;
}
$key = 'web:' . $address;
$ctx->emit(['source_type' => 'web', 'source_id' => $key,
'title' => $response->dom()->text('title', '')], $key);
}
if ($ctx->mail()->available()) {
$letter = $ctx->mail()->current();
$key = 'mail:' . $letter['id'];
$ctx->emit(['source_type' => 'mail', 'source_id' => $key,
'title' => $letter['subject'] ?? 'Message'], $key);
}
}
JavaScript
async function run(ctx) {
const urls = ctx.param('source_urls', []);
if (!Array.isArray(urls)) ctx.abort('Provide a URL list');
for (const url of urls) {
const address = String(url);
const response = await ctx.http().get(address);
if (!response.ok()) {
ctx.log('Website did not respond', { url: address }, 'warning');
continue;
}
const key = `web:${address}`;
ctx.emit({ source_type: 'web', source_id: key,
title: response.dom().text('title', '') }, key);
}
if (await ctx.mail().available()) {
const letter = await ctx.mail().current();
const key = `mail:${letter.id}`;
ctx.emit({ source_type: 'mail', source_id: key,
title: letter.subject ?? 'Message' }, key);
}
}
Code validation does not open websites or retrieve messages. First try a short URL list in a trial run. Then configure the mail binding and check a real incoming-message event. Billing follows actual execution and service use; the number of URLs in code does not become the number of registered sites.
Scenarios and publishing · PHP Mail SDK · JavaScript Mail SDK · Limits