> ## Documentation Index
> Fetch the complete documentation index at: https://usefoil.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Dashboard login

> Let developers log into your dashboard with npx signup login. Add one route that verifies the one-time Gate login code and creates a session in your app.

Gate supports `npx signup yourproduct login`, which generates a magic link and opens your dashboard. You add one route to handle it.

## How it works

1. Developer runs `npx signup yourproduct login`
2. CLI authenticates with the agent token from `.env`
3. Gate opens a consent window — developer clicks Approve
4. Gate issues a short-lived login code
5. CLI opens your dashboard at `/auth/gate?code=...`
6. Your server verifies the code with Gate and creates a session

## Add the route

<CodeGroup>
  ```javascript Node.js (Express) theme={"dark"}
  app.get('/auth/gate', async (req, res) => {
    const code = req.query.code;
    if (!code) return res.redirect('/login');

    // Verify with Gate
    const resp = await fetch(`https://api.usefoil.com/gate/login-sessions/consume`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token: code }),
    });

    if (!resp.ok) return res.redirect('/login');

    const { data } = await resp.json();
    // data.gate_account_id — look up the user in your system

    // Create a session in your auth system
    const user = await findOrCreateUser(data.gate_account_id, data.account_name);
    req.session.userId = user.id;

    res.redirect('/dashboard');
  });
  ```

  ```python Python (Flask) theme={"dark"}
  @app.get("/auth/gate")
  def gate_login():
      code = request.args.get("code")
      if not code:
          return redirect("/login")

      resp = requests.post(
          "https://api.usefoil.com/gate/login-sessions/consume",
          json={"token": code},
      )

      if not resp.ok:
          return redirect("/login")

      data = resp.json()["data"]
      user = find_or_create_user(data["gate_account_id"], data["account_name"])
      session["user_id"] = user.id

      return redirect("/dashboard")
  ```

  ```go Go theme={"dark"}
  func gateLogin(w http.ResponseWriter, r *http.Request) {
      code := r.URL.Query().Get("code")
      if code == "" {
          http.Redirect(w, r, "/login", http.StatusFound)
          return
      }

      body, _ := json.Marshal(map[string]string{"token": code})
      resp, err := http.Post(
          "https://api.usefoil.com/gate/login-sessions/consume",
          "application/json",
          bytes.NewReader(body),
      )
      if err != nil || resp.StatusCode != 200 {
          http.Redirect(w, r, "/login", http.StatusFound)
          return
      }

      // Parse response, create session, redirect to /dashboard
  }
  ```

  ```ruby Ruby (Sinatra) theme={"dark"}
  get '/auth/gate' do
    code = params[:code]
    redirect '/login' unless code

    resp = Net::HTTP.post(
      URI('https://api.usefoil.com/gate/login-sessions/consume'),
      { token: code }.to_json,
      'Content-Type' => 'application/json',
    )

    redirect '/login' unless resp.code == '200'

    data = JSON.parse(resp.body)['data']
    user = find_or_create_user(data['gate_account_id'], data['account_name'])
    session[:user_id] = user.id

    redirect '/dashboard'
  end
  ```

  ```php PHP theme={"dark"}
  $code = $_GET['code'] ?? '';
  if (!$code) { header('Location: /login'); exit; }

  $resp = file_get_contents('https://api.usefoil.com/gate/login-sessions/consume', false,
      stream_context_create([
          'http' => [
              'method' => 'POST',
              'header' => 'Content-Type: application/json',
              'content' => json_encode(['token' => $code]),
          ],
      ])
  );

  $data = json_decode($resp, true)['data'] ?? null;
  if (!$data) { header('Location: /login'); exit; }

  // Create session, redirect to /dashboard
  ```

  ```bash cURL theme={"dark"}
  curl -X POST https://api.usefoil.com/gate/login-sessions/consume \
    -H "Content-Type: application/json" \
    -d '{"token": "CODE_FROM_URL"}'
  ```
</CodeGroup>

## Consume response

```json theme={"dark"}
{
  "data": {
    "gate_account_id": "gacct_...",
    "account_name": "my-project"
  }
}
```

The code is one-time-use. Once consumed, it cannot be reused.

## What's next

* [Agent tokens](/gate/agent-tokens) — verify tokens in your API
* [What is Gate?](/gate/what-is-gate) — overview of the Gate product
