Quick reference for API endpoints and usage patterns.
- Quick Start
- Common Use Cases
- Essential Endpoints
- Mobile Integration
- TS43/SIM Integration
- Configuration API
- Error Handling
- Advanced Details
Base URL: http://localhost:3000 (development)
Most Common Flow:
- User clicks button → Redirects to
/auth/start - User authenticates → IPification redirects to
/auth/callback - App redirects to
/user/info→ Shows user data
Authentication: Session-based (handled automatically)
→ Use /auth/start → user authenticates → handle /auth/callback
→ Use /auth/mobile/login with authorization code
→ Use /ts43/auth → /ts43/token flow (see TS43 Guide)
→ Use /sms/auth → user enters OTP → /sms/token flow (see SMS Flow Guide)
→ Call /api/config to get auth_servers, clients, etc.
GET /auth/start?user_flow=pvn_ip&server_id=stage&state=abc123
Starts OAuth flow and redirects user to IPification.
Required:
user_flow: Which flow to use (pvn_ip,login_ip, etc.)state: Random string for security
Optional:
server_id: Which auth server (stage,live). Defaults to first serverphone: Pre-fill phone number
GET /auth/callback/:userFlow/:serverId?
IPification redirects here after authentication. Your app handles this automatically.
Example: /auth/callback/pvn_ip/stage?code=xyz&state=abc
GET /user/info
Shows authenticated user information (requires valid session).
Exchange authorization code for user info (for mobile apps).
Request:
{
"client_id": "your_client_id",
"code": "auth_code",
"redirect_uri": "your_callback_url",
"server_id": "stage"
}Response: User information JSON
For SIM-based verification, see dedicated TS43 Guide.
Quick overview:
- POST
/ts43/auth→ get digital_request - Call Credential Manager
- POST
/ts43/token→ get user info
Get application configuration (auth servers, clients, etc.)
Response:
{
"auth_servers": [
{"id": "stage", "url": "https://..."}
],
"realm": "ipification",
"clients": [...]
}Common Errors:
| Error | Cause | Solution |
|---|---|---|
Invalid server_id |
Server not in config | Check auth_servers in config |
Client not found |
Invalid user_flow | Check clients array in config |
server_id not found in session |
Session expired | User needs to restart auth flow |
Click to expand detailed endpoint specifications
GET /auth/login
Display the login page with available authentication options.
Response: HTML page (Pug template)
Query Parameters: None
GET /auth/start
Initiates the OAuth2/OIDC authentication flow by redirecting to IPification authorization server.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
user_flow |
string | Yes | User flow identifier (e.g., pvn_ip, login_ip) |
server_id |
string | No | Auth server ID (e.g., stage, live). Defaults to first server |
phone |
string | No | Phone number in E.164 format (e.g., +1234567890) |
state |
string | Yes | State parameter for OAuth flow (used for CSRF protection) |
Example Request:
GET /auth/start?user_flow=pvn_ip&server_id=stage&phone=+1234567890&state=abc123xyz
Response: HTTP 302 Redirect to IPification authorization server
Flow:
- Validates
server_idand resolves to auth server URL (defaults to first server if not provided) - Validates user flow exists in configuration
- Validates state parameter
- Builds authorization URL with OAuth2 parameters
- Redirects user to IPification authorization server
Callback URL Format:
The redirect_uri sent to auth server will be: /auth/callback/{user_flow}/{server_id}
Error Responses:
| Status Code | Error Message | Cause |
|---|---|---|
| 400 | Invalid server_id: 'xyz' |
Server ID not found in config |
| 400 | No auth servers configured |
auth_servers array is empty |
GET /auth/callback/:userFlow/:serverId?
Handles the OAuth2 callback after user authentication.
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
userFlow |
string | Yes | User flow identifier (e.g., pvn_ip, login_ip) |
serverId |
string | No | Auth server ID (e.g., stage, live). Defaults to first server |
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Authorization code from IPification |
state |
string | Yes | State parameter (must match original) |
error |
string | No | Error code if authentication failed |
error_description |
string | No | Error description |
Example Requests:
GET /auth/callback/pvn_ip/stage?code=abc123&state=xyz789
GET /auth/callback/login_ip?code=abc123&state=xyz789
(Uses default/first server when serverId not in URL)
Response:
- Success: HTTP 302 Redirect to
/auth/complete?state=xyz789 - QR Code Flow: HTTP 302 Redirect to
/auth/qrcode/completeor/auth/qrcode/error - Backchannel Flow: HTTP 200 (empty body)
- Error: HTTP 302 Redirect to
/auth/loginwith error message
Flow:
- Extracts
serverIdfrom URL path (or defaults to first server) - Resolves auth server URL from
serverId - Validates authorization code and state
- Exchanges authorization code for access token (using same auth server)
- Retrieves user information using access token
- Stores user information in data store
- For QR code flows, emits Socket.io event to desktop browser
- Redirects to completion endpoint
Headers:
ip-backchannel-im-auth: Set totruefor server-to-server IM flows
Error Responses:
| Status Code | Error Message | Cause |
|---|---|---|
| 400 | Invalid server_id: 'xyz' |
Server ID not found in config |
| 400 | No auth servers configured |
auth_servers array is empty |
GET /auth/complete
Completes the authentication flow and retrieves stored user information.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
state |
string | Yes | State parameter |
Example Request:
GET /auth/complete?state=xyz789
Response: HTTP 302 Redirect to /user/info
Flow:
- Retrieves user information from data store using state
- Polls data store (up to 5 attempts with 1-second delay)
- Sets session variables (
isAuthenticated,userData) - Redirects to user info page
GET /auth/qrcode/complete
Displays success page after QR code authentication.
Response: HTML page (Pug template)
GET /auth/qrcode/error
Displays error page if QR code authentication failed.
Response: HTML page (Pug template)
POST /auth/mobile/login
Mobile-specific endpoint for exchanging authorization code for user information.
Request Headers:
Content-Type: application/json
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
client_id |
string | Yes | OAuth client ID |
code |
string | Yes | Authorization code |
redirect_uri |
string | Yes | Callback URL (must match OAuth redirect) |
server_id |
string | No | Auth server ID (e.g., stage, live). Defaults to first server |
Example Request:
{
"client_id": "webclient2",
"code": "authorization-code",
"redirect_uri": "https://example.com/auth/callback/pvn_ip/stage",
"server_id": "stage"
}Response:
{
"sub": "user-id",
"phone_number": "+1234567890",
"phone_number_verified": "true"
}Status Codes:
200: Success - Returns user information400: Invalid server_id or missing required fields401: Client not found or authentication failed
POST /auth/s2s/signin
Server-to-server sign-in endpoint for retrieving user information.
Request Body:
{
"state": "state-parameter"
}Response:
{
"sub": "user-id",
"phone_number": "+1234567890",
...
}Status Codes:
200: Success401: User information not found
POST /ts43/auth
Initiates TS43 (SIM-based) authentication flow using CIBA (Client Initiated Backchannel Authentication).
Request Body:
{
"login_hint": "+1234567890",
"carrier_hint": "carrier-code",
"client_id": "webclient3",
"operation": "VerifyPhoneNumber",
"scope": "openid"
}Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
login_hint |
string | No | Phone number hint |
carrier_hint |
string | No | Carrier code hint |
client_id |
string | Yes | Client identifier |
operation |
string | No | Operation type (VerifyPhoneNumber or GetPhoneNumber) |
scope |
string | No | OAuth2 scope (defaults to client scope) |
Response:
{
"auth_req_id": "auth-request-id",
"nonce": "nonce-value",
"digital_request": {
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "nonce-value",
"dcql_query": {
"credentials": [...]
}
}
}
}Status Codes:
200: Success401: Client not found500: Server error
Flow:
- Validates client configuration
- Calls CIBA auth endpoint to get
auth_req_id - Calls DCQL endpoint to get credential query
- Returns digital request structure for mobile app
POST /ts43/token
Exchanges VP token for access token in TS43 flow.
Request Body:
{
"vp_token": "vp-token-value",
"auth_req_id": "auth-request-id",
"client_id": "webclient3",
"nonce": "nonce-value"
}Response:
{
"sub": "user-id",
"phone_number": "+1234567890",
...
}Status Codes:
200: Success401: Client not found500: Server error
Flow:
- Validates client configuration
- Calls callback endpoint with VP token
- Exchanges auth_req_id for access token using CIBA grant type
- Retrieves user information
- Sets session and returns user info
POST /ts43/log
Logging endpoint for TS43 debugging.
Request Body:
{
"data": {...}
}Response: "OK"
See SMS Flow Guide for full documentation.
Starts CIBA with SMS channel. Auth server sends OTP to the given phone.
Request Body: client_id, server_id (optional), login_hint (phone), scope (optional)
Response: auth_server, auth_req_id, nonce
Submits user-entered OTP to auth server callback, then exchanges for token and user info.
Request Body: code (OTP), auth_req_id, client_id, nonce, server_id (optional)
Response: User info (e.g. sub, phone_number, phone_number_verified) and auth_server
Optional logging for SMS flow debugging. Request Body: { "data": {...} }. Response: "OK"
GET /api/config
Returns safe application configuration for the frontend (client secrets are removed).
Response:
{
"realm": "ipification",
"auth_servers": [
{
"id": "stage",
"url": "https://api.stage.ipification.com/auth"
}
],
"clients": [
{
"user_flow": "pvn_ip",
"client_id": "your-client-id",
"title": "IP Phone Number Verification",
"scope": "openid ip:phone_verify"
}
]
}Flow:
- Reads config from
res.locals - Strips
client_secretfrom each client entry - Returns
auth_servers,realm, and safeclients
GET /api/geoip
Returns country code based on client IP address.
Response:
{
"country": "us",
"ip": "192.168.1.1"
}Flow:
- Extracts client IP from request
- Performs GeoIP lookup
- Returns country code (lowercase) and IP address
GET /user/info
Displays authenticated user information (requires valid session).
Response: HTML page (Pug template)
Session Requirements:
isAuthenticated: Must betrueuserData: User data object
Status Codes:
200: Success (renders info page)302: Redirects to/if not authenticated
Event: init
Payload:
{
"state": "state-parameter"
}Description: Joins client to a room channel for receiving authentication updates.
Channel Format: auth:{state}
Event: messages
Payload:
{
"event_name": "connected",
"socket_id": "socket-id"
}Description: Sent immediately after client connects.
Event: messages
Payload:
{
"event_name": "url",
"url": "http://example.com/auth/complete?state=xyz789"
}Description: Sent when QR code authentication completes. Desktop browser should navigate to the provided URL.
All endpoints follow standard HTTP status codes:
200: Success302: Redirect400: Bad Request (invalid parameters)401: Unauthorized (authentication failed)404: Not Found500: Internal Server Error
For JSON responses:
{
"error": "Error message",
"status": 400
}For HTML responses, errors are displayed in modals or redirect to login page with error message in session.
Currently, no rate limiting is implemented. Consider implementing rate limiting for production deployments.
- State Parameter: Always validate state parameter to prevent CSRF attacks
- Secret Keys: Keep notification secret keys secure
- HTTPS: Use HTTPS in production
- Session Security: Configure secure session cookies
- Input Validation: Validate all input parameters
# 1. Start authentication
curl "http://localhost:3000/auth/start?user_flow=pvn_ip&state=abc123"
# 2. After user completes authentication, callback is called automatically
# 3. Complete authentication
curl "http://localhost:3000/auth/complete?state=abc123"
# 4. View user info (requires session cookie)
curl -b cookies.txt "http://localhost:3000/user/info"# Exchange authorization code for user info
curl -X POST http://localhost:3000/auth/mobile/login \
-H "Content-Type: application/json" \
-d '{
"client_id": "webclient2",
"code": "authorization-code",
"redirect_uri": "https://example.com/callback"
}'# 1. Initiate TS43 authentication
curl -X POST http://localhost:3000/ts43/auth \
-H "Content-Type: application/json" \
-d '{
"login_hint": "+1234567890",
"client_id": "webclient3",
"operation": "VerifyPhoneNumber"
}'
# 2. Exchange VP token (after mobile app completes)
curl -X POST http://localhost:3000/ts43/token \
-H "Content-Type: application/json" \
-d '{
"vp_token": "vp-token",
"auth_req_id": "auth-req-id",
"client_id": "webclient3",
"nonce": "nonce-value"
}'