<@ULVA73B9P> Can I get the email of the Prefect Cl...
# ask-marvin
j
@Marvin Can I get the email of the Prefect Cloud user that triggered a deployment from within the flow, to send them a summary email with the results of the flow?
m
thought for 482.2 seconds
Short answer: mostly yes. In Prefect 3.x you can fetch the creator of the current flow run from the API during execution. The FlowRun object returned by the API includes a
created_by
field with
id
,
type
, and
display_value
. In Prefect Cloud,
display_value
is typically the user’s email when a human manually starts a run from the UI. For runs started by schedules, automations, or service accounts, it will reflect those instead (not a user email). Here’s how to get it inside your flow: Async flow example
Copy code
from prefect import flow
from prefect.runtime import flow_run as runtime_flow_run
from prefect.client.orchestration import get_client

@flow
async def my_flow():
    # Prefer the root run’s creator in case this is a subflow
    flow_run_id = runtime_flow_run.root_flow_run_id() or runtime_flow_run.id()

    async with get_client() as client:
        fr = await client.read_flow_run(flow_run_id)

    creator = getattr(fr, "created_by", None)
    email = None
    if creator and getattr(creator, "display_value", None):
        # For user-initiated runs in Cloud, this is usually the email
        dv = creator.display_value
        if "@" in dv:
            email = dv

    # Use `email` if present to send your summary
    return {"creator": creator, "email": email}
Sync flow example
Copy code
from prefect import flow
from prefect.runtime import flow_run as runtime_flow_run
from prefect.client.orchestration import SyncPrefectClient

@flow
def my_flow():
    flow_run_id = runtime_flow_run.root_flow_run_id() or runtime_flow_run.id()
    with SyncPrefectClient() as client:
        fr = client.read_flow_run(flow_run_id)

    creator = getattr(fr, "created_by", None)
    email = None
    if creator and getattr(creator, "display_value", None):
        dv = creator.display_value
        if "@" in dv:
            email = dv

    return {"creator": creator, "email": email}
Notes and limitations - Manual runs: For a run started by a logged-in Cloud user via the UI,
created_by.display_value
is typically that user’s email. - Non-user triggers: For schedules, automations, or service accounts,
created_by.type
will reflect those and
display_value
won’t be a user email. - Subflows: A subflow’s own
created_by
may be “system”; use
root_flow_run_id()
to fetch the top-level run’s
created_by
as shown above. - Robustness: Since
display_value
is not guaranteed to be an email, a more deterministic approach is to pass a
notify_email
parameter when manually triggering the run in the UI and use that inside the flow. Helpful links - Access runtime info: Access runtime info - Python client usage: API client guide - REST API: read a flow run (includes created_by): GET /api/flow-runs/{id} If you confirm how your runs are typically triggered (manual vs schedule/automation), I can tailor a small snippet to populate recipients and send the email right in the flow.