CINXE.COM
Verify phone numbers on the web with the WebOTP API | Identity | Chrome for Developers
<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="157101835696-ooapojlodmuabs2do2vuhhnf90bccmoi.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="Chrome for Developers"> <meta property="og:type" content="website"><meta name="theme-color" content="#1a73e8"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/chrome/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/favicon.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/touchicon-180.png"><link rel="canonical" href="https://developer.chrome.com/docs/identity/web-apis/web-otp"><link rel="search" type="application/opensearchdescription+xml" title="Chrome for Developers" href="https://developer.chrome.com/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://developer.chrome.com/docs/identity/web-apis/web-otp" /><link rel="alternate" hreflang="x-default" href="https://developer.chrome.com/docs/identity/web-apis/web-otp" /><link rel="alternate" hreflang="ar" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=ar" /><link rel="alternate" hreflang="bn" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=zh-tw" /><link rel="alternate" hreflang="nl" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=nl" /><link rel="alternate" hreflang="fa" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=fa" /><link rel="alternate" hreflang="fr" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=fr" /><link rel="alternate" hreflang="de" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=de" /><link rel="alternate" hreflang="he" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=he" /><link rel="alternate" hreflang="hi" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=hi" /><link rel="alternate" hreflang="id" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=id" /><link rel="alternate" hreflang="it" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=it" /><link rel="alternate" hreflang="ja" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=ja" /><link rel="alternate" hreflang="ko" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=ko" /><link rel="alternate" hreflang="pl" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=pt-br" /><link rel="alternate" hreflang="ru" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=ru" /><link rel="alternate" hreflang="es-419" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=es-419" /><link rel="alternate" hreflang="th" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=th" /><link rel="alternate" hreflang="tr" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=tr" /><link rel="alternate" hreflang="vi" href="https://developer.chrome.com/docs/identity/web-apis/web-otp?hl=vi" /><link rel="alternate" hreflang="en-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp" /><link rel="alternate" hreflang="x-default" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp" /><link rel="alternate" hreflang="ar-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=ar" /><link rel="alternate" hreflang="bn-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=bn" /><link rel="alternate" hreflang="zh-Hans-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=zh-tw" /><link rel="alternate" hreflang="nl-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=nl" /><link rel="alternate" hreflang="fa-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=fa" /><link rel="alternate" hreflang="fr-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=fr" /><link rel="alternate" hreflang="de-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=de" /><link rel="alternate" hreflang="he-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=he" /><link rel="alternate" hreflang="hi-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=hi" /><link rel="alternate" hreflang="id-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=id" /><link rel="alternate" hreflang="it-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=it" /><link rel="alternate" hreflang="ja-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=ja" /><link rel="alternate" hreflang="ko-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=ko" /><link rel="alternate" hreflang="pl-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=pl" /><link rel="alternate" hreflang="pt-BR-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=pt-br" /><link rel="alternate" hreflang="ru-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=ru" /><link rel="alternate" hreflang="es-419-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=es-419" /><link rel="alternate" hreflang="th-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=th" /><link rel="alternate" hreflang="tr-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=tr" /><link rel="alternate" hreflang="vi-cn" href="https://developer.chrome.google.cn/docs/identity/web-apis/web-otp?hl=vi" /><title>Verify phone numbers on the web with the WebOTP API | Identity | Chrome for Developers</title> <meta property="og:title" content="Verify phone numbers on the web with the WebOTP API | Identity | Chrome for Developers"><meta name="description" content="Finding, memorizing, and typing OTPs sent via SMS is cumbersome. The WebOTP API simplifies the OTP workflow for users."> <meta property="og:description" content="Finding, memorizing, and typing OTPs sent via SMS is cumbersome. The WebOTP API simplifies the OTP workflow for users."><meta property="og:url" content="https://developer.chrome.com/docs/identity/web-apis/web-otp"><meta property="og:locale" content="en"><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "dateModified": "2019-10-07", "headline": "Verify phone numbers on the web with the WebOTP API" } </script><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Docs", "item": "https://developer.chrome.com/docs" },{ "@type": "ListItem", "position": 2, "name": "Identity", "item": "https://developer.chrome.com/docs/identity" },{ "@type": "ListItem", "position": 3, "name": "Verify phone numbers on the web with the WebOTP API", "item": "https://developer.chrome.com/docs/identity/web-apis/web-otp" }] } </script> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="page" theme="chrome-theme" type="article" appearance layout="docs" display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner"> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="chromeForDevelopers" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Chrome for Developers"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup.svg" class="devsite-site-logo" alt="Chrome for Developers"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> <devsite-tabs class="upper-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Upper tabs"> <tab > <a href="https://developer.chrome.com/case-studies" track-metadata-eventdetail="https://developer.chrome.com/case-studies" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - get inspired" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Get inspired" track-name="get inspired" > Get inspired </a> </tab> <tab > <a href="https://developer.chrome.com/blog" track-metadata-eventdetail="https://developer.chrome.com/blog" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - blog" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" > Blog </a> </tab> <tab class="devsite-dropdown devsite-dropdown-full "> <a href="https://developer.chrome.com/docs" track-metadata-eventdetail="https://developer.chrome.com/docs" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - docs" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" > Docs </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Docs" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs" track-metadata-position="nav - docs" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section build-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Build with Chrome</li> <li class="devsite-nav-description">Learn how Chrome works, participate in origin trials, and build with Chrome everywhere. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/web-platform" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/web-platform" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Web Platform </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/capabilities" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/capabilities" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Capabilities </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/chromedriver" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/chromedriver" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> ChromeDriver </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/extensions" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/extensions" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Extensions </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/webstore" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/webstore" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Chrome Web Store </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/chromium" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/chromium" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Chromium </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/aurora" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/aurora" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Aurora </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/android" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/android" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Web on Android </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/origintrials/" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/origintrials/" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Origin trials </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/release-notes" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/release-notes" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Release notes </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section productivity-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Productivity</li> <li class="devsite-nav-description">Create the best experience for your users with the web's best tools.</li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/devtools" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/devtools" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> DevTools </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/lighthouse" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/lighthouse" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Lighthouse </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/crux" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/crux" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Chrome UX Report </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/accessibility" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/accessibility" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Accessibility </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section dcc-subnav second-column-list"> <li class="devsite-nav-description">Get things done quicker and neater, with our ready-made libraries. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/workbox" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/workbox" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Workbox </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/puppeteer" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/puppeteer" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Puppeteer </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section experience-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Experience</li> <li class="devsite-nav-description">Design a beautiful and performant web with Chrome. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/ai" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/ai" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> AI </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/performance" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/performance" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Performance </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/css-ui" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/css-ui" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> CSS and UI </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/identity" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/identity" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Identity </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/payments" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/payments" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Payments </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/privacy-security" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/privacy-security" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Privacy and security </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section resources-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Resources</li> <li class="devsite-nav-description">More from the Chrome team. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="resources" tooltip > <div class="devsite-nav-item-title"> All documentation </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/baseline" track-type="nav" track-metadata-eventdetail="https://web.dev/baseline" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="resources" tooltip > <div class="devsite-nav-item-title"> Baseline </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev" track-type="nav" track-metadata-eventdetail="https://web.dev" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="resources" tooltip > <div class="devsite-nav-item-title"> web.dev </div> </a> </li> </ul> </div> </div> </div> </tab> <tab > <a href="https://developer.chrome.com/new" track-metadata-eventdetail="https://developer.chrome.com/new" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - new in chrome" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: New in Chrome" track-name="new in chrome" > New in Chrome </a> </tab> </nav> </devsite-tabs> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion project-name="Identity" tenant-name="Chrome for Developers" > <form class="devsite-search-form" action="https://developer.chrome.com/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="nl" >Nederlands</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <devsite-user enable-profiles id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> <div class="devsite-collapsible-section devsite-header-no-lower-tabs "> <div class="devsite-header-background"> <div class="devsite-product-id-row" > <div class="devsite-product-description-row"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> <a href="https://developer.chrome.com/docs/identity" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Lower Header" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="Identity" > Identity </a> </li> </ul> </div> </div> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars hidden> <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="chromeForDevelopers" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Chrome for Developers"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup.svg" class="devsite-site-logo" alt="Chrome for Developers"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="/case-studies" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Get inspired" track-name="get inspired" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Get inspired" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Get inspired </span> </a> </li> <li class="devsite-nav-item"> <a href="/blog" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Blog" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Blog </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Docs" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Docs </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" > <span class="devsite-nav-text" tooltip menu="Docs"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Docs"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/new" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: New in Chrome" track-name="new in chrome" data-category="Site-Wide Custom Events" data-label="Responsive Tab: New in Chrome" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > New in Chrome </span> </a> </li> </ul> </div> <div class="devsite-mobile-nav-bottom"> <ul class="devsite-nav-list" menu="Docs" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Build with Chrome </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs/web-platform" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Web Platform" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Web Platform </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/capabilities" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Capabilities" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Capabilities </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/chromedriver" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: ChromeDriver" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > ChromeDriver </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/extensions" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Extensions" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Extensions </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/webstore" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Chrome Web Store" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Chrome Web Store </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/chromium" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Chromium" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Chromium </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/aurora" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Aurora" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Aurora </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/android" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Web on Android" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Web on Android </span> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/origintrials/" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Origin trials" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Origin trials </span> </a> </li> <li class="devsite-nav-item"> <a href="/release-notes" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Release notes" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Release notes </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Productivity </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs/devtools" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: DevTools" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > DevTools </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/lighthouse" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Lighthouse" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Lighthouse </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/crux" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Chrome UX Report" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Chrome UX Report </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/accessibility" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Accessibility" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Accessibility </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/workbox" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Workbox" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Workbox </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/puppeteer" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Puppeteer" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Puppeteer </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Experience </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs/ai" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: AI" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > AI </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/performance" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Performance" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Performance </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/css-ui" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: CSS and UI" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > CSS and UI </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/identity" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Identity" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Identity </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/payments" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Payments" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Payments </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/privacy-security" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Privacy and security" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Privacy and security </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Resources </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: All documentation" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > All documentation </span> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/baseline" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Baseline" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Baseline </span> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: web.dev" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > web.dev </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" class="devsite-main-content" has-sidebar > <div class="devsite-sidebar"> <div class="devsite-sidebar-content"> <devsite-toc class="devsite-nav" role="navigation" aria-label="On this page" depth="2" scrollbars ></devsite-toc> <devsite-recommendations-sidebar class="nocontent devsite-nav"> </devsite-recommendations-sidebar> </div> </div> <devsite-content> <article class="devsite-article"> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" aria-label="Breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://developer.chrome.com/" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="" > Home </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developer.chrome.com/docs" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="Docs" > Docs </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developer.chrome.com/docs/identity" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="3" track-type="globalNav" track-name="breadcrumb" track-metadata-position="3" track-metadata-eventdetail="Identity" > Identity </a> </li> </ul> <devsite-thumb-rating position="header"> </devsite-thumb-rating> </div> <h1 class="devsite-page-title" tabindex="-1"> Verify phone numbers on the web with the WebOTP API </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <div class="devsite-page-title-meta"><devsite-view-release-notes></devsite-view-release-notes></div> <devsite-toc class="devsite-nav" depth="2" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <p>Help users with OTPs received through SMS</p> <p><style> .wd-authors { --avatar-size: 65px; display: flex; gap: 2em; } .wd-author { display: flex; flex-wrap: wrap; gap: 1em; line-height: calc(var(--avatar-size) / 2); } .wd-author img { border-radius: 50%; height: var(--avatar-size, 65px); width: var(--avatar-size, 65px); } .dcc-authors { --avatar-size: 65px; display: flex; gap: 2em; } .dcc-author { display: flex; flex-wrap: wrap; gap: 1em; line-height: calc(var(--avatar-size) / 2); } .dcc-author img { border-radius: 50%; height: var(--avatar-size, 65px); width: var(--avatar-size, 65px); } .dcc-author__links a { margin-inline-end: 6px; } .dcc-author__links a:last-of-type { margin-inline-end: 0; } </style> <div class="dcc-authors" translate="no"> <div class="dcc-author"> <img class="devsite-landing-row-item-icon" alt="Eiji Kitamura" src="https://web.dev/images/authors/agektmr.jpg" decoding="async" height="64" loading="lazy" width="64"> <div> <span> Eiji Kitamura </span> <div class="dcc-author__links"> <a href="https://twitter.com/agektmr" aria-label="Eiji Kitamura on X" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 300 271"> <title>X</title> <path fill="currentColor" d="m236 0h46l-101 115 118 156h-92.6l-72.5-94.8-83 94.8h-46l107-123-113-148h94.9l65.5 86.6zm-16.1 244h25.5l-165-218h-27.4z"></path> </svg></a> <a href="https://github.com/agektmr" aria-label="Eiji Kitamura on GitHub" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32.6 31.8"> <title>GitHub</title> <path d="M16.3 0C7.3 0 0 7.3 0 16.3c0 7.2 4.7 13.3 11.1 15.5.8.1 1.1-.4 1.1-.8v-2.8c-4.5 1-5.5-2.2-5.5-2.2-.7-1.9-1.8-2.4-1.8-2.4-1.5-1 .1-1 .1-1 1.6.1 2.5 1.7 2.5 1.7 1.5 2.5 3.8 1.8 4.7 1.4.1-1.1.6-1.8 1-2.2-3.6-.4-7.4-1.8-7.4-8.1 0-1.8.6-3.2 1.7-4.4-.1-.3-.7-2 .2-4.2 0 0 1.4-.4 4.5 1.7 1.3-.4 2.7-.5 4.1-.5 1.4 0 2.8.2 4.1.5 3.1-2.1 4.5-1.7 4.5-1.7.9 2.2.3 3.9.2 4.3 1 1.1 1.7 2.6 1.7 4.4 0 6.3-3.8 7.6-7.4 8 .6.5 1.1 1.5 1.1 3V31c0 .4.3.9 1.1.8 6.5-2.2 11.1-8.3 11.1-15.5C32.6 7.3 25.3 0 16.3 0z" fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" /> </svg></a> <a href="https://glitch.com/@agektmr" aria-label="Eiji Kitamura on Glitch" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32 32"> <title>Glitch</title> <path fill="currentColor" d="M31.734 16.76c-.385-.198-4.536 1.865-5.427 1.693-2.24-.401-1.828-.667-4.839-1.359-1.203-.266-1.031-.109-1.297-.307-.172-.135-.344-.161-.599-.401 4-.719 6.026-1.693 6.734-1.839.76-.146 5.161 1.958 5.427 1.469.266-.495-.964-1.578-.401-3.031.589-1.464-.693-2.422.016-3.583.719-1.161.573-2.932.396-3.026-.396-.203-4.531 1.865-5.438 1.693-2.24-.417-1.828-.682-4.839-1.359-1.203-.271-1.031-.12-1.297-.323-.266-.198-.521-.13-1.036-.974-.521-.839-6.51-2.13-6.906-2.13-.828 0-2.375 2.13-2.375 2.13s-.599 0-2.401.094c-1.802.094-3.375.896-5.495 2.563C-.173 9.737.134 11.414.134 11.414s1.969.667 1.969 1.042c0 .359-1.729.802-1.729.802 1.12 1.411 4.583 2.745 5.464 2.745h.693c-1.438.281-2.823 1.068-4.583 2.438-2.12 1.698-1.813 3.375-1.813 3.375s1.969.667 1.969 1.026-1.729.802-1.729.802c1.12 1.427 4.583 2.76 5.464 2.76.844 0 1.427.026 2.495-.172.078.172.906 1.932 2.599 2.292 1.786.385 2.776.078 2.776.078s.094-.786-.323-1.573c1.547.161 3.307.203 5.026-.068 4.76-.719 7.12-1.865 7.896-2.01.76-.161 5.161 1.948 5.427 1.464.266-.505-.964-1.583-.385-3.036.573-1.469-.708-2.417 0-3.589.719-1.161.573-2.932.396-3.026zM4.615 11.828a1.446 1.446 0 0 1-.297-.042h-.052c-.026-.01-.052-.026-.078-.042l-.052-.01-.083-.042h-.052a.418.418 0 0 1-.068-.042l-.068-.052-.063-.036-.057-.042c-.021-.016-.042-.036-.063-.052l-.042-.042c-.026-.026-.047-.052-.068-.078l-.026-.031a1.954 1.954 0 0 1-.094-.104l-.026-.026c-.021-.036-.036-.073-.052-.109l-.026-.036-.057-.083c-.005-.021-.016-.042-.026-.063l-.026-.083-.026-.052-.016-.094-.01-.068c-.01-.026-.021-.052-.026-.078v-.068c.094.573.557 1.016 1.104 1.016.63 0 1.146-.573 1.146-1.297 0-.719-.505-1.307-1.146-1.307-.625 0-1.13.573-1.146 1.281 0-.932.667-1.693 1.495-1.693.823 0 1.479.745 1.479 1.682 0 .932-.667 1.693-1.479 1.693zm-1-1.265c0-.203.13-.365.318-.365s.307.161.307.365c0 .198-.135.344-.307.344s-.318-.161-.318-.344zm1 11.651a.712.712 0 0 1-.146 0l-.057-.016a.6.6 0 0 1-.094-.01l-.052-.016-.078-.026-.052-.026c-.031-.005-.057-.016-.083-.026l-.052-.026c-.021-.016-.047-.026-.068-.042L3.881 22l-.068-.052-.052-.042-.068-.052-.042-.042c-.031-.031-.063-.057-.089-.094a.671.671 0 0 1-.094-.12l-.031-.026c-.016-.031-.036-.063-.052-.094l-.026-.052c-.016-.026-.036-.052-.052-.078l-.026-.057-.026-.094-.026-.052-.031-.094-.01-.052c-.01-.031-.021-.063-.026-.094v-.068c.094.573.557 1.016 1.104 1.016.63 0 1.146-.573 1.146-1.292 0-.724-.505-1.297-1.146-1.297-.625 0-1.13.563-1.146 1.266 0-.932.667-1.693 1.495-1.693.823 0 1.479.76 1.479 1.682 0 .917-.667 1.693-1.479 1.693zm-1-1.266c0-.188.13-.349.318-.349s.307.161.307.349c0 .188-.135.344-.307.344s-.318-.146-.318-.344zm6.77-7.333v-.042l.042-.078.078-.297c.182-.583.344-1.172.479-1.771.161-.708.229-1.281.203-1.599-.016-.12-.031-.245-.052-.359a8.276 8.276 0 0 0-.521-1.724l-.083-.172-.026-.068c-.12-.266.057-.573.323-.557h.188l.531.036 2.104.109 1.151.078a28.24 28.24 0 0 1 10.573 2.828l.891.401c.172.078.266.307.188.505-.068.188-.266.292-.438.214l-.896-.401a27.695 27.695 0 0 0-10.359-2.786l-1.146-.068-.51-.026-1.599-.094h-.156c.188.51.339 1.031.453 1.562l.063.427c.042.453-.036 1.078-.224 1.88l-.203.823a23.62 23.62 0 0 1-.385 1.323l-.026.078v.042c-.068.188-.266.292-.438.214-.177-.068-.271-.292-.203-.495zm-2-6.349a.307.307 0 0 1 .479.026c.208.26.396.536.563.828.292.531.495 1.068.547 1.615.026.307 0 .651-.052 1.026a8.718 8.718 0 0 1-.271 1.104c-.094.313-.208.62-.333.922-.078.188-.276.266-.453.172-.172-.094-.24-.318-.156-.521l.026-.052.068-.172c.073-.198.146-.396.214-.599.099-.328.182-.661.24-1 .052-.307.063-.573.052-.802a3.47 3.47 0 0 0-.453-1.292 4.794 4.794 0 0 0-.443-.667l-.036-.042a.417.417 0 0 1 .026-.531zm1.537 13.869c-.063.38-.151.76-.271 1.13a9.549 9.549 0 0 1-.333.906c-.078.188-.276.266-.453.177-.172-.094-.24-.323-.156-.521l.026-.057.068-.172c.073-.198.146-.396.214-.599.099-.328.182-.661.24-1 .052-.307.063-.573.036-.802a3.365 3.365 0 0 0-.438-1.276 4.794 4.794 0 0 0-.443-.667l-.036-.057a.417.417 0 0 1 .026-.531.3.3 0 0 1 .464 0c.214.266.396.547.563.839.292.536.495 1.083.547 1.615.026.307 0 .651-.052 1.026zm16.531.157c-.068.188-.266.297-.438.214l-.896-.401a27.695 27.695 0 0 0-10.359-2.786l-1.135-.063h-.063l-.458-.026c-.583-.036-1.172-.068-1.755-.094l.036.078c.234.615.396 1.255.479 1.906.042.453-.036 1.078-.224 1.88l-.203.828a24.99 24.99 0 0 1-.385 1.333l-.026.068v.036c-.068.203-.266.297-.438.229a.42.42 0 0 1-.203-.51v-.026l.042-.078.078-.292c.182-.589.344-1.177.479-1.776.161-.708.229-1.281.203-1.599-.016-.12-.031-.24-.052-.359a7.996 7.996 0 0 0-.521-1.708l-.052-.12-.031-.068-.026-.063c-.12-.271.057-.578.323-.563h.188l.531.042 2.12.104 1.135.083a28.14 28.14 0 0 1 10.573 2.823l.891.401c.172.078.266.307.188.505z"/> </svg></a> <a href="https://infosec.exchange/@agektmr" aria-label="Eiji Kitamura on Mastodon" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 16 16"> <title>Mastodon</title> <path fill="currentColor" d="M 15.659 9.592 C 15.424 10.72 13.553 11.956 11.404 12.195 C 10.283 12.32 9.18 12.434 8.003 12.384 C 6.079 12.302 4.56 11.956 4.56 11.956 C 4.56 12.13 4.572 12.297 4.595 12.452 C 4.845 14.224 6.478 14.33 8.025 14.379 C 9.586 14.429 10.976 14.02 10.976 14.02 L 11.04 15.337 C 11.04 15.337 9.948 15.884 8.003 15.984 C 6.93 16.039 5.598 15.959 4.047 15.576 C 0.683 14.746 0.104 11.4 0.015 8.006 C -0.012 6.998 0.005 6.048 0.005 5.253 C 0.005 1.782 2.443 0.765 2.443 0.765 C 3.672 0.238 5.782 0.017 7.975 0 L 8.029 0 C 10.221 0.017 12.332 0.238 13.561 0.765 C 13.561 0.765 15.999 1.782 15.999 5.253 C 15.999 5.253 16.03 7.814 15.659 9.592 Z M 13.124 5.522 L 13.124 9.725 L 11.339 9.725 L 11.339 5.646 C 11.339 4.786 10.951 4.35 10.175 4.35 C 9.317 4.35 8.887 4.867 8.887 5.891 L 8.887 8.124 L 7.113 8.124 L 7.113 5.891 C 7.113 4.867 6.683 4.35 5.825 4.35 C 5.049 4.35 4.661 4.786 4.661 5.646 L 4.661 9.725 L 2.876 9.725 L 2.876 5.522 C 2.876 4.663 3.111 3.981 3.582 3.476 C 4.067 2.971 4.703 2.712 5.493 2.712 C 6.406 2.712 7.098 3.039 7.555 3.695 L 8 4.39 L 8.445 3.695 C 8.902 3.039 9.594 2.712 10.507 2.712 C 11.297 2.712 11.933 2.971 12.418 3.476 C 12.889 3.981 13.124 4.663 13.124 5.522 Z" style="stroke:none;stroke-miterlimit:10;fill-rule:evenodd;"></path> </svg></a> </div> </div> </div> </div></p> <aside class="key-point"><b>Key point:</b> If you want to learn more general SMS OTP form best practices including WebOTP API, checkout <a href="https://web.dev/sms-otp-form">SMS OTP form best practices</a>.</aside> <h2 id="what_is_the_webotp_api" data-text="What is the WebOTP API?" tabindex="-1">What is the WebOTP API?</h2> <p>These days, most people in the world own a mobile device and developers are commonly using phone numbers as an identifier for users of their services.</p> <p>There are a variety of ways to verify phone numbers, but a randomly generated one-time password (OTP) sent by SMS is one of the most common. Sending this code back to the developer's server demonstrates control of the phone number.</p> <p>This idea is already deployed in many scenarios to achieve:</p> <ul> <li><strong>Phone number as an identifier for the user.</strong> When signing up for a new service, some websites ask for a phone number instead of an email address and use it as an account identifier.</li> <li><strong>Two step verification.</strong> When signing in, a website asks for a one-time code sent via SMS on top of a password or other knowledge factor for extra security.</li> <li><strong>Payment confirmation.</strong> When a user is making a payment, asking for a one-time code sent via SMS can help verify the person's intent.</li> </ul> <p>The current process creates friction for users. Finding an OTP within an SMS message, then copying and pasting it to the form is cumbersome, lowering conversion rates in critical user journeys. Easing this has been a long standing request for the web from many of the largest global developers. Android has <a href="https://developers.google.com/identity/sms-retriever/">an API that does exactly this</a>. So does <a href="https://developer.apple.com/documentation/security/password_autofill/about_the_password_autofill_workflow">iOS</a> and <a href="https://developer.apple.com/documentation/security/password_autofill/enabling_password_autofill_on_an_html_input_element">Safari</a>.</p> <p>The WebOTP API lets your app receive specially-formatted messages bound to your app's domain. From this, you can programmatically obtain an OTP from an SMS message and verify a phone number for the user more easily.</p> <aside class="warning"><b>Warning:</b> Attackers can spoof SMS and hijack a person's phone number. Carriers can also recycle phone numbers to new users after an account is closed. While SMS OTP is useful to verify a phone number for the use cases above, we recommend using additional and stronger forms of authentication (such as multiple factors and the <a href="https://developer.mozilla.org/docs/Web/API/Web_Authentication_API">Web Authentication API</a> to establish new sessions for these users.</aside> <h2 id="see_it_in_action" data-text="See it in action" tabindex="-1">See it in action</h2> <p>Let's say a user wants to verify their phone number with a website. The website sends a text message to the user over SMS and the user enters the OTP from the message to verify the ownership of the phone number.</p> <p>With the WebOTP API, these steps are as easy as one tap for the user, as demonstrated in the video. When the text message arrives, a bottom sheet pops up and prompts the user to verify their phone number. After clicking the <strong>Verify</strong> button on the bottom sheet, the browser pastes the OTP into the form and the form is submitted without the user needing to press <strong>Continue</strong>.</p> <video autoplay loop muted playsinline> <source src="/static/docs/identity/web-apis/web-otp/video/web-dev-assets/web-otp/demo.mp4" type="video/mp4"> <source src="/static/docs/identity/web-apis/web-otp/video/web-dev-assets/web-otp/demo.webm" type="video/webm"> </video> <p>The whole process is diagrammed in the image below.</p> <figure> <img src="/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe.png" alt width="494" height="391" srcset="https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_36.png 36w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_48.png 48w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_72.png 72w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_96.png 96w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_480.png 480w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_720.png 720w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_856.png 856w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_960.png 960w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_1440.png 1440w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_1920.png 1920w,https://developer.chrome.com/static/docs/identity/web-apis/web-otp/image/GrFHzEg98jxCOguAQwHe_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="dcc-caption"> WebOTP API diagram </figcaption> </figure> <p>Try <a href="https://web-otp.glitch.me">the demo</a> yourself. It doesn't ask for your phone number or send an SMS to your device, but you can send one from another device by copying the text displayed in the demo. This works because it doesn't matter who the sender is when using the WebOTP API.</p> <ol> <li>Go to <a href="https://web-otp.glitch.me">https://web-otp.glitch.me</a> in Chrome 84 or later on an Android device.</li> <li>Send your phone the following SMS text message from the another phone.</li> </ol> <pre class="prettyprint lang-text" translate="no" dir="ltr"><code translate="no" dir="ltr">Your OTP is: 123456. @web-otp.glitch.me #12345 </code></pre> <p>Did you receive the SMS and see the prompt to enter the code to the input area? That is how the WebOTP API works for users.</p> <aside class="key-point"><b>Key point:</b> If the dialog doesn't appear for you, check out <a href="#no-dialog">the FAQ</a>.</aside> <p>Using the WebOTP API consists of three parts:</p> <ul> <li>A properly annotated <code translate="no" dir="ltr"><input></code> tag</li> <li>JavaScript in your web app</li> <li>Formatted message text sent via SMS.</li> </ul> <p>I'll cover the <code translate="no" dir="ltr"><input></code> tag first.</p> <h2 id="annotate_an_input_tag" data-text="Annotate an <input> tag" tabindex="-1">Annotate an <code translate="no" dir="ltr"><input></code> tag</h2> <p>WebOTP itself works without any HTML annotation, but for cross-browser compatibility, I highly recommend that you add <code translate="no" dir="ltr">autocomplete="one-time-code"</code> to the <code translate="no" dir="ltr"><input></code> tag where you expect the user entering an OTP.</p> <p>This allows Safari 14 or later to suggest that the user to autofill the <code translate="no" dir="ltr"><input></code> field with an OTP when they receive an SMS with the format described in <a href="#format">Format the SMS message</a> even though it doesn't support WebOTP.</p> <p><span class="dcc-label">HTML</span></p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><form> <input autocomplete="one-time-code" required/> <input type="submit"> </form> </code></pre> <h2 id="use_the_webotp_api" data-text="Use the WebOTP API" tabindex="-1">Use the WebOTP API</h2> <p>Because WebOTP is simple, just copying and pasting the following code will do the job. I'll walk you through what's happening anyway.</p> <p><span class="dcc-label">JavaScript</span></p> <pre class="prettyprint lang-js" translate="no" dir="ltr"><code translate="no" dir="ltr">if ('OTPCredential' in window) { window.addEventListener('DOMContentLoaded', e => { const input = document.querySelector('input[autocomplete="one-time-code"]'); if (!input) return; const ac = new AbortController(); const form = input.closest('form'); if (form) { form.addEventListener('submit', e => { ac.abort(); }); } navigator.credentials.get({ otp: { transport:['sms'] }, signal: ac.signal }).then(otp => { input.value = otp.code; if (form) form.submit(); }).catch(err => { console.log(err); }); }); } </code></pre> <h3 id="feature_detection" data-text="Feature detection" tabindex="-1">Feature detection</h3> <p>Feature detection is the same as for many other APIs. Listening to <code translate="no" dir="ltr">DOMContentLoaded</code> event will wait for the DOM tree to be ready to query.</p> <p><span class="dcc-label">JavaScript</span></p> <pre class="prettyprint lang-js" translate="no" dir="ltr"><code translate="no" dir="ltr">if ('OTPCredential' in window) { window.addEventListener('DOMContentLoaded', e => { const input = document.querySelector('input[autocomplete="one-time-code"]'); if (!input) return; … const form = input.closest('form'); … }); } </code></pre> <aside class="caution"><b>Caution:</b> The WebOTP API requires a secure origin (HTTPS). The feature detection on an HTTP website will fail.</aside> <h3 id="process_the_otp" data-text="Process the OTP" tabindex="-1">Process the OTP</h3> <p>The WebOTP API itself is simple enough. Use <a href="https://developer.mozilla.org/docs/Web/API/CredentialsContainer/get"><code translate="no" dir="ltr">navigator.credentials.get()</code></a> to obtain the OTP. WebOTP adds a new <code translate="no" dir="ltr">otp</code> option to that method. It only has one property: <code translate="no" dir="ltr">transport</code>, whose value must be an array with the string <code translate="no" dir="ltr">'sms'</code>.</p> <p><span class="dcc-label">JavaScript</span></p> <pre class="prettyprint lang-js/1-2" translate="no" dir="ltr"><code translate="no" dir="ltr"> … navigator.credentials.get({ otp: { transport:['sms'] } … }).then(otp => { … </code></pre> <p>This triggers the browser's permission flow when an SMS message arrives. If permission is granted, the returned promise resolves with an <code translate="no" dir="ltr">OTPCredential</code> object.</p> <p><span class="dcc-label">Content of obtained <code translate="no" dir="ltr">OTPCredential</code> object</span></p> <pre class="prettyprint lang-json" translate="no" dir="ltr"><code translate="no" dir="ltr">{ code: "123456" // Obtained OTP type: "otp" // `type` is always "otp" } </code></pre> <p>Next, pass the OTP value to the <code translate="no" dir="ltr"><input></code> field. Submitting the form directly will eliminate the step requiring the user to tap a button.</p> <p><span class="dcc-label">JavaScript</span></p> <pre class="prettyprint lang-js/5-6" translate="no" dir="ltr"><code translate="no" dir="ltr"> … navigator.credentials.get({ otp: { transport:['sms'] } … }).then(otp => { input.value = otp.code; if (form) form.submit(); }).catch(err => { console.error(err); }); … </code></pre> <h3 id="aborting" data-text="Aborting the message" tabindex="-1">Aborting the message</h3> <p>In case the user manually enters an OTP and submits the form, you can cancel the <code translate="no" dir="ltr">get()</code> call by using an <code translate="no" dir="ltr">AbortController</code> instance in the <a href="https://developer.mozilla.org/docs/Web/API/CredentialsContainer/get#Parameters"><code translate="no" dir="ltr">options</code> object</a>.</p> <p><span class="dcc-label"> JavaScript </span></p> <pre class="prettyprint lang-js/1,5,11" translate="no" dir="ltr"><code translate="no" dir="ltr"> … const ac = new AbortController(); … if (form) { form.addEventListener('submit', e => { ac.abort(); }); } … navigator.credentials.get({ otp: { transport:['sms'] }, signal: ac.signal }).then(otp => { … </code></pre> <h2 id="format" data-text="Format the SMS message" tabindex="-1">Format the SMS message</h2> <p>The API itself should look simple enough, but there are a few things you should know before using it. The message must be sent after <code translate="no" dir="ltr">navigator.credentials.get()</code> is called and it must be received on the device where <code translate="no" dir="ltr">get()</code> was called. Finally, the message must adhere to the following formatting:</p> <ul> <li>The message begins with (optional) human-readable text that contains a four to ten character alphanumeric string with at least one number leaving the last line for the URL and the OTP.</li> <li>The domain part of the URL of the website that invoked the API must be preceded by <code translate="no" dir="ltr">@</code>.</li> <li>The URL must contain a pound sign ('<code translate="no" dir="ltr">#</code>') followed by the OTP.</li> </ul> <p>For example:</p> <pre class="prettyprint lang-text" translate="no" dir="ltr"><code translate="no" dir="ltr">Your OTP is: 123456. @www.example.com #123456 </code></pre> <p>Here are bad examples:</p> <table> <thead> <tr> <th>Example malformed SMS Text</th> <th>Why this won't work</th> </tr> </thead> <tbody> <tr> <td><code translate="no" dir="ltr">Here is your code for @example.com #123456</code></td> <td><code translate="no" dir="ltr">@</code> is expected to be the first character of the last line.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your code for @example.com is #123456</code></td> <td><code translate="no" dir="ltr">@</code> is expected to be the first character of the last line.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@example.com\t#123456</code></td> <td>A single space is expected between <code translate="no" dir="ltr">@host</code> and <code translate="no" dir="ltr">#code</code>.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@example.com</code><code translate="no" dir="ltr"> </code><code translate="no" dir="ltr">#123456</code></td> <td>A single space is expected between <code translate="no" dir="ltr">@host</code> and <code translate="no" dir="ltr">#code</code>.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@ftp://example.com #123456</code></td> <td>URL scheme cannot be included.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@https://example.com #123456</code></td> <td>URL scheme cannot be included.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@example.com:8080 #123456</code></td> <td>Port cannot be included.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@example.com/foobar #123456</code></td> <td>Path cannot be included.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@example .com #123456</code></td> <td>No whitespace in domain.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@domain-forbiden-chars-#%/:<>?@[] #123456</code></td> <td>No <a href="https://url.spec.whatwg.org/#forbidden-host-code-point">forbidden chars</a> in domain.</td> </tr> <tr> <td><code translate="no" dir="ltr">@example.com #123456</code><br/><br/><code translate="no" dir="ltr">Mambo Jumbo</code></td> <td><code translate="no" dir="ltr">@host</code> and <code translate="no" dir="ltr">#code</code> are expected to be the last line.</td> </tr> <tr> <td><code translate="no" dir="ltr">@example.com #123456</code><br/><br/><code translate="no" dir="ltr">App hash #oudf08lkjsdf834</code></td> <td><code translate="no" dir="ltr">@host</code> and <code translate="no" dir="ltr">#code</code> are expected to be the last line.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">@example.com 123456</code></td> <td>Missing <code translate="no" dir="ltr">#</code>.</td> </tr> <tr> <td><code translate="no" dir="ltr">Your verification code is 123456</code><br/><br/><code translate="no" dir="ltr">example.com #123456</code></td> <td>Missing <code translate="no" dir="ltr">@</code>.</td> </tr> <tr> <td><code translate="no" dir="ltr">Hi mom, did you receive my last text</code></td> <td>Missing <code translate="no" dir="ltr">@</code> and <code translate="no" dir="ltr">#</code>.</td> </tr> </tbody> </table> <h2 id="demos" data-text="Demos" tabindex="-1">Demos</h2> <p>Try various messages with the demo: <a href="https://web-otp.glitch.me">https://web-otp.glitch.me</a></p> <p>You may also fork it and create your version: <a href="https://glitch.com/edit/#!/web-otp">https://glitch.com/edit/#!/web-otp</a>.</p> <div class="dcc-embed" style="height: 420px;"> <iframe style="height: 100%; width: 100%; border: 0;" title="web-otp on Glitch" src="https://glitch.com/embed/#!/embed/web-otp?attributionHidden=true&sidebarCollapsed=true&path=views%2Findex.html&previewSize=0" allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi" loading="lazy"></iframe> </div> <h2 id="use_webotp_from_a_cross-origin_iframe" data-text="Use WebOTP from a cross-origin iframe" tabindex="-1">Use WebOTP from a cross-origin iframe</h2> <p>Entering an SMS OTP to a cross-origin iframe is typically used for payment confirmation, especially with 3D Secure. Having the common format to support cross-origin iframes, WebOTP API delivers OTPs bound to nested origins. For example:</p> <ul> <li>A user visits <code translate="no" dir="ltr">shop.example</code> to purchase a pair of shoes with a credit card.</li> <li>After entering the credit card number, the integrated payment provider shows a form from <code translate="no" dir="ltr">bank.example</code> within an iframe asking the user to verify their phone number for fast checkout.</li> <li><code translate="no" dir="ltr">bank.example</code> sends an SMS that contains an OTP to the user so that they can enter it to verify their identity.</li> </ul> <p>To use WebOTP API from within a cross-origin iframe, you need to do two things:</p> <ul> <li>Annotate both the top-frame origin and the iframe origin in the SMS text message.</li> <li>Configure permissions policy to allow the cross-origin iframe to receive OTP from the user directly.</li> </ul> <figure> <video autoplay controls height="600" loop muted preload="auto" width="300" style="--vid-width: 300; --vid-height: 600" > <source src="/static/docs/identity/web-apis/web-otp/video/YLflGBAPWecgtKJLqCJHSzHqe2J2/Ba3OSkSsB4NwFkHGOuvc.mp4" type="video/mp4" /> </video> <figcaption class="dcc-caption"> WebOTP API within an iframe in action. </figcaption> </figure> <p>You can try the demo at <a href="https://web-otp-iframe-demo.stackblitz.io">https://web-otp-iframe-demo.stackblitz.io</a>.</p> <h3 id="annotate_bound-origins_to_the_sms_text_message" data-text="Annotate bound-origins to the SMS text message" tabindex="-1">Annotate bound-origins to the SMS text message</h3> <p>When WebOTP API is called from within an iframe, the SMS text message must include the top-frame origin preceded by <code translate="no" dir="ltr">@</code> followed by the OTP preceded by <code translate="no" dir="ltr">#</code> and the iframe origin preceded by <code translate="no" dir="ltr">@</code> at the last line.</p> <pre class="prettyprint lang-text" translate="no" dir="ltr"><code translate="no" dir="ltr">Your verification code is 123456 @shop.example #123456 @bank.exmple </code></pre> <h3 id="configure_permissions_policy" data-text="Configure Permissions Policy" tabindex="-1">Configure Permissions Policy</h3> <p>To use WebOTP in a cross-origin iframe, the embedder must grant access to this API via otp-credentials <a href="https://www.w3.org/TR/permissions-policy-1">permissions policy</a> to avoid unintended behavior. In general there are two ways to achieve this goal:</p> <p><span class="dcc-label">via HTTP Header:</span></p> <pre class="prettyprint lang-http" translate="no" dir="ltr"><code translate="no" dir="ltr">Permissions-Policy: otp-credentials=(self "https://bank.example") </code></pre> <p><span class="dcc-label">via iframe <code translate="no" dir="ltr">allow</code> attribute:</span></p> <pre class="prettyprint lang-html" translate="no" dir="ltr"><code translate="no" dir="ltr"><iframe src="https://bank.example/…" allow="otp-credentials"></iframe> </code></pre> <p>See <a href="/docs/privacy-sandbox/permissions-policy#example-permissions-policy-setups/">more examples on how to specify a permission policy </a>.</p> <aside class="note"><b>Note:</b> At the moment Chrome only supports WebOTP API calls from cross-origin iframes that have <strong>no more than one</strong> unique origin in its ancestor chain. In the following scenarios: <ul> <li><code translate="no" dir="ltr">a.com</code> -> <code translate="no" dir="ltr">b.com</code></li> <li><code translate="no" dir="ltr">a.com</code> -> <code translate="no" dir="ltr">b.com</code> -> <code translate="no" dir="ltr">b.com</code></li> <li><code translate="no" dir="ltr">a.com</code> -> <code translate="no" dir="ltr">a.com</code> -> <code translate="no" dir="ltr">b.com</code></li> <li><code translate="no" dir="ltr">a.com</code> -> <code translate="no" dir="ltr">b.com</code> -> <code translate="no" dir="ltr">c.com</code></li> </ul> using WebOTP in <code translate="no" dir="ltr">b.com</code> is supported but using it in <code translate="no" dir="ltr">c.com</code> is not. Note that the following scenario is also not supported because of lack of demand and UX complexities. <ul> <li><code translate="no" dir="ltr">a.com</code> -> <code translate="no" dir="ltr">b.com</code> -> <code translate="no" dir="ltr">a.com</code> (calls WebOTP API)</li> </ul></aside> <h2 id="use_webotp_on_desktop" data-text="Use WebOTP on desktop" tabindex="-1">Use WebOTP on desktop</h2> <p>In Chrome, WebOTP supports listening for SMSes received on other devices to assist users in completing phone number verification on desktop.</p> <figure> <video autoplay controls loop muted preload="auto" > <source src="/static/docs/identity/web-apis/web-otp/video/vgdbNJBYHma2o62ZqYmcnkq3j0o1/iUUGcawm8LJpGH3PFxNZ.mp4" type="video/mp4" /> </video> <figcaption class="dcc-caption"> WebOTP API on desktop. </figcaption> </figure> <p>This capability requires the user to sign-in to the same Google account on both desktop Chrome and Android Chrome.</p> <p>All developers have to do is to implement WebOTP API on their desktop website, the same way they do on their mobile website, but no special tricks are required.</p> <p>Learn more details at <a href="/blog/cross-device-webotp">Verify a phone number on desktop using WebOTP API</a>.</p> <h2 id="faq" data-text="FAQ" tabindex="-1">FAQ</h2> <h3 id="no-dialog" data-text="The dialog doesn't appear though I'm sending a properly formatted message. What's going wrong?" tabindex="-1">The dialog doesn't appear though I'm sending a properly formatted message. What's going wrong?</h3> <p>There are a couple of caveats when testing the API:</p> <ul> <li>If the sender's phone number is included in the receiver's contact list, this API will not be triggered due to the design of the underlying <a href="https://developers.google.com/identity/sms-retriever/user-consent/request#2_start_listening_for_incoming_messages">SMS User Consent API</a>.</li> <li>If you are using a work profile on your Android device and the WebOTP does not work, try installing and using Chrome on your personal profile instead (i.e. the same profile in which you receive SMS messages).</li> </ul> <p>Check back at <a href="#format">the format</a> to see if your SMS is correctly formatted.</p> <h3 id="is_this_api_compatible_between_different_browsers" data-text="Is this API compatible between different browsers?" tabindex="-1">Is this API compatible between different browsers?</h3> <p>Chromium and WebKit agreed on <a href="https://wicg.github.io/sms-one-time-codes">the SMS text message format</a> and <a href="https://developer.apple.com/news/?id=z0i801mg">Apple announced Safari's support for it</a> starting in iOS 14 and macOS Big Sur. Though Safari doesn't support the WebOTP JavaScript API, by annotating <code translate="no" dir="ltr">input</code> element with <code translate="no" dir="ltr">autocomplete=["one-time-code"]</code>, the default keyboard automatically suggests that you enter the OTP if the SMS message complies with the format.</p> <h3 id="is_it_safe_to_use_sms_as_a_way_to_authenticate" data-text="Is it safe to use SMS as a way to authenticate?" tabindex="-1">Is it safe to use SMS as a way to authenticate?</h3> <p>While SMS OTP is useful to verify a phone number when the number is first provided, phone number verification via SMS must be used carefully for re-authentication since phone numbers can be hijacked and recycled by carriers. WebOTP is a convenient re-auth and recovery mechanism, but services should combine it with additional factors, such as a knowledge challenge, or use the <a href="https://developer.mozilla.org/docs/Web/API/Web_Authentication_API">Web Authentication API</a> for strong authentication.</p> <h3 id="where_do_i_report_bugs_in_chromes_implementation" data-text="Where do I report bugs in Chrome's implementation?" tabindex="-1">Where do I report bugs in Chrome's implementation?</h3> <p>Did you find a bug with Chrome's implementation?</p> <ul> <li>File a bug at <a href="https://issues.chromium.org/issues/new">crbug.com</a>. Include as much detail as you can, simple instructions for reproducing, and set <strong>Components</strong> to <code translate="no" dir="ltr">Blink>WebOTP</code>.</li> </ul> <h3 id="how_can_i_help_this_feature" data-text="How can I help this feature?" tabindex="-1">How can I help this feature?</h3> <p>Are you planning to use the WebOTP API? Your public support helps us prioritize features, and shows other browser vendors how critical it is to support them. Send a tweet to <a href="https://twitter.com/chromiumdev">@ChromiumDev</a> using the hashtag <a href="https://twitter.com/search?q=%23WebOTP&src=typed_query&f=live"><code translate="no" dir="ltr">#WebOTP</code></a> and let us know where and how you're using it.</p> <aside class="note"><b>Note:</b> Find more questions at <a href="https://github.com/WICG/WebOTP/blob/master/FAQ.md">the FAQ section in the explainer</a>.</aside> <h2 id="resources" data-text="Resources" tabindex="-1">Resources</h2> <ul> <li><a href="https://web.dev/articles/sms-otp-form">SMS OTP form best practices</a></li> <li><a href="/blog/cross-device-webotp">Verify a phone number on desktop using WebOTP API</a></li> <li><a href="https://web.dev/articles/web-otp-iframe">Fill OTP forms within cross-origin iframes with WebOTP API</a></li> <li><a href="https://web.dev/case-studies/yahoo-japan-identity">Yahoo! JAPAN's password-free authentication reduced inquiries by 25%, sped up sign-in time by 2.6x</a></li> </ul> </div> <devsite-thumb-rating position="footer"> </devsite-thumb-rating> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> <p>Last updated 2019-10-07 UTC.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2019-10-07 UTC."],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Contribute</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues/new?component=1400036&template=1897236" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > File a bug </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues?q=status:open%20componentid:1400036&s=created_time:desc" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > See open issues </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Related content</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://blog.chromium.org/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Chromium updates </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/case-studies" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Case studies </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/deprecated" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Archive </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://web.dev/shows" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Podcasts & shows </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Follow</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://twitter.com/ChromiumDev" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > @ChromiumDev on X </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.youtube.com/user/ChromeDevelopers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > YouTube </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.linkedin.com/showcase/chrome-for-developers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Chrome for Developers on LinkedIn </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/static/blog/feed.xml" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > RSS </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/terms" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="nl" >Nederlands</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{"at": "True", "ga4": [], "ga4p": [], "gtm": [{"id": "GTM-5QF3RT2", "purpose": 0}], "parameters": {"internalUser": "False", "language": {"machineTranslated": "False", "requested": "en", "served": "en"}, "pageType": "article", "projectName": "Identity", "signedIn": "False", "tenant": "chrome", "recommendations": {"sourcePage": "", "sourceType": 0, "sourceRank": 0, "sourceIdenticalDescriptions": 0, "sourceTitleWords": 0, "sourceDescriptionWords": 0, "experiment": ""}, "experiment": {"ids": ""}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <script nonce="2RXDxugr/BcjtkekBxHd46/V4wYp8L"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/js/app_loader.js', '[53,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome","https://chrome-dot-devsite-v2-prod-3p.appspot.com",1,null,["/_pwa/chrome/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/favicon.png","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,116,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyCNm9YxQumEXwGJgTDjxoxXK6m1F-9720Q","AIzaSyCc76DZePGtoyUjqKrLdsMGk_ry7sljLbY","developer.chrome.com","AIzaSyB9bqgQ2t11WJsOX8qNsCQ6U-w91mmqF-I","AIzaSyAdYnStPdzjcJJtQ0mvIaeaMKj7_t6J_Fg",null,null,null,["Cloud__enable_legacy_calculator_redirect","Cloud__enable_llm_concierge_chat","Profiles__enable_awarding_url","MiscFeatureFlags__developers_footer_dark_image","Search__enable_page_map","Analytics__enable_clearcut_logging","Profiles__enable_page_saving","CloudShell__cloud_shell_button","Cloud__enable_cloud_shell_fte_user_flow","Profiles__enable_complete_playlist_endpoint","CloudShell__cloud_code_overflow_menu","Cloud__enable_cloud_shell","Cloud__enable_cloud_dlp_service","Search__enable_ai_eligibility_checks","Cloud__enable_cloudx_experiment_ids","Profiles__enable_release_notes_notifications","MiscFeatureFlags__enable_firebase_utm","DevPro__enable_developer_subscriptions","Cloud__enable_free_trial_server_call","Profiles__enable_public_developer_profiles","MiscFeatureFlags__enable_project_variables","MiscFeatureFlags__emergency_css","Experiments__reqs_query_experiments","BookNav__enable_tenant_cache_key","Profiles__enable_profile_collections","Cloud__enable_cloud_facet_chat","Profiles__enable_developer_profiles_callout","Profiles__require_profile_eligibility_for_signin","DevPro__enable_cloud_innovators_plus","OnSwitch__enable","Profiles__enable_recognition_badges","MiscFeatureFlags__enable_variable_operator","TpcFeatures__enable_mirror_tenant_redirects","MiscFeatureFlags__enable_view_transitions","Profiles__enable_completecodelab_endpoint","TpcFeatures__enable_required_headers","EngEduTelemetry__enable_engedu_telemetry","MiscFeatureFlags__developers_footer_image","Search__enable_suggestions_from_borg","Profiles__enable_dashboard_curated_recommendations","Cloud__enable_cloudx_ping","Search__enable_dynamic_content_confidential_banner","Concierge__enable_pushui","MiscFeatureFlags__enable_explain_this_code"],null,null,"AIzaSyA58TaKli1DculwmAmbpzLVGuWc8eCQgQc","https://developerscontentserving-pa.googleapis.com","AIzaSyDWBU60w0P9hEkr29kkksYs8Z7gvZ8u_wc","https://developerscontentsearch-pa.googleapis.com",2,4,null,"https://developerprofiles-pa.googleapis.com",[53,"chrome","Chrome for Developers","developer.chrome.com",null,"chrome-dot-devsite-v2-prod-3p.appspot.com",null,null,[null,null,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],null,null,null,null,[1,null,1],[1,1,null,1,1]],null,[69,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,1,1,null,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup-dark-theme.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[],[1,1]],[[null,null,null,null,null,["GTM-5QF3RT2"],null,null,null,null,null,[["GTM-5QF3RT2",1]],1]],null,4]]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>