> ## 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 Mobile SDK methods for email OTP, SMS OTP, WhatsApp OTP, or authenticator app.

When using Mobile 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 Mobile 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).
</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>
  ```swift iOS theme={null}
  authsignal.setToken("eyJhbGciOiJ...")

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

  // Verify the inputted code matches the original code
  let response = await authsignal.whatsapp.verify(code: "123456")
  ```

  ```kotlin Android theme={null}
  authsignal.setToken("eyJhbGciOiJ...")

  // Send the user a WhatsApp OTP code
  // You can call this multiple times via a 'resend' button
  authsignal.whatsapp.challenge()

  // Verify the inputted code matches the original code
  val response = authsignal.whatsapp.verify(code = "123456")
  ```

  ```ts React Native theme={null}
  await authsignal.setToken("eyJhbGciOiJ...");

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

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

  ```dart Flutter theme={null}
  await authsignal.setToken("eyJhbGciOiJ...");

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

  // Verify the inputted code matches the original code
  final response = await authsignal.whatsapp.verify(code: "123456");
  ```
</CodeGroup>
