Skip to content

MFA Authentication Flow

piekstra edited this page Feb 7, 2026 · 1 revision

MFA Authentication Flow

When a TP-Link account has two-factor authentication (2FA/MFA) enabled, the login process requires an additional verification step.

Flow Overview

Login Request
    │
    ├── error_code: 0 → Success (no MFA)
    │
    └── error_code: -20677 → MFA Required
            │
            ├── supportedMFATypes: ["email"]
            │       │
            │       └── Request email code
            │               │
            │               └── User enters code
            │                       │
            │                       └── checkMFACodeAndLogin → Token
            │
            └── supportedMFATypes: ["push"]
                    │
                    └── Request push notification
                            │
                            └── User approves on phone
                                    │
                                    └── checkMFACodeAndLogin → Token

Step 1: Detect MFA Requirement

When login returns error code -20677, the response includes:

{
  "error_code": -20677,
  "result": {
    "mfaProcessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "supportedMFATypes": ["email"],
    "accountId": "1234567"
  }
}

Save the mfaProcessId - it's needed for the verification step.

Step 2: Request Verification Code

Email MFA

Endpoint: POST {appServerUrl}/api/v2/account/getEmailVC4TerminalMFA

Body:

{
  "mfaProcessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "appType": "Kasa_Android_Mix"
}

This sends a verification code to the user's registered email address.

Push MFA

Endpoint: POST {appServerUrl}/api/v2/account/getPushVC4TerminalMFA

Body:

{
  "mfaProcessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "appType": "Kasa_Android_Mix"
}

This sends a push notification to the user's Kasa app on their phone.

Step 3: Verify Code and Complete Login

Endpoint: POST {appServerUrl}/api/v2/account/checkMFACodeAndLogin

Body (from decompiled CheckMFACodeParams):

{
  "appType": "Kasa_Android_Mix",
  "code": "123456",
  "mfaProcessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "mfaType": "email"
}

Successful Response: Same as a successful login - returns token, refreshToken, accountId, etc.

{
  "error_code": 0,
  "result": {
    "token": "xxxxxxxx-xxxxxxxxxxxxxxxxxxxx",
    "refreshToken": "xxxxxxxx-xxxxxxxxxxxxxxxxxxxx",
    "accountId": "1234567",
    ...
  }
}

Library Design Considerations

For the Python library, MFA support needs a callback mechanism since the verification code must come from the user interactively.

Proposed API:

# Option 1: Callback function
def mfa_callback(mfa_type, email):
    code = input(f"Enter the MFA code sent to {email}: ")
    return code

device_manager = TPLinkDeviceManager(
    username="user@example.com",
    password="password",
    mfa_callback=mfa_callback
)

# Option 2: Exception-based
try:
    device_manager = TPLinkDeviceManager(username="...", password="...")
except TPLinkMFARequiredError as e:
    code = input(f"Enter MFA code: ")
    device_manager = e.complete_login(code)

Source in Decompiled APK

  • API Interface: sources/com/tplink/cloud/api/AccountV2Api.java - checkMFACodeAndLogin(), getEmailVC4TerminalMFA()
  • Params: sources/com/tplink/cloud/bean/account/params/CheckMFACodeParams.java
  • Login Result: sources/com/tplink/cloud/bean/account/result/LoginV2Result.java - Contains mfaProcessId, supportedMFATypes

Clone this wiki locally