# Login Session (`pocesar/login-session`) Actor

Get localStorage, sessionStorage and cookies from logins for usage in other actors.

- **URL**: https://apify.com/pocesar/login-session.md
- **Developed by:** [Paulo Cesar](https://apify.com/pocesar) (community)
- **Categories:** Developer tools, Open source
- **Stats:** 463 total users, 1 monthly users, 0.0% runs succeeded, 9 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Login Session

Get localStorage, sessionStorage and cookies from logins for usage in other actors.

### Usage

This actor can help you (re)use logged in sessions for your website and serivces, abstracting away the need for developing your own login mechanism. It uses a named session storage, so you when you request a new session, it will be readily available. It's tailored to work seamlessly on Apify platform and other actors.

It's more low-level than other actors, but it tries to cover the most common use cases like:

- Single Page Applications
- Server Side Rendered websites
- Ajax login calls
- Multi step logins such as username on one page, password on another

You may call directly from your actor, or use the `INPUT.json` to create a task or scheduled to keep seeding your session storage with new sessions. It cannot deal with 2FA or captchas (yet).

```js
// in your actor
const storageName = 'session-example';

const call = await Apify.call('pocesar/login-session', {
    username: 'username',
    password: 'password',
    website: [{ url: 'http://example.com' }], // the RequestList format
    cookieDomains: [
        "http://example.com"
    ],
    sessionConfig: {
        storageName,
        maxAgeSecs: 3600,
        maxUsageCount: 10,
        maxPoolSize: 120
    },
    steps: [{
        username: {
            selector: "input#email", // the input that receives the username
            timeoutMillis: 10000 // optional timeout in ms
        },
        password: {
            selector: "input#password" // the input that receives the password
        },
        submit: {
            selector: "input[type=\"submit\"]", // the button that executes the login
        },
        failed: {
            selector: "[role=\"alert\"],#captcha", // usually an error that tells the login failed
            timeoutMillis: 10000 // optional timeout in ms
        },
        waitForMillis: 15000 // optional "sleep" in ms to consider the page as "settled"
    }]
});

const { session, error } = call.output;

// if it fails, the error will be filled with something
// otherwise, the session will have the Session parameters, that can be
// instantiated manually using `new Apify.Session({ ...session, sessionPool })`

// load the session pool from the storage, so it has our new
// session. this might change in the future
const sessionPool = await Apify.openSessionPool({
    persistStateKeyValueStoreId: storageName
});

const sessionJustCreated = sessionPool.sessions.find(s => s.id === session.id);

/**
 * the complete Cookie string for usage on the header
 */
sessionJustCreated.getCookieString('http://example.com');

/**
 * contains the User-Agent used for the login request.
 * the same userAgent must be set between uses so there's no
 * conflict and blocks. Set this as your User-Agent header
 **/
sessionJustCreated.userData.userAgent;

/**
 * the proxyUrl used, can be empty.
 * Set this as your proxyUrl parameter in crawlers.
 *
 * This might be undefined if you didn't use any proxies
 */
sessionJustCreated.userData.proxyUrl;

/**
 * object containing any sessionStorage content, useful for JWT tokens.
 * Useful for using in PuppeteerCrawler
 */
sessionJustCreated.userData.sessionStorage;

/**
 * object containing any localStorage content, useful for JWT
 * tokens. Useful for using in PuppeteerCrawler
 */
sessionJustCreated.userData.localStorage;

```

### Login locally then use the session on the platform

You can login locally, executing the login-session actor on your machine, make sure you're logged in to the platform using `apify login` and using `forceCloud` input option, like this:

```jsonc
{
    "username": "username",
    "password": "s3cr3tp4ssw0rd",
    "website": [{ "url": "https://example.com/" }],
    "sessionConfig": {
        "storageName": "example-login-sessions" // need to use this
    },
    "steps": [
        {
            "username": { "selector": "#email" },
            "password": { "selector": "#password" },
            "submit": { "selector": "input[type=\"submit\"]" },
            "success": { "selector": ".main-menu", "timeoutMillis": 10000 },
            "failed": {
                "selector": ".login.error",
                "timeoutMillis": 10000
            },
            "waitForMillis": 30000
        }
    ],
    "cookieDomains": ["https://example.com"],
    "proxyConfiguration": {
        "useApifyProxy": false
    },
    "forceCloud": true // this forces the login to be saved on platform Storage (https://my.apify.com/storage#/keyValueStores)
}
```

Place this in your `apify_storage/key_value_stores/default/INPUT.json` file, then run locally:

```
$ apify run --purge
```

The session will be created in your Apify platform account, under the `storageName` you provided, but using your local IP.
Using this, you're able to avoid PIN requests and security checkpoint screens.

### Input Recipes

Here are some real-life examples of INPUT.json that you may use:

#### Gmail

```json
{
    "username": "username",
    "password": "password",
    "website": [{ "url": "https://accounts.google.com/signin/v2/identifier?service=mail&passive=true&flowName=GlifWebSignIn&flowEntry=ServiceLogin" }],
    "cookieDomains": [
        "https://mail.google.com",
        "https://accounts.google.com",
        "https://google.com"
    ],
    "steps": [{
        "username": {
            "selector": "#identifierId"
        },
        "submit": {
            "selector": "#identifierNext"
        },
        "success": {
            "selector": "input[type=\"password\"]",
            "timeoutMillis": 10000
        },
        "failed": {
            "selector": "#identifierId[aria-invalid=\"true\"],iframe[src*=\"CheckConnection\"]"
        },
        "waitForMillis": 30000
    }, {
        "password": {
            "selector": "input[type=\"password\"]"
        },
        "submit": {
            "selector": "#passwordNext",
            "timeoutMillis": 15000
        },
        "failed": {
            "selector": "input[type=\"password\"][aria-invalid=\"true\"],iframe[src*=\"CheckConnection\"]",
            "timeoutMillis": 5000
        },
        "success": {
            "selector": "link[href*=\"mail.google.com\"]",
            "timeoutMillis": 10000
        },
        "waitForMillis": 30000
    }]
}
```

#### Facebook

```json
{
    "username": "username",
    "password": "password",
    "website": [{ "url": "https://www.facebook.com/" }],
    "cookieDomains": [
        "https://facebook.com"
    ],
    "steps": [{
        "username": {
            "selector": "#login_form [type=\"email\"]"
        },
        "password": {
            "selector": "#login_form [type=\"password\"]"
        },
        "submit": {
            "selector": "#login_form [type=\"submit\"]"
        },
        "success": {
            "selector": "body.home",
            "timeoutMillis": 10000
        },
        "failed": {
            "selector": "body.login_page,body.UIPage_LoggedOut",
            "timeoutMillis": 10000
        },
        "waitForMillis": 30000
    }]
}
```

#### Twitter

```json
{
    "username": "username",
    "password": "password",
    "website": [{ "url": "https://twitter.com/login" }],
    "cookieDomains": [
        "https://twitter.com"
    ],
    "steps": [{
        "username": {
            "selector": "h1 ~ form [name=\"session[username_or_email]\"]",
            "timeoutMillis": 2000
        },
        "password": {
            "selector": "h1 ~ form [name=\"session[password]\"]",
            "timeoutMillis": 2000
        },
        "submit": {
            "selector": "h1 ~ form [role=\"button\"][data-focusable]"
        },
        "success": {
            "selector": "h2[role=\"heading\"]",
            "timeoutMillis": 10000
        },
        "failed": {
            "selector": "h1 ~ form [role=\"button\"][disabled]",
            "timeoutMillis": 10000
        },
        "waitForMillis": 30000
    }]
}
```

#### Instagram

```json
{
    "username": "username",
    "password": "password",
    "website": [{ "url": "https://instagram.com" }],
    "cookieDomains": [
        "https://www.instagram.com"
    ],
    "steps": [{
        "username": {
            "selector": "input[name=\"username\"]",
            "timeoutMillis": 10000
        },
        "password": {
            "selector": "input[name=\"password\"]",
            "timeoutMillis": 10000
        },
        "submit": {
            "selector": "button[type=\"submit\"]"
        },
        "success": {
            "selector": "img[alt=\"Instagram\"]",
            "timeoutMillis": 10000
        },
        "failed": {
            "selector": "#slfErrorAlert",
            "timeoutMillis": 5000
        },
        "waitForMillis": 30000
    }]
}
```

#### LinkedIn

```jsonc
{
    "username": "username",
    "password": "password",
    "website": [
        {
            "url": "https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin"
        }
    ],
    "steps": [
        {
            "username": {
                "selector": "#username"
            },
            "password": {
                "selector": "#password"
            },
            "submit": {
                "selector": ".login__form_action_container button"
            },
            "success": {
                "selector": ".authentication-outlet,.launchpad-cp-enabled",
                "timeoutMillis": 15000
            },
            "failed": {
                "selector": ".form__input--error,.login__form,.pin-verification-form",
                "timeoutMillis": 15000
            },
            "waitForMillis": 30000
        }
    ],
    "cookieDomains": ["https://www.linkedin.com"]
}
```

### Related Content

- [Log in to website by transferring cookies from web browser (legacy)](https://help.apify.com/en/articles/1444249-log-in-to-website-by-transferring-cookies-from-web-browser-legacy)
- [How to log in to a website using Puppeteer](https://help.apify.com/en/articles/1640711-how-to-log-in-to-a-website-using-puppeteer)
- [Session Management](https://sdk.apify.com/docs/guides/session-management)

### Caveats

- Apify proxy sessions can last at most 24h, so never set your `maxAgeSecs` greater than this number
- If the proxy fails, the login fails. If the proxy is banned, the login fails.

### Example

Example form is in <https://now-h3p8398gc.now.sh>

### License

Apache 2.0

# Actor input Schema

## `username` (type: `string`):

The username/email that will be passed to the form

## `password` (type: `string`):

The password that will be passed to the form

## `userAgent` (type: `string`):

Choose an user-agent string

## `maxRequestRetries` (type: `integer`):

How many retries before considering the request as failed

## `website` (type: `array`):

The website to get the session from. The login form should be available on the provided url

## `sessionConfig` (type: `object`):

The configuration for your sessions

## `steps` (type: `array`):

Each step that should be taken for the login to happen. For multi-stage logins (username then password), provide multiple steps

## `cookieDomains` (type: `array`):

Specify the domains that should get cookies from

## `gotoTimeout` (type: `integer`):

How many seconds until page.goto should wait

## `proxyConfiguration` (type: `object`):

Select proxies to be used by your actor.

## `extraUrlPatterns` (type: `array`):

Passes this blocking pattern to puppeteer.blockRequests, so you can selectively block some requests on the page

## `forceCloud` (type: `boolean`):

Use this when you execute the actor locally in your machine, but fills the session storage on the Apify platform

## `countryCode` (type: `string`):

Set the proxy country to pass to proxy configuration when using RESIDENTIALS

## Actor input object example

```json
{
  "username": "username@example.com",
  "password": "secretpassword",
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36",
  "maxRequestRetries": 1,
  "sessionConfig": {
    "storageName": "login-sessions",
    "maxAgeSecs": 3600,
    "maxUsageCount": 100,
    "maxPoolSize": 100
  },
  "steps": [
    {
      "username": {
        "selector": "input#email"
      },
      "password": {
        "selector": "input#pass"
      },
      "submit": {
        "selector": "input[type=\"submit\"]"
      },
      "failed": {
        "selector": "[role=\"alert\"]"
      },
      "waitForMillis": 5000
    }
  ],
  "cookieDomains": [
    "domain.com",
    "subdomain.domain.com"
  ],
  "gotoTimeout": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "extraUrlPatterns": [
    ".png",
    ".svg"
  ],
  "forceCloud": true
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36",
    "maxRequestRetries": 0,
    "sessionConfig": {
        "storageName": "login-sessions",
        "maxAgeSecs": 3600,
        "maxUsageCount": 100,
        "maxPoolSize": 100
    },
    "steps": [
        {
            "username": {
                "selector": "input#email"
            },
            "password": {
                "selector": "input#pass"
            },
            "submit": {
                "selector": "input[type=\"submit\"]"
            },
            "failed": {
                "selector": "[role=\"alert\"]"
            },
            "waitForMillis": 5000
        }
    ],
    "cookieDomains": [],
    "gotoTimeout": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    },
    "extraUrlPatterns": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("pocesar/login-session").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36",
    "maxRequestRetries": 0,
    "sessionConfig": {
        "storageName": "login-sessions",
        "maxAgeSecs": 3600,
        "maxUsageCount": 100,
        "maxPoolSize": 100,
    },
    "steps": [{
            "username": { "selector": "input#email" },
            "password": { "selector": "input#pass" },
            "submit": { "selector": "input[type=\"submit\"]" },
            "failed": { "selector": "[role=\"alert\"]" },
            "waitForMillis": 5000,
        }],
    "cookieDomains": [],
    "gotoTimeout": 30,
    "proxyConfiguration": { "useApifyProxy": True },
    "extraUrlPatterns": [],
}

# Run the Actor and wait for it to finish
run = client.actor("pocesar/login-session").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36",
  "maxRequestRetries": 0,
  "sessionConfig": {
    "storageName": "login-sessions",
    "maxAgeSecs": 3600,
    "maxUsageCount": 100,
    "maxPoolSize": 100
  },
  "steps": [
    {
      "username": {
        "selector": "input#email"
      },
      "password": {
        "selector": "input#pass"
      },
      "submit": {
        "selector": "input[type=\\"submit\\"]"
      },
      "failed": {
        "selector": "[role=\\"alert\\"]"
      },
      "waitForMillis": 5000
    }
  ],
  "cookieDomains": [],
  "gotoTimeout": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "extraUrlPatterns": []
}' |
apify call pocesar/login-session --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=pocesar/login-session",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/P2M3dZzrvinZA2454/builds/Zk7LGi74MKF4Fjb1p/openapi.json
