Bootstrap the mobile app session
curl --request GET \
--url https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch \
--header 'x-device-id: <x-device-id>' \
--header 'x-platform: <x-platform>'import requests
url = "https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch"
headers = {
"x-device-id": "<x-device-id>",
"x-platform": "<x-platform>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-device-id': '<x-device-id>', 'x-platform': '<x-platform>'}
};
fetch('https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch', 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://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-device-id: <x-device-id>",
"x-platform: <x-platform>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-device-id", "<x-device-id>")
req.Header.Add("x-platform", "<x-platform>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch")
.header("x-device-id", "<x-device-id>")
.header("x-platform", "<x-platform>")
.asString();require 'uri'
require 'net/http'
url = URI("https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-device-id"] = '<x-device-id>'
request["x-platform"] = '<x-platform>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"appLaunchResponseData": {
"userData": {
"userId": "<string>",
"name": "<string>",
"deviceId": "<string>",
"platform": "android",
"authProvider": "<string>",
"isLoggedIn": true,
"isVerified": true,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"email": "jsmith@example.com",
"phoneNumber": "<string>",
"avatarUrl": "<string>",
"accessTokenExpiry": "2023-11-07T05:31:56Z"
},
"auth": {
"sessionExists": true,
"refreshAllowed": true,
"graceWindowSeconds": 123
},
"isOnboardingRequired": true,
"freeThreshold": {
"total": 123,
"used": 123,
"remaining": 123,
"percentUsed": 50
},
"socialMediaUrls": {
"facebook": "https://www.facebook.com/handauncle",
"instagram": "https://www.instagram.com/handauncle",
"linkedin": "https://www.linkedin.com/company/handauncle",
"twitter": "https://twitter.com/handauncle"
},
"systemUrls": {
"termsAndConditions": "https://www.handauncle.com/terms",
"privacyPolicy": "https://www.handauncle.com/privacy",
"faqs": "https://www.handauncle.com/faqs",
"supportEmail": "hello@handauncle.com"
}
}
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>"
}
}{
"success": false,
"error": {
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)",
"code": "VALIDATION_ERROR",
"details": [
{
"field": "phone",
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)"
}
]
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>"
}
}{
"success": false,
"error": {
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)",
"code": "VALIDATION_ERROR",
"details": [
{
"field": "phone",
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)"
}
]
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>"
}
}Mobile app
App Launch
Resolves the caller to a user (if possible), updates device metadata, and returns onboarding, usage, auth state, and link information required to render the home screen. Supports optional Authorization header to return token expiry info and validate device-user mapping for silent refresh flows.
GET
/
app
/
launch
Bootstrap the mobile app session
curl --request GET \
--url https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch \
--header 'x-device-id: <x-device-id>' \
--header 'x-platform: <x-platform>'import requests
url = "https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch"
headers = {
"x-device-id": "<x-device-id>",
"x-platform": "<x-platform>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {'x-device-id': '<x-device-id>', 'x-platform': '<x-platform>'}
};
fetch('https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch', 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://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-device-id: <x-device-id>",
"x-platform: <x-platform>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-device-id", "<x-device-id>")
req.Header.Add("x-platform", "<x-platform>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch")
.header("x-device-id", "<x-device-id>")
.header("x-platform", "<x-platform>")
.asString();require 'uri'
require 'net/http'
url = URI("https://handauncle-backend-prod-205012263523.asia-south1.run.app/app/launch")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-device-id"] = '<x-device-id>'
request["x-platform"] = '<x-platform>'
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"appLaunchResponseData": {
"userData": {
"userId": "<string>",
"name": "<string>",
"deviceId": "<string>",
"platform": "android",
"authProvider": "<string>",
"isLoggedIn": true,
"isVerified": true,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"email": "jsmith@example.com",
"phoneNumber": "<string>",
"avatarUrl": "<string>",
"accessTokenExpiry": "2023-11-07T05:31:56Z"
},
"auth": {
"sessionExists": true,
"refreshAllowed": true,
"graceWindowSeconds": 123
},
"isOnboardingRequired": true,
"freeThreshold": {
"total": 123,
"used": 123,
"remaining": 123,
"percentUsed": 50
},
"socialMediaUrls": {
"facebook": "https://www.facebook.com/handauncle",
"instagram": "https://www.instagram.com/handauncle",
"linkedin": "https://www.linkedin.com/company/handauncle",
"twitter": "https://twitter.com/handauncle"
},
"systemUrls": {
"termsAndConditions": "https://www.handauncle.com/terms",
"privacyPolicy": "https://www.handauncle.com/privacy",
"faqs": "https://www.handauncle.com/faqs",
"supportEmail": "hello@handauncle.com"
}
}
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>"
}
}{
"success": false,
"error": {
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)",
"code": "VALIDATION_ERROR",
"details": [
{
"field": "phone",
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)"
}
]
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>"
}
}{
"success": false,
"error": {
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)",
"code": "VALIDATION_ERROR",
"details": [
{
"field": "phone",
"message": "Please enter a valid 10-digit phone number (e.g., 9876543210)"
}
]
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"requestId": "<string>"
}
}Use this endpoint whenever the Handa Uncle mobile app boots. The backend will
associate the provided device information with an existing user (if one can be
identified) or create a lightweight record and respond with everything the app
needs to decide whether to show onboarding, what limits apply, and which system
links to surface.
Required headers
x-device-id: Stable device identifier or installation IDx-platform: One ofandroid,ios,web
Optional headers
x-user-id: Known user identifier (Auth0 / Mongo ID)x-user-email: Known email addressx-user-phone: E.164‑formatted phone number
Example request
curl -X GET https://api.handauncle.com/app/launch \
-H 'x-device-id=ios-device-3f92' \
-H 'x-platform=ios' \
-H 'x-user-email=investor@example.com'
Response highlights
data.appLaunchResponseData.userDatamirrors the canonical user profile, including verification, platform, and timestamps.isOnboardingRequiredflips tofalseonce either an email or phone is attached to the user.freeThresholdis derived from theFREE_MESSAGE_THRESHOLDenvironment value and the user’s current message count.socialMediaUrlsandsystemUrlsare dynamically loaded from the database, so no hard-coded URLs are required in clients. Administrators can update these URLs via the configuration endpoints without requiring app updates.
Configuration URLs
ThesocialMediaUrls and systemUrls returned in this response are centrally
managed and can be updated by administrators. For more information:
- Get App Configuration - View current configuration
- Update System URLs - Modify legal/support URLs
- Update Social Media URLs - Modify social media links
Headers
Unique identifier for the physical device or installation.
Minimum string length:
1Platform the client is running on.
Available options:
android, ios, web Known user identifier (Auth0 or Mongo ID) if available.
Known user email address.
Known phone number in E.164 format.
Pattern:
^\+?[1-9]\d{7,14}$Optional Bearer token for authenticated users. When provided, the response includes accessTokenExpiry in userData and validates device-user mapping. This enables silent refresh flows without blocking the UI.
Pattern:
^Bearer .+$