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

# Via backend SDK or API

> Examples and considerations when doing a server-side integration with Stytch.

<Tip>
  Our [frontend SDK](./via-sdk) provide automatic session management, prebuilt login or signup, multi-step flow handling, and more. They can also be used alongside our backend API or SDKs.
</Tip>

## Quickstart

This quickstart guides you through building a login or signup flow. Select a framework:

<Tabs>
  <Tab title="Node.js" icon="node-js">
    <Columns cols={3}>
      <Card title="Example apps" icon="github" href="/get-started/example-apps">
        End-to-end consumer examples
      </Card>

      <Card title="Node.js SDK" icon="node" href="https://github.com/stytchauth/stytch-node">
        Stytch Node.js library
      </Card>

      <Card title="API reference" icon="book-text" href="/api-reference/consumer/api/overview">
        API & SDK references
      </Card>
    </Columns>

    <Steps>
      <Step title="Before you start">
        * Have your `project_id` and `secret_key` from your Stytch project & environment.
        * Add `http://localhost:3000/authenticate` as a [redirect URL](https://stytch.com/dashboard/redirect-urls) in your Dashboard.
      </Step>

      <Step title="Install the Node.js SDK and configure API keys">
        1. Install the SDK:

        ```bash npm icon="terminal" theme={null}
        npm install stytch express express-session
        ```

        2. Then add your Stytch API keys to your project's `.env` file:

        ```dotEnv .env icon=file-code theme={null}
        STYTCH_PROJECT_ID="YOUR_STYTCH_PROJECT_ID"
        STYTCH_SECRET="YOUR_STYTCH_PROJECT_SECRET"
        # Use your Project's 'live' or any available 'test' credentials
        ```
      </Step>

      <Step title="Set up your app and login routes">
        1. Initialize the Stytch client with your environment variables.
        2. Create a `/login` route that takes in a user's email address and initiates the login or signup flow.

        ```javascript title="POST '/login'" lines theme={null}
        const express = require('express');
        const session = require('express-session');
        const stytch = require('stytch');

        const app = express();
        app.use(express.json());
        app.use(session({
          resave: true,
          saveUninitialized: false,
          secret: 'session-signing-secret',
        }));

        const stytchClient = new stytch.Client({
          project_id: process.env.STYTCH_PROJECT_ID,
          secret: process.env.STYTCH_SECRET,
        });

        app.post('/login', async (req, res) => {
          const params = {
            email: req.body.email,
            login_magic_link_url: "http://localhost:3000/authenticate",
            signup_magic_link_url: "http://localhost:3000/authenticate",
          };
          const resp = await stytchClient.magicLinks.email.loginOrCreate(params);
          res.json(resp);
        });
        ```
      </Step>

      <Step title="Add a route to handle Stytch's redirect callback">
        1. Stytch calls your authenticate redirect URL with a token to complete the flow.
        2. Add an `/authenticate` route to mint a session:

        ```javascript title="GET '/authenticate'" lines theme={null}
        app.get('/authenticate', async (req, res) => {
          const token = req.query.token;
          const resp = await stytchClient.magicLinks.authenticate({
            token,
            session_duration_minutes: 60,
          });

          req.session.session_jwt = resp.session_jwt;
          res.redirect('/dashboard');
        });
        ```
      </Step>

      <Step title="Add a session-protected route">
        1. Create a helper method that authenticates a session.
        2. Use the method to gate any protected route.

        ```javascript title="GET '/dashboard'" lines theme={null}
        app.get('/dashboard', async (req, res) => {
          const sessionJWT = req.session.session_jwt;
          if (!sessionJWT) {
            res.send("Log in to view this page");
            return;
          }

          const resp = await stytchClient.sessions.authenticate({
            session_jwt: sessionJWT,
          });
          if (resp.status_code !== 200) {
            req.session.session_jwt = undefined;
            res.send("Log in to view this page");
            return;
          }

          res.send("You're logged in.");
        });
        ```
      </Step>

      <Step title="Full completed example:">
        ```javascript expandable lines theme={null}
        const express = require('express');
        const session = require('express-session');
        const stytch = require('stytch');

        const app = express();
        app.use(express.json());
        app.use(session({
          resave: true,
          saveUninitialized: false,
          secret: 'session-signing-secret',
        }));

        const stytchClient = new stytch.Client({
          project_id: process.env.STYTCH_PROJECT_ID,
          secret: process.env.STYTCH_SECRET,
        });

        app.post('/login', async (req, res) => {
          const params = {
            email: req.body.email,
            login_magic_link_url: "http://localhost:3000/authenticate",
            signup_magic_link_url: "http://localhost:3000/authenticate",
          };
          const resp = await stytchClient.magicLinks.email.loginOrCreate(params);
          res.json(resp);
        });

        app.get('/authenticate', async (req, res) => {
          const token = req.query.token;
          const resp = await stytchClient.magicLinks.authenticate({
            token,
            session_duration_minutes: 60,
          });

          req.session.session_jwt = resp.session_jwt;
          res.redirect('/dashboard');
        });

        app.get('/dashboard', async (req, res) => {
          const sessionJWT = req.session.session_jwt;
          if (!sessionJWT) {
            res.send("Log in to view this page");
            return;
          }

          const resp = await stytchClient.sessions.authenticate({
            session_jwt: sessionJWT,
          });
          if (resp.status_code !== 200) {
            req.session.session_jwt = undefined;
            res.send("Log in to view this page");
            return;
          }

          res.send("You're logged in.");
        });

        app.listen(3000, () => console.log('Server running on http://localhost:3000'));
        ```
      </Step>

      <Step title="Test your application" icon="check">
        * Run your application and send a `POST` request to the `/login` endpoint with your email address.
        * You should receive an email magic link in your inbox.
        * Click the link to finish the login or signup flow.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Go" icon="golang">
    <Columns cols={3}>
      <Card title="Example apps" icon="github" href="/get-started/example-apps">
        End-to-end consumer examples
      </Card>

      <Card title="Go SDK" icon="golang" href="https://github.com/stytchauth/stytch-go">
        Stytch Go library
      </Card>

      <Card title="API reference" icon="book-text" href="/api-reference/consumer/api/overview">
        API & SDK references
      </Card>
    </Columns>

    <Steps>
      <Step title="Before you start">
        Have your `project_id` and `secret_key` from your Stytch project & environment.
      </Step>

      <Step title="Install dependencies and configure API keys">
        Use the Go standard library (`net/http`, `encoding/json`) or your preferred HTTP client.
      </Step>

      <Step title="Set up your app and login routes">
        ```go lines theme={null}
        payload := map[string]any{
          "email": email,
          "login_magic_link_url": "http://localhost:3000/authenticate",
          "signup_magic_link_url": "http://localhost:3000/authenticate",
        }
        body, _ := json.Marshal(payload)

        req, _ := http.NewRequest("POST", "https://test.stytch.com/v1/magic_links/email/login_or_create", bytes.NewReader(body))
        req.SetBasicAuth(os.Getenv("STYTCH_PROJECT_ID"), os.Getenv("STYTCH_SECRET"))
        req.Header.Set("Content-Type", "application/json")
        ```
      </Step>

      <Step title="Add a route to handle Stytch's redirect callback">
        ```go lines theme={null}
        payload := map[string]any{
          "token": token,
          "session_duration_minutes": 60,
        }
        body, _ := json.Marshal(payload)

        req, _ := http.NewRequest("POST", "https://test.stytch.com/v1/magic_links/authenticate", bytes.NewReader(body))
        req.SetBasicAuth(os.Getenv("STYTCH_PROJECT_ID"), os.Getenv("STYTCH_SECRET"))
        req.Header.Set("Content-Type", "application/json")
        ```
      </Step>

      <Step title="Add a session-protected route">
        ```go lines theme={null}
        payload := map[string]any{"session_jwt": sessionJWT}
        body, _ := json.Marshal(payload)

        req, _ := http.NewRequest("POST", "https://test.stytch.com/v1/sessions/authenticate", bytes.NewReader(body))
        req.SetBasicAuth(os.Getenv("STYTCH_PROJECT_ID"), os.Getenv("STYTCH_SECRET"))
        req.Header.Set("Content-Type", "application/json")
        ```
      </Step>

      <Step title="Full completed example:">
        ```go expandable lines theme={null}
        package main

        import (
          "bytes"
          "encoding/json"
          "net/http"
          "os"
        )

        func main() {
          http.HandleFunc("/login", sendLoginHandler)
          http.HandleFunc("/authenticate", authenticateHandler)
          http.HandleFunc("/dashboard", dashboardHandler)
          http.ListenAndServe(":3000", nil)
        }

        // Implement sendLoginHandler/authenticateHandler/dashboardHandler using the
        // requests shown above.
        ```
      </Step>

      <Step title="Test your application" icon="check">
        * Run your application and send a `POST` request to the `/login` endpoint with your email address.
        * You should receive an email magic link in your inbox.
        * Click the link to finish the login or signup flow.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Python" icon="python">
    <Columns cols={3}>
      <Card title="Example apps" icon="github" href="/get-started/example-apps">
        End-to-end consumer examples
      </Card>

      <Card title="Python SDK" icon="python" href="https://github.com/stytchauth/stytch-python">
        Stytch Python library
      </Card>

      <Card title="API reference" icon="book-text" href="/api-reference/consumer/api/overview">
        API & SDK references
      </Card>
    </Columns>

    <Steps>
      <Step title="Before you start">
        Have your `project_id` and `secret_key` from your Stytch project & environment.
      </Step>

      <Step title="Install dependencies and configure API keys">
        ```bash pip icon="terminal" theme={null}
        pip install requests
        ```
      </Step>

      <Step title="Set up your app and login routes">
        ```python lines theme={null}
        import requests

        resp = requests.post(
          "https://test.stytch.com/v1/magic_links/email/login_or_create",
          auth=(project_id, secret),
          json={
            "email": email,
            "login_magic_link_url": "http://localhost:3000/authenticate",
            "signup_magic_link_url": "http://localhost:3000/authenticate",
          },
        )
        ```
      </Step>

      <Step title="Add a route to handle Stytch's redirect callback">
        ```python lines theme={null}
        resp = requests.post(
          "https://test.stytch.com/v1/magic_links/authenticate",
          auth=(project_id, secret),
          json={"token": token, "session_duration_minutes": 60},
        )
        session_jwt = resp.json()["session_jwt"]
        ```
      </Step>

      <Step title="Add a session-protected route">
        ```python lines theme={null}
        resp = requests.post(
          "https://test.stytch.com/v1/sessions/authenticate",
          auth=(project_id, secret),
          json={"session_jwt": session_jwt},
        )
        ```
      </Step>

      <Step title="Full completed example:">
        ```python expandable lines theme={null}
        # Combine the login, authenticate, and session check requests in your
        # framework of choice (Flask, Django, FastAPI, etc.).
        ```
      </Step>

      <Step title="Test your application" icon="check">
        * Run your application and send a `POST` request to the `/login` endpoint with your email address.
        * You should receive an email magic link in your inbox.
        * Click the link to finish the login or signup flow.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Ruby on Rails" icon="gem">
    <Columns cols={3}>
      <Card title="Example apps" icon="github" href="/get-started/example-apps">
        End-to-end consumer examples
      </Card>

      <Card title="Ruby SDK" icon="gem" href="https://github.com/stytchauth/stytch-ruby">
        Stytch Ruby gem
      </Card>

      <Card title="API reference" icon="book-text" href="/api-reference/consumer/api/overview">
        API & SDK references
      </Card>
    </Columns>

    <Steps>
      <Step title="Before you start">
        Have your `project_id` and `secret_key` from your Stytch project & environment.
      </Step>

      <Step title="Install dependencies and configure API keys">
        Use Ruby's built-in `net/http` or your preferred HTTP client.
      </Step>

      <Step title="Set up your app and login routes">
        ```ruby lines theme={null}
        uri = URI("https://test.stytch.com/v1/magic_links/email/login_or_create")
        req = Net::HTTP::Post.new(uri)
        req.basic_auth(project_id, secret)
        req["Content-Type"] = "application/json"
        req.body = {
          email: email,
          login_magic_link_url: "http://localhost:3000/authenticate",
          signup_magic_link_url: "http://localhost:3000/authenticate"
        }.to_json
        ```
      </Step>

      <Step title="Add a route to handle Stytch's redirect callback">
        ```ruby lines theme={null}
        uri = URI("https://test.stytch.com/v1/magic_links/authenticate")
        req = Net::HTTP::Post.new(uri)
        req.basic_auth(project_id, secret)
        req["Content-Type"] = "application/json"
        req.body = { token: token, session_duration_minutes: 60 }.to_json
        ```
      </Step>

      <Step title="Add a session-protected route">
        ```ruby lines theme={null}
        uri = URI("https://test.stytch.com/v1/sessions/authenticate")
        req = Net::HTTP::Post.new(uri)
        req.basic_auth(project_id, secret)
        req["Content-Type"] = "application/json"
        req.body = { session_jwt: session_jwt }.to_json
        ```
      </Step>

      <Step title="Full completed example:">
        ```ruby expandable lines theme={null}
        # Combine the login, authenticate, and session check requests in your
        # Rails controllers and routes.
        ```
      </Step>

      <Step title="Test your application" icon="check">
        * Run your application and send a `POST` request to the `/login` endpoint with your email address.
        * You should receive an email magic link in your inbox.
        * Click the link to finish the login or signup flow.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Java" icon="java">
    <Columns cols={3}>
      <Card title="Example apps" icon="github" href="/get-started/example-apps">
        End-to-end consumer examples
      </Card>

      <Card title="Java SDK" icon="java" href="https://github.com/stytchauth/stytch-java">
        Stytch Java library
      </Card>

      <Card title="API reference" icon="book-text" href="/api-reference/consumer/api/overview">
        API & SDK references
      </Card>
    </Columns>

    <Steps>
      <Step title="Before you start">
        Have your `project_id` and `secret_key` from your Stytch project & environment.
      </Step>

      <Step title="Install dependencies and configure API keys">
        Use `java.net.http.HttpClient` or your preferred HTTP client library.
      </Step>

      <Step title="Set up your app and login routes">
        ```java theme={null}
        var payload = """
          {
            "email": "%s",
            "login_magic_link_url": "http://localhost:3000/authenticate",
            "signup_magic_link_url": "http://localhost:3000/authenticate"
          }
        """.formatted(email);

        var request = HttpRequest.newBuilder()
          .uri(URI.create("https://test.stytch.com/v1/magic_links/email/login_or_create"))
          .header("Content-Type", "application/json")
          .header("Authorization", basicAuth(projectId, secret))
          .POST(HttpRequest.BodyPublishers.ofString(payload))
          .build();
        ```
      </Step>

      <Step title="Add a route to handle Stytch's redirect callback">
        ```java theme={null}
        var payload = """
          {
            "token": "%s",
            "session_duration_minutes": 60
          }
        """.formatted(token);

        var request = HttpRequest.newBuilder()
          .uri(URI.create("https://test.stytch.com/v1/magic_links/authenticate"))
          .header("Content-Type", "application/json")
          .header("Authorization", basicAuth(projectId, secret))
          .POST(HttpRequest.BodyPublishers.ofString(payload))
          .build();
        ```
      </Step>

      <Step title="Add a session-protected route">
        ```java theme={null}
        var payload = """
          {
            "session_jwt": "%s"
          }
        """.formatted(sessionJwt);

        var request = HttpRequest.newBuilder()
          .uri(URI.create("https://test.stytch.com/v1/sessions/authenticate"))
          .header("Content-Type", "application/json")
          .header("Authorization", basicAuth(projectId, secret))
          .POST(HttpRequest.BodyPublishers.ofString(payload))
          .build();
        ```
      </Step>

      <Step title="Full completed example:">
        ```java theme={null}
        import java.nio.charset.StandardCharsets;
        import java.util.Base64;

        private static String basicAuth(String projectId, String secret) {
          var token = projectId + ":" + secret;
          return "Basic " + Base64.getEncoder().encodeToString(token.getBytes(StandardCharsets.UTF_8));
        }

        // Wire the requests above into your controllers/routes and store sessionJwt
        // in a server-side session or signed cookie.
        ```
      </Step>

      <Step title="Test your application" icon="check">
        * Run your application and send a `POST` request to the `/login` endpoint with your email address.
        * You should receive an email magic link in your inbox.
        * Click the link to finish the login or signup flow.
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Next steps

* [Handle a session](/consumer-auth/manage-sessions/overview)
