TSGGLOBAL Support sign in
Skip to page content
Browse TNID API docs

TNID API documentation User Authentication

User Authentication

On this page

Request a one-time code by phone number or email, then exchange it at /auth/token for a user access token.

Learn how to get a TNID user access token to authenticate into the /user GraphQL API.

Users of TNID (as opposed to Companies) authenticate with a one-time code (OTP) delivered to their telephone number or email address.

Access tokens are valid for 7 days and refresh tokens for 30 days (see Refresh Token). There are no passwords to rotate; if a token is compromised, stop using it and request a new OTP.

Generate Your Access Token

The OTP endpoint is available in each environment:

Environment OTP endpoint
Staging https://api.staging.v2.tnid.com/auth/create-user-otp
Zero (pre-production) https://api.zero.v2.tnid.com/auth/create-user-otp

The path is also accepted spelled /auth/create_user_otp.

Step 1. Make a request to /auth/create-user-otp with the telephone_number or email of an existing user. To create a new user, include the optional profile fields:

{
   "telephone_number": "13024343433",
   "first_name": "John",
   "last_name": "Doe",
   "email": "email@address.com"
}

The response tells you when the code expires and how many attempts remain:

{
  "expires_at": "2026-01-15T09:00:01.000000Z",
  "next_otp_at": "2026-01-15T09:00:00",
  "otp_status": "OTP sent",
  "remaining_otp_attempts": 5
}

Step 2. Make a request to /auth/token with the same telephone_number (or email) and the received otp_code:

{
   "telephone_number": "13024343433",
   "otp_code": "698125"
}

The response contains an access_token and a refresh_token. Use the access_token as Authorization: Bearer <access_token> to interact with the GraphQL API at /user.

Example Code

Python

import requests

BASE = "https://api.staging.v2.tnid.com"
HEADERS = {"Content-Type": "application/x-www-form-urlencoded"}

# Step one: request an OTP for an existing user. The user receives the code by SMS (or email if you pass "email").
def request_otp(user_phone_number):
    response = requests.post(f"{BASE}/auth/create-user-otp", headers=HEADERS,
                             data={"telephone_number": user_phone_number})
    if response.status_code != 200:
        raise Exception(f"Failed to request OTP: {response.status_code} {response.text}")
    print(f"OTP requested: {response.text}")

# Step two: exchange the OTP for tokens.
def get_bearer_token(user_phone_number, otp):
    response = requests.post(f"{BASE}/auth/token", headers=HEADERS,
                             data={"telephone_number": user_phone_number, "otp_code": otp})
    if response.status_code != 200:
        raise Exception(f"Failed to retrieve token: {response.status_code} {response.text}")
    return response.json().get("access_token")

# Creating a new user: same endpoint, with profile fields. Then request the OTP and token as above.
def create_new_user(phone_number, first_name, last_name, email):
    response = requests.post(f"{BASE}/auth/create-user-otp", headers=HEADERS,
                             data={"telephone_number": phone_number, "first_name": first_name,
                                   "last_name": last_name, "email": email})
    if response.status_code != 200:
        raise Exception(f"Failed to create new user: {response.status_code} {response.text}")
    print(f"User created: {response.text}")

phone = "14075554530"
request_otp(phone)
otp = input("Enter the OTP you received: ")
print("Bearer Token:", get_bearer_token(phone, otp))

curl

curl -X POST https://api.staging.v2.tnid.com/auth/create-user-otp \
  -H "Content-Type: application/json" \
  -d '{"telephone_number":"14075554530"}'

curl -X POST https://api.staging.v2.tnid.com/auth/token \
  -H "Content-Type: application/json" \
  -d '{"telephone_number":"14075554530","otp_code":"698125"}'