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

# Actions

> Initiate actions using a Server SDK before using Web SDK methods for email OTP, SMS OTP, WhatsApp OTP, or authenticator app.

When using Web SDK methods for email OTP, SMS OTP, WhatsApp OTP, or authenticator app, you must first track an action using a [Server SDK](/sdks/server/overview) to generate a short-lived token.
This token is valid for 10 minutes by default and authorizes a window in which Web SDK methods can be used to authenticate the user associated with the token.

<CodeGroup>
  ```ts Node.js theme={null}
  const request = {
    userId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
    action: "signIn",
  };

  const response = await authsignal.track(request);

  const token = response.token;
  ```

  ```csharp C# theme={null}
  var request = new TrackRequest(
      UserId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
      Action: "signIn"
  );

  var response = await authsignal.Track(request);

  var token = response.Token;
  ```

  ```java Java theme={null}
  TrackRequest request = new TrackRequest();
  request.userId = "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833";
  request.action = "signIn";

  TrackResponse response = authsignal.track(request).get();

  String token = response.token;
  ```

  ```ruby Ruby theme={null}
  response = Authsignal.track({
    user_id: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
    action: "signIn",
  })

  token = response[:token]
  ```

  ```python Python theme={null}
  response = authsignal.track(
      user_id="dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
      action="signIn",
  )

  token = response["token"]
  ```

  ```php PHP theme={null}
  $response = Authsignal::track([
      'userId' => "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
      'action' => "signIn",
  ]);

  $token = $response["token"];
  ```

  ```go Go theme={null}
  response, err := client.Track(
      TrackRequest{
          UserId: "dc58c6dc-a1fd-4a4f-8e2f-846636dd4833",
          Action: "signIn",
      },
  )

  token := response.Token
  ```
</CodeGroup>

<Info>
  For enrollment flows, you must also specify the scope `add:authenticators` when tracking the
  action if the user already has an existing authenticator. For more detail refer to our guide on
  [how to ensure a strong binding when adding
  authenticators](/advanced-usage/authenticator-binding#tracking-an-action-to-generate-a-token).
</Info>

Then you can use the SDK's `setToken` method.
You must use the **same token** for the initial enroll/challenge call and the subsequent verify call.

<CodeGroup>
  ```js JS theme={null}
  authsignal.setToken("eyJhbGciOiJ...");

  // Send the user an email OTP code
  // You can call this multiple times via a 'resend' button
  await authsignal.email.challenge();

  // Verify the inputted code matches the original code
  const response = await authsignal.email.verify({ code: "123456" });
  ```
</CodeGroup>
