Set up 2FA (start)
curl --request POST \
--url https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup \
--header 'Content-Type: application/json' \
--header 'x-program-id: <x-program-id>' \
--data '
{
"session_token": "3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b"
}
'import requests
url = "https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup"
payload = { "session_token": "3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b" }
headers = {
"x-program-id": "<x-program-id>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-program-id': '<x-program-id>', 'Content-Type': 'application/json'},
body: JSON.stringify({session_token: '3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b'})
};
fetch('https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'session_token' => '3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-program-id: <x-program-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup"
payload := strings.NewReader("{\n \"session_token\": \"3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-program-id", "<x-program-id>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup")
.header("x-program-id", "<x-program-id>")
.header("Content-Type", "application/json")
.body("{\n \"session_token\": \"3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-program-id"] = '<x-program-id>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"session_token\": \"3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"secret": "JBSWY3DPEHPK3PXP",
"qr_uri": "otpauth://totp/Orenda:ada.lovelace@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Orenda"
}
}{
"success": false,
"code": "INVALID_CREDENTIALS",
"message": "<string>",
"retryable": true
}{
"success": false,
"code": "SESSION_EXPIRED",
"message": "Challenge session has expired"
}{
"success": false,
"code": "VALIDATION_ERROR",
"message": "email is required"
}{
"success": false,
"code": "USER_LOCKED",
"message": "Too many failed attempts"
}{
"success": false,
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal Server Error"
}Security setup
Set up 2FA (start)
Get a secret and QR code during security setup.
POST
/
v1
/
auth
/
security-setup
/
mfa
/
setup
Set up 2FA (start)
curl --request POST \
--url https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup \
--header 'Content-Type: application/json' \
--header 'x-program-id: <x-program-id>' \
--data '
{
"session_token": "3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b"
}
'import requests
url = "https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup"
payload = { "session_token": "3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b" }
headers = {
"x-program-id": "<x-program-id>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-program-id': '<x-program-id>', 'Content-Type': 'application/json'},
body: JSON.stringify({session_token: '3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b'})
};
fetch('https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'session_token' => '3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-program-id: <x-program-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup"
payload := strings.NewReader("{\n \"session_token\": \"3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-program-id", "<x-program-id>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup")
.header("x-program-id", "<x-program-id>")
.header("Content-Type", "application/json")
.body("{\n \"session_token\": \"3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.next.orenda.finance/v1/auth/security-setup/mfa/setup")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-program-id"] = '<x-program-id>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"session_token\": \"3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"secret": "JBSWY3DPEHPK3PXP",
"qr_uri": "otpauth://totp/Orenda:ada.lovelace@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Orenda"
}
}{
"success": false,
"code": "INVALID_CREDENTIALS",
"message": "<string>",
"retryable": true
}{
"success": false,
"code": "SESSION_EXPIRED",
"message": "Challenge session has expired"
}{
"success": false,
"code": "VALIDATION_ERROR",
"message": "email is required"
}{
"success": false,
"code": "USER_LOCKED",
"message": "Too many failed attempts"
}{
"success": false,
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal Server Error"
}Step 1 of the 2FA path during first-time security setup. (To add 2FA to an
already-signed-in user later, see Start 2FA setup.) Send the
session_token from the SECURITY_SETUP_REQUIRED challenge. You get back a secret and an otpauth:// qr_uri — render the QR code so the
user can add it to their authenticator app. No bearer token needed.
Then confirm with the first code the app shows.Headers
Identifies the program. Can also be sent as the programId query parameter.
Body
application/json
From the SECURITY_SETUP_REQUIRED challenge.
Example:
"3f1c2e8a-9b4d-4e6f-8a1b-2c3d4e5f6a7b"
⌘I