Skip to content
Get Started

Cloud Events

Every meaningful thing a player does in your game might generate a timestamped event — matches played, items purchased, milestones reached, sessions started and ended. Studios capture this data across backend game servers, telemetry pipelines, and analytics exports, but it often accumulates in cloud storage without ever reaching the engagement systems that could act on it.

Cloud Events bridges that gap. The S3 ingestion pipeline lets you point FirstLook at your own Amazon S3 bucket and automatically import player event data from CSV files. Once ingested, these events flow into the same analytics, retention charts, and player profiles as data collected through the FirstLook SDK — giving you a single, unified view of every player’s journey.

  • Monitors your S3 bucket for new CSV files on a recurring schedule, so you can drop files and walk away.
  • Resolves player identity from platform IDs (Steam, Discord, Xbox, PlayStation, and more) to unified FirstLook player profiles — automatically creating new player records when a platform ID is seen for the first time.
  • Appends events to each player’s chronological record, powering retention metrics, event charts, cohort segmentation, and campaign targeting.
  • Surfaces processing status in the dashboard so you always know which files succeeded, which had issues, and what went wrong.

Before FirstLook can read from your bucket, you’ll need to create an IAM role that grants cross-account read access. This keeps your credentials secure — FirstLook assumes the role temporarily using AWS STS and never stores long-lived keys.

Create a new IAM policy in your AWS account with the following permissions. Replace YOUR_BUCKET_NAME with your actual bucket name, and optionally scope the prefix to a subdirectory.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::YOUR_BUCKET_NAME",
"arn:aws:s3:::YOUR_BUCKET_NAME/*"
]
}
]
}

Create an IAM role and attach the policy above. Then configure its trust policy to allow FirstLook’s AWS account to assume it. Contact the FirstLook team for the account ID to use in your trust policy.

The trust policy must include an External ID condition to prevent confused deputy attacks. You’ll find your unique External ID on the S3 Configuration page in the dashboard after saving your initial configuration.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::409257555035:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "YOUR_EXTERNAL_ID"
}
}
}
]
}

Replace YOUR_EXTERNAL_ID with the value shown on your S3 Configuration page.

Navigate to Configuration > S3 Events > S3 Configuration in your game’s dashboard and enter:

  • IAM Role ARN — The ARN of the role you just created (e.g. arn:aws:iam::123456789012:role/FirstLookIngestion).
  • External ID(Read-only) A unique identifier generated by FirstLook. Copy this value and add it to your IAM role’s trust policy as shown above.
  • Bucket — Your S3 bucket name.
  • Prefix(Optional) A path prefix to limit which directory FirstLook scans, such as events/.
  • AWS Region — The region where your bucket lives (e.g. us-east-1).
  • Enabled — Toggle ingestion on or off at any time.

Once saved, FirstLook will begin scanning your bucket for CSV files every few minutes.


FirstLook accepts CSV files with either a Counter schema or a Duration schema. Each file should contain events of one type — the schema is detected automatically based on the column headers present.

  • Delimiters: Comma (,), tab, semicolon (;), and pipe (|) are all supported. FirstLook auto-detects the delimiter from your file’s header row.
  • Encoding: UTF-8 is expected. Excel-style BOM markers are handled automatically.
  • File size: Up to 200 MB per file. Larger exports should be split into smaller files.

Every CSV must include exactly one player identifier column. FirstLook uses this to resolve each row to a unified player profile. If a platform ID hasn’t been seen before, FirstLook will automatically create a new player record and link it.

Supported identifier columns:

ColumnDescription
player_idFirstLook internal player ID
steam_idSteam ID
discord_idDiscord user ID
xbox_idXbox ID
psn_idPlayStation Network ID
epic_idEpic Games ID
roblox_idRoblox user ID
ea_idEA ID
emailPlayer email address
pragma_social_idPragma social ID (UUID)
pragma_player_idPragma player ID (UUID)
apple_idApple ID
google_idGoogle ID
twitch_idTwitch ID
tiktok_idTikTok ID
kick_idKick ID
kid_idKrafton ID
ioi_idIOI ID
chzzk_idCHZZK ID

Use the counter schema when each row represents a discrete event with a numeric value — kills in a match, items purchased, currency earned, etc.

Required columns:

ColumnTypeDescription
session_idUUIDGroups events in a play session.
timestampISO 8601 datetimeWhen the event occurred (e.g. 2026-01-15T14:30:00Z).
counter_nameStringDot-separated event name (e.g. match.kills).
counter_valueIntegerThe event value (e.g. kill count).
(identifier)StringOne player identity column from the table above.

Optional columns:

ColumnTypeDescription
build_versionStringThe game build version that generated the event.

Example:

steam_id,session_id,timestamp,counter_name,counter_value,build_version
76561198012345678,a1b2c3d4-e5f6-7890-abcd-ef1234567890,2026-01-15T14:30:00Z,match.kills,7,1.2.0
76561198012345678,a1b2c3d4-e5f6-7890-abcd-ef1234567890,2026-01-15T14:30:00Z,match.deaths,3,1.2.0
76561198087654321,b2c3d4e5-f6a7-8901-bcde-f12345678901,2026-01-15T15:00:00Z,store.purchase,1,1.2.0

Use the duration schema when each row represents a timed activity — match length, time in a menu, loading screen duration, etc.

Required columns:

ColumnTypeDescription
session_idUUIDGroups events in a play session.
start_timeISO 8601 datetimeWhen the activity started.
end_timeISO 8601 datetimeWhen the activity ended.
duration_nameStringDot-separated event name (e.g. match.round).
(identifier)StringOne player identity column from the table above.

Example:

steam_id,session_id,start_time,end_time,duration_name
76561198012345678,a1b2c3d4-e5f6-7890-abcd-ef1234567890,2026-01-15T14:00:00Z,2026-01-15T14:25:00Z,match.round
76561198012345678,a1b2c3d4-e5f6-7890-abcd-ef1234567890,2026-01-15T14:26:00Z,2026-01-15T14:28:00Z,menu.loadout
76561198087654321,b2c3d4e5-f6a7-8901-bcde-f12345678901,2026-01-15T15:00:00Z,2026-01-15T15:45:00Z,match.round

When FirstLook encounters a platform ID it hasn’t seen before — say a steam_id that doesn’t match any existing player — it automatically creates a new player record and links the identity. This means you can start importing events immediately, even before players have signed up through your FirstLook onboarding flow.

This identity resolution works across all supported platforms, so you can import data using whichever identifier your game server or telemetry system already tracks.


Navigate to Configuration > S3 Events > Monitor in your dashboard to see the status of every file FirstLook has discovered in your bucket.

Each file shows:

  • StatusPending, Processing, Completed, Failed, or No Longer Found (if the file was removed from S3).
  • Rows Processed / Duplicates Skipped / Rows Failed — How many rows were successfully ingested versus how many had issues.
  • Error — A human-readable description of what went wrong, if anything.
  • Reprocess — For failed files, a button to queue the file for another attempt after you’ve fixed the underlying issue.