Lingam Rajesh
02/12/2026, 9:54 PM/api/users/{id} , but this api only return the api key user information only if i give any other user id it returns 404 not found errorMarvin
02/12/2026, 9:55 PMMarvin
02/12/2026, 9:57 PM/api/users/{id} will return your own user record if {id} matches the user tied to your API key; requests for any other user ID are not exposed and will return 404. This is by design for privacy/permissions.
If your goal is to see who’s in an account or workspace (and their roles), use the memberships endpoints instead (e.g., list account/workspace members). Those return the set of users you’re authorized to view along with role info.
Can you share:
- Which environment you’re calling (base URL)?
- What you’re trying to accomplish (e.g., list all users in a workspace, fetch a specific teammate’s email/role, etc.)?
With that, I can point you to the exact endpoint and a curl example for your case.Lingam Rajesh
02/12/2026, 10:00 PMMarvin
02/12/2026, 10:02 PMMarvin
02/12/2026, 10:05 PMcreated_by with fields like type, id, and display_value. For user-triggered runs, display_value typically includes the user’s name and/or email. For scheduled/automation/service-account runs, there may not be a user email.
Below is a complete script that:
- Resolves a flow run ID from a CLI flag, env var, or the runtime context (if run inside a flow)
- Fetches the flow run
- Prints the best-available creator info and extracts an email from display_value when present
Notes:
- For Prefect Cloud, set PREFECT_API_URL and PREFECT_API_KEY in your environment before running.
- For Prefect Server, set PREFECT_API_URL only.
import argparse
import asyncio
import os
import re
import sys
from prefect.client.orchestration import get_client
# We will try to use the runtime flow run id if the script runs inside a flow
def get_runtime_flow_run_id():
try:
from prefect.runtime import flow_run as runtime_flow_run
return runtime_flow_run.id()
except Exception:
return None
EMAIL_RE = re.compile(r'[\w\.-]+@[\w\.-]+\.\w+')
async def get_creator_info(flow_run_id: str):
async with get_client() as client:
flow_run = await client.read_flow_run(flow_run_id)
created_by = getattr(flow_run, "created_by", None)
if not created_by:
return {
"flow_run_id": flow_run_id,
"creator_type": None,
"creator_id": None,
"display_value": None,
"email": None,
}
display_value = getattr(created_by, "display_value", None)
email = None
if display_value:
m = EMAIL_RE.search(display_value)
if m:
email = m.group(0)
return {
"flow_run_id": flow_run_id,
"creator_type": getattr(created_by, "type", None),
"creator_id": str(getattr(created_by, "id", None)),
"display_value": display_value,
"email": email,
}
def main():
parser = argparse.ArgumentParser(description="Show who created a Prefect flow run.")
parser.add_argument("--flow-run-id", help="Flow run ID to inspect (optional).")
args = parser.parse_args()
flow_run_id = (
args.flow_run_id
or os.environ.get("FLOW_RUN_ID")
or get_runtime_flow_run_id()
)
if not flow_run_id:
print(
"No flow run ID found. Provide one with:\n"
" --flow-run-id <ID>\n"
"or set FLOW_RUN_ID env var, or run this inside a Prefect flow."
)
sys.exit(2)
info = asyncio.run(get_creator_info(flow_run_id))
print("Flow Run:", info["flow_run_id"])
print("Created By Type:", info["creator_type"])
print("Created By ID:", info["creator_id"])
print("Display Value:", info["display_value"])
print("Email (best effort):", info["email"])
if __name__ == "__main__":
main()
What to expect:
- If a human triggered the run, display_value usually contains their name/email and the regex will extract the email.
- If a service account, automation, or the system created the run, there may be no email — the script will show the type and display value.
- Directly querying another user’s full profile from their ID is not exposed via the public API for privacy reasons; relying on created_by.display_value is the supported path.