Skip to content

TOTP

TOTP setup and code generation

Method Return Description
totp_generate_seed() str Generate 2FA TOTP seed
totp_enable(verification_code: str) List[str] Enable TOTP 2FA (return backup keys, save it)
totp_disable() bool Disable TOTP 2FA
totp_generate_code(seed: str) str Generate 2FA TOTP code (you can use it instead of Google Authenticator)

Example:

>>> from aiograpi import Client
>>> cl = Client()
>>> await cl.login(USERNAME, PASSWORD)

>>> seed = await cl.totp_generate_seed()
"67EIYPWCIJDTTVX632NEODKEU2PY5BIW"

>>> code = cl.totp_generate_code(seed)
"123456"

>>> await cl.totp_enable(code)
["1234 5678", "1234 5678", "1234 5678", "1234 5678", "1234 5678"]

>>> await cl.totp_disable()
True

Notes:

  • totp_generate_seed() gives you the secret key you would normally scan into an authenticator app.
  • totp_generate_code() is a local helper and can be used anywhere you already have the TOTP seed.
  • Save the backup codes returned by totp_enable() immediately. Instagram does not guarantee that you can fetch the same codes again later.

Bloks two-factor flow

Some accounts are moved by Instagram to a newer CAA/Bloks two-factor flow. In that case the legacy accounts/two_factor_login/ endpoint can reject a valid code with Invalid Parameters.

Client.login(..., verification_code="123456") still uses the legacy mobile endpoint first. If Instagram returns a two_step_verification_context, aiograpi automatically retries through the Bloks two-factor flow. When the context is not present, the exception explains that the account still needs manual app verification or a fresh current-app login response.

The low-level helpers remain available when you need to inspect or drive the flow manually:

from aiograpi import Client

cl = Client()

# The context comes from Instagram's login challenge response.
context = "<two_step_verification_context>"

await cl.bloks_two_step_verification_entrypoint(context)
await cl.bloks_two_step_verification_method_picker(context)
await cl.bloks_two_step_verification_select_method(context, selected_method="totp")

code = cl.totp_generate_code("<totp seed>")
result = await cl.bloks_two_step_verification_verify_code(context, code, challenge="totp")
login_payload = cl.bloks_extract_login_response(result)
cl.bloks_apply_login_response(login_payload)

For SMS, select and verify the sms challenge instead:

await cl.bloks_two_step_verification_select_method(context, selected_method="sms")
result = await cl.bloks_two_step_verification_verify_code(context, "123456", challenge="sms")

bloks_extract_login_response(...) returns decoded login_response, response headers, cookie values, raw cookie header text, and the raw embedded object when Instagram returns a successful Bloks login payload. It returns {} when the response is an intermediate UI state or an error. bloks_apply_login_response(...) can then copy the returned authorization data and cookies into the current client session.

Automatic fallback can only run after Instagram exposes two_step_verification_context to the client. A BadPassword response with a known-good password can still be account-risk handling before Instagram exposes that context, so treat it as a signal to inspect proxy/IP, device consistency, and the raw login response.