> ## Documentation Index
> Fetch the complete documentation index at: https://turnkey-0e7c1f5b-9-digit-updates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# SMS Authentication

> SMS authentication enables users to authenticate their Turnkey account using their phone number via a 6-9 digit or bech32 alphanumeric one-time password (OTP). When authenticated, users receive an expiring API key stored in memory within an iframe, which functions like a session key to access their wallet.

## Access and Pricing

SMS authentication is available to all Enterprise customers. To enable this feature, please reach out to the Turnkey team.

SMS pricing is usage-based and varies depending on the country of the destination phone number. A downloadable price list for all supported countries is available <a href="https://tkhq-prod-public-content.s3.us-east-1.amazonaws.com/sms-prices.csv">
here as a CSV</a>

.

## How It Works

SMS authentication uses two activities:

1. `INIT_OTP_AUTH` - sends a 6-9 digit or bech32 alphanumeric OTP code to the specified phone number
2. `OTP_AUTH` - verifies the code and returns an encrypted API key credential

## Implementation

### Initiating SMS Authentication

To start SMS authentication, create an activity with `ACTIVITY_TYPE_INIT_OTP_AUTH` and the following parameters:

* `otpType`: must be set to `"OTP_TYPE_SMS"`
* `contact`: user's phone number (must be previously approved and attached to the user's organization data)
* `userIdentifier`: optional parameter for rate limiting SMS OTP requests per user.
  We recommend generating this server-side based on the user's IP address or public key.
  See the [OTP Rate Limits](#otp-rate-limits) section below for more details.
* `smsCustomizationParams`: optional parameters for customizing sms.
* `alphanumeric`: optional parameter for making this code bech32 alphanumeric or not. default: true
* `otpLength`: optional parameter for selecting the length of the OTP. default: 9

### Verifying the OTP

Once the user receives their code, use `ACTIVITY_TYPE_OTP_AUTH` with these parameters:

* `otpId`: ID from the `INIT_OTP_AUTH` response
* `otpCode`: the 6-9 digit or bech32 alphanumeric code received via SMS
* `targetPublicKey`: public key for credential encryption
* `apiKeyName`: optional name for the API Key (defaults to `OTP Auth - <Timestamp>`)
* `expirationSeconds`: optional duration in seconds (defaults to 15 minutes)
* `invalidateExisting`: optional boolean to invalidate previous OTP Auth API keys

## Authorization

SMS authentication requires proper permissions through policies or parent organization status.

<Info>
  Non-paying accounts are limited to **50 SMS messages** per month.
</Info>

## Enabling/Disabling SMS Auth

### For Top-level Organizations

SMS authentication is disabled by default. Enable it using `ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE`:

```bash theme={"system"}
turnkey request --host api.turnkey.com --path /public/v1/submit/set_organization_feature --body '{
        "timestampMs": "'"$(date +%s)"'000",
        "type": "ACTIVITY_TYPE_SET_ORGANIZATION_FEATURE",
        "organizationId": "<YOUR-ORG-ID>",
        "parameters": {
                "name": "FEATURE_NAME_SMS_AUTH"
        }
}' --organization <YOUR-ORG-ID>
```

### For Sub-organizations

* SMS auth is enabled by default
* Disable during creation using `disableSmsAuth: true` in the `CreateSubOrganizationIntentV7` activity
* Disable after creation using `ACTIVITY_TYPE_REMOVE_ORGANIZATION_FEATURE` with feature name `FEATURE_NAME_SMS_AUTH`

## Implementation Notes

* Users are limited to 10 long-lived API keys and 10 expiring API keys
* When the expiring API key limit is reached, the oldest key is automatically discarded

## OTP Rate Limits

In order to safeguard users, Turnkey enforces rate limits for OTP auth activities. If a `userIdentifier` parameter is provided, the following limits are enforced:

* 3 requests per 3 minutes per unique `userIdentifier`
* 3 retries max per code, after which point that code will be locked
* 3 active codes per user, each with a 5 minute TTL
