
Profiles: Your Agent's Persistent Identity
Profiles: Your Agent's Persistent Identity
Profiles: Your Agent's Persistent Identity
/
/
San Francisco
San Francisco
/
/

Hussien Hussien
Hussien Hussien

Think Chrome profiles. You have one for work, one for personal browsing, maybe one for testing. Each remembers its own logins, cookies, and settings. Steel Profiles work the same way — but you can spin them up programmatically for your agents.
Before today, every Steel session started fresh. Your agent would log in, complete a task, and when the session ended, everything was forgotten. Cookies cleared. Auth tokens gone. Next run? Log in again.
Now your agents can maintain persistent browser identities across sessions.

How It Works
A Profile stores browser state: cookies, extensions, credentials, localStorage, auth tokens, and fingerprints. When you start a session with a profileId, the browser loads that state. The agent picks up effectively where it left off — still logged in, still authenticated.
Here's the simplest case—an agent that needs to stay logged in across multiple runs:
// Day 1: Agent logs in and completes a task const session = await client.sessions.create({ persistProfile: true }); const browser = await chromium.connectOverCDP( `wss://connect.steel.dev?apiKey=${apiKey}&sessionId=${session.id}` ); const page = await browser.contexts()[0].pages()[0]; await page.goto('https://app.example.com/login'); await page.fill('#email', 'agent@company.com'); await page.fill('#password', process.env.PASSWORD); await page.click('#login-button'); // Session ends, state is saved await client.sessions.release(session.id); console.log(`Profile ID: ${session.profileId}`); // Day 2: Resume where you left off const resumedSession = await client.sessions.create({ profileId: session.profileId // Still logged in });
// Day 1: Agent logs in and completes a task const session = await client.sessions.create({ persistProfile: true }); const browser = await chromium.connectOverCDP( `wss://connect.steel.dev?apiKey=${apiKey}&sessionId=${session.id}` ); const page = await browser.contexts()[0].pages()[0]; await page.goto('https://app.example.com/login'); await page.fill('#email', 'agent@company.com'); await page.fill('#password', process.env.PASSWORD); await page.click('#login-button'); // Session ends, state is saved await client.sessions.release(session.id); console.log(`Profile ID: ${session.profileId}`); // Day 2: Resume where you left off const resumedSession = await client.sessions.create({ profileId: session.profileId // Still logged in });
Persist or Read-Only
When using an existing profile, you control whether changes write back:
// Read from profile, build on its history const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: true // Appends new cookies, state changes }); // Read from profile, keep it unchanged const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: false // Default: no state mutation });
// Read from profile, build on its history const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: true // Appends new cookies, state changes }); // Read from profile, keep it unchanged const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: false // Default: no state mutation });
Set persistProfile: true when you want to update the profile with new authentication state or app data. Keep it false for read-only operations or when running parallel sessions that shouldn't interfere with each other.
Human-in-the-Loop Setup
For complex auth flows, you can set up profiles manually. Create a session, open the debug URL, and handle the tricky parts yourself:
const session = await client.sessions.create({ persistProfile: true }); console.log(`Complete auth here: ${session.sessionViewerUrl}`); // Open the URL, handle 2FA, solve CAPTCHAs, accept terms, etc. // Wait for manual completion... await new Promise(resolve => setTimeout(resolve, 60000)); // Release the session - your auth state is saved await client.sessions.release(session.id); // Now your agent uses your authenticated state const agentSession = await client.sessions.create({ profileId: session.profileId });
const session = await client.sessions.create({ persistProfile: true }); console.log(`Complete auth here: ${session.sessionViewerUrl}`); // Open the URL, handle 2FA, solve CAPTCHAs, accept terms, etc. // Wait for manual completion... await new Promise(resolve => setTimeout(resolve, 60000)); // Release the session - your auth state is saved await client.sessions.release(session.id); // Now your agent uses your authenticated state const agentSession = await client.sessions.create({ profileId: session.profileId });
Handle 2FA, CAPTCHAs, or SSO flows once, then let your agent reuse that authenticated state for all future runs.
Why This Matters
No repeated authentication: Your agent logs in once. Every subsequent session picks up with valid auth tokens and cookies already in place.
Better stealth: Profiles build browsing history and reputation. Sites see a returning user, not a fresh bot on every request. Fewer CAPTCHAs, less anti-bot friction.
Multi-tenant workflows: Each customer gets their own profile. One authentication per tenant, reused across all their agent operations.
Parallel testing: Fork a baseline profile to test different agent strategies without sessions interfering with each other's state.
Simpler infrastructure: No more managing cookie jars in Redis or session blobs in S3. Steel handles state persistence, encryption, and retrieval.
Available Now
The Profiles API is live today in Steel Cloud, plus Python(v0.11.0+) and Node SDKs (v0.12.0+).
Get started:
Questions or want to share what you build? Join us in Discord or tag us on Twitter @steeldotdev.
This is part of Steel's launch week. More features dropping daily at steel.dev/launch-week.
Think Chrome profiles. You have one for work, one for personal browsing, maybe one for testing. Each remembers its own logins, cookies, and settings. Steel Profiles work the same way — but you can spin them up programmatically for your agents.
Before today, every Steel session started fresh. Your agent would log in, complete a task, and when the session ended, everything was forgotten. Cookies cleared. Auth tokens gone. Next run? Log in again.
Now your agents can maintain persistent browser identities across sessions.

How It Works
A Profile stores browser state: cookies, extensions, credentials, localStorage, auth tokens, and fingerprints. When you start a session with a profileId, the browser loads that state. The agent picks up effectively where it left off — still logged in, still authenticated.
Here's the simplest case—an agent that needs to stay logged in across multiple runs:
// Day 1: Agent logs in and completes a task const session = await client.sessions.create({ persistProfile: true }); const browser = await chromium.connectOverCDP( `wss://connect.steel.dev?apiKey=${apiKey}&sessionId=${session.id}` ); const page = await browser.contexts()[0].pages()[0]; await page.goto('https://app.example.com/login'); await page.fill('#email', 'agent@company.com'); await page.fill('#password', process.env.PASSWORD); await page.click('#login-button'); // Session ends, state is saved await client.sessions.release(session.id); console.log(`Profile ID: ${session.profileId}`); // Day 2: Resume where you left off const resumedSession = await client.sessions.create({ profileId: session.profileId // Still logged in });
Persist or Read-Only
When using an existing profile, you control whether changes write back:
// Read from profile, build on its history const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: true // Appends new cookies, state changes }); // Read from profile, keep it unchanged const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: false // Default: no state mutation });
Set persistProfile: true when you want to update the profile with new authentication state or app data. Keep it false for read-only operations or when running parallel sessions that shouldn't interfere with each other.
Human-in-the-Loop Setup
For complex auth flows, you can set up profiles manually. Create a session, open the debug URL, and handle the tricky parts yourself:
const session = await client.sessions.create({ persistProfile: true }); console.log(`Complete auth here: ${session.sessionViewerUrl}`); // Open the URL, handle 2FA, solve CAPTCHAs, accept terms, etc. // Wait for manual completion... await new Promise(resolve => setTimeout(resolve, 60000)); // Release the session - your auth state is saved await client.sessions.release(session.id); // Now your agent uses your authenticated state const agentSession = await client.sessions.create({ profileId: session.profileId });
Handle 2FA, CAPTCHAs, or SSO flows once, then let your agent reuse that authenticated state for all future runs.
Why This Matters
No repeated authentication: Your agent logs in once. Every subsequent session picks up with valid auth tokens and cookies already in place.
Better stealth: Profiles build browsing history and reputation. Sites see a returning user, not a fresh bot on every request. Fewer CAPTCHAs, less anti-bot friction.
Multi-tenant workflows: Each customer gets their own profile. One authentication per tenant, reused across all their agent operations.
Parallel testing: Fork a baseline profile to test different agent strategies without sessions interfering with each other's state.
Simpler infrastructure: No more managing cookie jars in Redis or session blobs in S3. Steel handles state persistence, encryption, and retrieval.
Available Now
The Profiles API is live today in Steel Cloud, plus Python(v0.11.0+) and Node SDKs (v0.12.0+).
Get started:
Questions or want to share what you build? Join us in Discord or tag us on Twitter @steeldotdev.
This is part of Steel's launch week. More features dropping daily at steel.dev/launch-week.
Think Chrome profiles. You have one for work, one for personal browsing, maybe one for testing. Each remembers its own logins, cookies, and settings. Steel Profiles work the same way — but you can spin them up programmatically for your agents.
Before today, every Steel session started fresh. Your agent would log in, complete a task, and when the session ended, everything was forgotten. Cookies cleared. Auth tokens gone. Next run? Log in again.
Now your agents can maintain persistent browser identities across sessions.

How It Works
A Profile stores browser state: cookies, extensions, credentials, localStorage, auth tokens, and fingerprints. When you start a session with a profileId, the browser loads that state. The agent picks up effectively where it left off — still logged in, still authenticated.
Here's the simplest case—an agent that needs to stay logged in across multiple runs:
// Day 1: Agent logs in and completes a task const session = await client.sessions.create({ persistProfile: true }); const browser = await chromium.connectOverCDP( `wss://connect.steel.dev?apiKey=${apiKey}&sessionId=${session.id}` ); const page = await browser.contexts()[0].pages()[0]; await page.goto('https://app.example.com/login'); await page.fill('#email', 'agent@company.com'); await page.fill('#password', process.env.PASSWORD); await page.click('#login-button'); // Session ends, state is saved await client.sessions.release(session.id); console.log(`Profile ID: ${session.profileId}`); // Day 2: Resume where you left off const resumedSession = await client.sessions.create({ profileId: session.profileId // Still logged in });
Persist or Read-Only
When using an existing profile, you control whether changes write back:
// Read from profile, build on its history const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: true // Appends new cookies, state changes }); // Read from profile, keep it unchanged const session = await client.sessions.create({ profileId: 'bc252fdd-0c22-43ae-9e53-c2ffaba1108a', persistProfile: false // Default: no state mutation });
Set persistProfile: true when you want to update the profile with new authentication state or app data. Keep it false for read-only operations or when running parallel sessions that shouldn't interfere with each other.
Human-in-the-Loop Setup
For complex auth flows, you can set up profiles manually. Create a session, open the debug URL, and handle the tricky parts yourself:
const session = await client.sessions.create({ persistProfile: true }); console.log(`Complete auth here: ${session.sessionViewerUrl}`); // Open the URL, handle 2FA, solve CAPTCHAs, accept terms, etc. // Wait for manual completion... await new Promise(resolve => setTimeout(resolve, 60000)); // Release the session - your auth state is saved await client.sessions.release(session.id); // Now your agent uses your authenticated state const agentSession = await client.sessions.create({ profileId: session.profileId });
Handle 2FA, CAPTCHAs, or SSO flows once, then let your agent reuse that authenticated state for all future runs.
Why This Matters
No repeated authentication: Your agent logs in once. Every subsequent session picks up with valid auth tokens and cookies already in place.
Better stealth: Profiles build browsing history and reputation. Sites see a returning user, not a fresh bot on every request. Fewer CAPTCHAs, less anti-bot friction.
Multi-tenant workflows: Each customer gets their own profile. One authentication per tenant, reused across all their agent operations.
Parallel testing: Fork a baseline profile to test different agent strategies without sessions interfering with each other's state.
Simpler infrastructure: No more managing cookie jars in Redis or session blobs in S3. Steel handles state persistence, encryption, and retrieval.
Available Now
The Profiles API is live today in Steel Cloud, plus Python(v0.11.0+) and Node SDKs (v0.12.0+).
Get started:
Questions or want to share what you build? Join us in Discord or tag us on Twitter @steeldotdev.
This is part of Steel's launch week. More features dropping daily at steel.dev/launch-week.
All Systems Operational

