cURL
curl --request POST \
--url https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup \
--header 'Authorization: Bearer <token>'import Foundation
// Step 1: returns otpauth:// URL + shared secret — render as QR code.
var request = URLRequest(url: URL(string: "https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup")!)
request.httpMethod = "POST"
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, _) = try await URLSession.shared.data(for: request)
// Step 2: POST /mfa/verify with {"code": "<6-digit TOTP>"} to confirm.
struct MFASetup: Decodable { let otpauthURL: String }
let setup = try JSONDecoder().decode(MFASetup.self, from: data)
print(setup.otpauthURL)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"otpauth_url": "otpauth://totp/TKTChurch:amina?secret=JBSWY3DPEHPK3PXP&issuer=TKTChurch"
}{
"error": "invalid_request",
"error_description": "Redirect URI not registered for this client"
}{
"error": "invalid_token",
"error_description": "Access token is invalid or malformed"
}Start TOTP setup
Returns otpauth URL + shared secret — render as a QR code, then confirm via verify.
POST
/
api
/
v1
/
users
/
me
/
mfa
/
setup
cURL
curl --request POST \
--url https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup \
--header 'Authorization: Bearer <token>'import Foundation
// Step 1: returns otpauth:// URL + shared secret — render as QR code.
var request = URLRequest(url: URL(string: "https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup")!)
request.httpMethod = "POST"
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let (data, _) = try await URLSession.shared.data(for: request)
// Step 2: POST /mfa/verify with {"code": "<6-digit TOTP>"} to confirm.
struct MFASetup: Decodable { let otpauthURL: String }
let setup = try JSONDecoder().decode(MFASetup.self, from: data)
print(setup.otpauthURL)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://prod-auth.tktchurch.com/api/v1/users/me/mfa/setup"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"otpauth_url": "otpauth://totp/TKTChurch:amina?secret=JBSWY3DPEHPK3PXP&issuer=TKTChurch"
}{
"error": "invalid_request",
"error_description": "Redirect URI not registered for this client"
}{
"error": "invalid_token",
"error_description": "Access token is invalid or malformed"
}