Authentication
Secure your API access with JWT Bearer tokens, OAuth2 social login, passkeys, magic links, and two-factor authentication. Complete guide to the OrbNET authentication flow.
Authentication
Secure every API request with industry-standard authentication. OrbNET supports JWT Bearer tokens, OAuth2 social login, passkeys, magic links, two-factor authentication, and API keys -- giving you flexible, production-grade security for any integration.
Authentication Methods Overview
OrbNET provides multiple authentication strategies. Choose the one that fits your application architecture and security requirements.
JWT Bearer Tokens
The primary authentication method. Exchange email and password for an access token and refresh token pair. Access tokens expire after 24 hours and can be renewed silently with the refresh token.
OAuth2 Social Login
Let users authenticate with their existing Google or Apple accounts. Token exchange returns the same JWT pair, providing a seamless sign-in experience without password management.
Passkeys / WebAuthn
Passwordless authentication using FIDO2 hardware keys or platform biometrics. The most secure option, resistant to phishing and credential stuffing attacks.
Magic Links
Send a one-time login link to the user's email. No password required. Ideal for low-friction onboarding and infrequent access patterns.
Two-Factor Authentication
Add a second layer of security with TOTP codes from apps like Google Authenticator or Authy. Can be combined with any primary authentication method.
API Key Authentication
Static API keys for server-to-server integrations with OrbGuard Labs. Generated from the dashboard, passed via the X-API-Key header.
Authentication Flow
Follow these steps to authenticate and make your first protected API request.
Obtain Credentials
Register a new account or use existing credentials. You can sign up with email and password, or use OAuth2 social login for a faster path.
Authenticate
Call the login endpoint with your credentials. The server returns a JWT access token and a refresh token.
Include Token in Requests
Pass the access token in the Authorization header as a Bearer token on every protected API request.
Refresh When Expired
When the access token expires after 24 hours, use the refresh token to obtain a new token pair without re-authenticating.
JWT Bearer Token Authentication
The primary authentication method for all OrbNET API requests. Exchange user credentials for a JWT access token and refresh token.
Login
/api/v1/auth/loginAuthenticate with email and password to receive JWT access and refresh tokens.
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Required | The user's registered email address. |
password | string | Required | The user's password. Minimum 8 characters. |
curl -X POST https://api.orbai.world/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "your_password"
}'{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2...",
"expiresAt": "2026-02-08T12:00:00Z",
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"role": "user"
}
}
}{
"success": false,
"error": {
"code": "INVALID_CREDENTIALS",
"message": "The email or password you entered is incorrect."
}
}{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Too many login attempts. Please try again later.",
"details": {
"retryAfter": 300
}
}
}Using the Access Token
Once authenticated, include the JWT access token in the Authorization header of every protected request.
curl https://api.orbai.world/api/v1/users/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."Token Security
Never expose your access tokens in client-side code, URLs, or version control. Store tokens in HTTP-only cookies, secure local storage, or your platform's keychain. Tokens passed in URLs or query parameters will be rejected.
Refreshing Tokens
Access tokens expire after 24 hours. Use the refresh token to obtain a new access token without requiring the user to re-enter credentials.
/api/v1/auth/refreshExchange a valid refresh token for a new access token and refresh token pair.
| Parameter | Type | Required | Description |
|---|---|---|---|
refreshToken | string | Required | The refresh token received from the login or previous refresh response. |
curl -X POST https://api.orbai.world/api/v1/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2..."
}'{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...(new)",
"refreshToken": "dGhpcyBpcyBhIG5ldyBy...(new)",
"expiresAt": "2026-02-09T12:00:00Z",
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"role": "user"
}
}
}{
"success": false,
"error": {
"code": "INVALID_REFRESH_TOKEN",
"message": "The refresh token is expired or has been revoked. Please log in again."
}
}Refresh Token Rotation
Each call to the refresh endpoint returns a new refresh token and invalidates the previous one. This is called refresh token rotation and prevents token replay attacks. Always store and use the latest refresh token.
Logout
Invalidate the current session and revoke the refresh token.
/api/v1/auth/logoutInvalidate the current access and refresh tokens, ending the user session.
| Parameter | Type | Required | Description |
|---|---|---|---|
refreshToken | string | Required | The refresh token to revoke. |
curl -X POST https://api.orbai.world/api/v1/auth/logout \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2..."
}'{
"success": true,
"data": {
"message": "Successfully logged out."
}
}User Registration
Create a new OrbVPN account with email and password. New accounts require email verification before full API access is granted.
/api/v1/auth/registerRegister a new user account with email, password, and display name.
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Required | A valid email address. Must not already be registered. |
password | string | Required | Password with minimum 8 characters, including uppercase, lowercase, and a number. |
name | string | Required | The user's display name. |
curl -X POST https://api.orbai.world/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"password": "SecureP@ss123",
"name": "Jane Doe"
}'{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2...",
"expiresAt": "2026-02-08T12:00:00Z",
"user": {
"id": "usr_def456",
"email": "newuser@example.com",
"role": "user"
},
"emailVerificationRequired": true
}
}{
"success": false,
"error": {
"code": "EMAIL_EXISTS",
"message": "An account with this email address already exists."
}
}Email Verification
After registration, a verification email is sent automatically. The user must click the verification link or enter the code to activate their account. Some protected endpoints may return limited data until verification is complete.
OAuth2 Social Login
Allow users to authenticate with their existing Google or Apple accounts. The client obtains an OAuth token from the identity provider, then exchanges it with OrbNET for a JWT token pair.
Google OAuth
/api/v1/auth/oauth/googleAuthenticate using a Google OAuth2 ID token.
| Parameter | Type | Required | Description |
|---|---|---|---|
idToken | string | Required | The Google ID token obtained from Google Sign-In on the client. |
curl -X POST https://api.orbai.world/api/v1/auth/oauth/google \
-H "Content-Type: application/json" \
-d '{
"idToken": "eyJhbGciOiJSUzI1NiIs...(Google ID token)"
}'{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2...",
"expiresAt": "2026-02-08T12:00:00Z",
"user": {
"id": "usr_ggl789",
"email": "user@gmail.com",
"role": "user"
},
"isNewUser": false
}
}Apple OAuth
/api/v1/auth/oauth/appleAuthenticate using an Apple Sign-In authorization code.
| Parameter | Type | Required | Description |
|---|---|---|---|
authorizationCode | string | Required | The authorization code from Apple Sign-In. |
identityToken | string | Required | The identity token from Apple Sign-In. |
name | string | Optional | The user's full name (only provided on first sign-in with Apple). |
curl -X POST https://api.orbai.world/api/v1/auth/oauth/apple \
-H "Content-Type: application/json" \
-d '{
"authorizationCode": "c1a2b3d4e5f6...",
"identityToken": "eyJhbGciOiJSUzI1NiIs...",
"name": "Jane Doe"
}'{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2...",
"expiresAt": "2026-02-08T12:00:00Z",
"user": {
"id": "usr_apl012",
"email": "user@privaterelay.appleid.com",
"role": "user"
},
"isNewUser": true
}
}OAuth Token Flow
Both Google and Apple OAuth endpoints create a new OrbVPN account on first use (indicated by isNewUser: true) and link subsequent logins to the same account. The returned JWT tokens work identically to those from email/password login.
Passkeys / WebAuthn
Passwordless authentication using the FIDO2/WebAuthn standard. Supports hardware security keys, platform biometrics (Touch ID, Face ID, Windows Hello), and cross-device authentication. The flow requires two round trips: a begin call to get a challenge from the server, followed by a finish call with the signed challenge from the authenticator.
Phishing Resistant
Passkeys are bound to the origin domain and cannot be used on fraudulent sites.
Fast Authentication
One-tap biometric login without typing passwords or waiting for codes.
No Shared Secrets
Private keys never leave the authenticator device. The server only stores public keys.
Register a Passkey
Step 1: Begin Registration
/api/v1/auth/passkeys/register/beginRequest a WebAuthn registration challenge from the server.
curl -X POST https://api.orbai.world/api/v1/auth/passkeys/register/begin \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"success": true,
"data": {
"publicKey": {
"challenge": "dGhpcyBpcyBhIGNoYWxsZW5nZQ...",
"rp": { "name": "OrbVPN", "id": "orbvpn.com" },
"user": {
"id": "dXNyX2FiYzEyMw...",
"name": "user@example.com",
"displayName": "Jane Doe"
},
"pubKeyCredParams": [
{ "type": "public-key", "alg": -7 },
{ "type": "public-key", "alg": -257 }
],
"timeout": 60000,
"attestation": "none",
"authenticatorSelection": {
"residentKey": "preferred",
"userVerification": "preferred"
}
}
}
}Step 2: Finish Registration
/api/v1/auth/passkeys/register/finishComplete passkey registration by submitting the signed credential from the authenticator.
| Parameter | Type | Required | Description |
|---|---|---|---|
credential | object | Required | The PublicKeyCredential object returned by navigator.credentials.create(), serialized to JSON. |
curl -X POST https://api.orbai.world/api/v1/auth/passkeys/register/finish \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"credential": {
"id": "a1b2c3d4e5...",
"rawId": "YTFiMmMzZDRl...",
"type": "public-key",
"response": {
"attestationObject": "o2NmbXRk...",
"clientDataJSON": "eyJ0eXBlI..."
}
}
}'{
"success": true,
"data": {
"credentialId": "a1b2c3d4e5...",
"message": "Passkey registered successfully."
}
}Authenticate with a Passkey
Step 1: Begin Login
/api/v1/auth/passkeys/login/beginRequest a WebAuthn authentication challenge.
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Optional | Optional. The user's email to narrow down credential selection. |
curl -X POST https://api.orbai.world/api/v1/auth/passkeys/login/begin \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'{
"success": true,
"data": {
"publicKey": {
"challenge": "YW5vdGhlciBjaGFsbGVuZ2U...",
"timeout": 60000,
"rpId": "orbvpn.com",
"allowCredentials": [
{
"type": "public-key",
"id": "a1b2c3d4e5..."
}
],
"userVerification": "preferred"
}
}
}Step 2: Finish Login
/api/v1/auth/passkeys/login/finishComplete passkey authentication by submitting the signed assertion.
| Parameter | Type | Required | Description |
|---|---|---|---|
credential | object | Required | The PublicKeyCredential object returned by navigator.credentials.get(), serialized to JSON. |
curl -X POST https://api.orbai.world/api/v1/auth/passkeys/login/finish \
-H "Content-Type: application/json" \
-d '{
"credential": {
"id": "a1b2c3d4e5...",
"rawId": "YTFiMmMzZDRl...",
"type": "public-key",
"response": {
"authenticatorData": "SZYN5YgO...",
"clientDataJSON": "eyJ0eXBlI...",
"signature": "MEUCIQC...",
"userHandle": "dXNyX2FiYzEyMw..."
}
}
}'{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2...",
"expiresAt": "2026-02-08T12:00:00Z",
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"role": "user"
}
}
}Discoverable Credentials
If no email is provided in the begin step, the browser will display all discoverable credentials (resident keys) for the domain. This enables a truly passwordless, username-less experience.
Magic Links
Send a one-time login link to the user's email. Clicking the link authenticates the user and returns JWT tokens. No password required.
Send Magic Link
/api/v1/auth/magic-linkSend a one-time magic login link to the specified email address.
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Required | The email address to send the magic link to. Must be a registered account. |
curl -X POST https://api.orbai.world/api/v1/auth/magic-link \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'{
"success": true,
"data": {
"message": "A magic link has been sent to your email address.",
"expiresIn": 600
}
}Security Notice
Magic links expire after 10 minutes and can only be used once. For security, the API always returns a success response regardless of whether the email is registered, to prevent account enumeration.
Verify Magic Link
When the user clicks the magic link in their email, they are redirected to your application with a token query parameter. Exchange this token for JWT credentials.
/api/v1/auth/magic-link/verifyVerify a magic link token and return JWT credentials.
| Parameter | Type | Required | Description |
|---|---|---|---|
token | string | Required | The one-time token from the magic link URL query parameter. |
curl "https://api.orbai.world/api/v1/auth/magic-link/verify?token=ml_abc123def456..."{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2...",
"expiresAt": "2026-02-08T12:00:00Z",
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"role": "user"
}
}
}{
"success": false,
"error": {
"code": "INVALID_MAGIC_LINK",
"message": "This magic link has expired or has already been used."
}
}Two-Factor Authentication (2FA)
Add a second layer of verification using Time-based One-Time Passwords (TOTP). Compatible with authenticator apps such as Google Authenticator, Authy, and 1Password.
Enable 2FA
/api/v1/auth/2fa/enableGenerate a TOTP secret and provisioning URI for the authenticated user.
curl -X POST https://api.orbai.world/api/v1/auth/2fa/enable \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."{
"success": true,
"data": {
"secret": "JBSWY3DPEHPK3PXP",
"qrCodeUri": "otpauth://totp/OrbVPN:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=OrbVPN&algorithm=SHA1&digits=6&period=30",
"recoveryCodes": [
"abc12-def34",
"ghi56-jkl78",
"mno90-pqr12",
"stu34-vwx56",
"yza78-bcd90",
"efg12-hij34",
"klm56-nop78",
"qrs90-tuv12"
]
}
}Store Recovery Codes
Recovery codes are shown only once. Instruct users to save them in a secure location. If a user loses access to their authenticator app and recovery codes, they will need to contact support to regain access to their account.
Verify 2FA Code
After scanning the QR code, the user must verify a TOTP code to complete 2FA setup. This endpoint is also used during login when 2FA is enabled.
/api/v1/auth/2fa/verifyVerify a TOTP code to complete 2FA setup or satisfy a 2FA login challenge.
| Parameter | Type | Required | Description |
|---|---|---|---|
code | string | Required | The 6-digit TOTP code from the authenticator app. |
curl -X POST https://api.orbai.world/api/v1/auth/2fa/verify \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"code": "123456"
}'{
"success": true,
"data": {
"message": "Two-factor authentication verified successfully.",
"twoFactorEnabled": true
}
}{
"success": false,
"error": {
"code": "INVALID_2FA_CODE",
"message": "The verification code is incorrect or has expired."
}
}Disable 2FA
/api/v1/auth/2fa/disableDisable two-factor authentication for the current user.
| Parameter | Type | Required | Description |
|---|---|---|---|
code | string | Required | A valid 6-digit TOTP code to confirm the action. |
password | string | Required | The user's current password for additional verification. |
curl -X POST https://api.orbai.world/api/v1/auth/2fa/disable \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"code": "654321",
"password": "your_password"
}'{
"success": true,
"data": {
"message": "Two-factor authentication has been disabled.",
"twoFactorEnabled": false
}
}Login with 2FA Enabled
When a user with 2FA enabled calls POST /api/v1/auth/login, the response will include "twoFactorRequired": true and a temporary, limited-scope token. The client must then call POST /api/v1/auth/2fa/verify with that token and the TOTP code to receive the full access and refresh tokens.
API Key Authentication
For server-to-server integrations, particularly with the OrbGuard Labs API, you can use static API keys instead of JWT tokens. API keys are generated from the OrbVPN dashboard and do not expire unless revoked.
/api/v1/guard/*OrbGuard Labs endpoints accept API key authentication via the X-API-Key header.
curl https://guard.orbai.world/api/v1/intelligence/check \
-H "X-API-Key: orbk_live_abc123def456ghi789..." \
-H "Content-Type: application/json" \
-d '{
"indicator": "suspicious-domain.com",
"type": "domain"
}'API Key Security
API keys carry the full permissions of the account that created them. Never embed API keys in client-side code, mobile apps, or public repositories. Use environment variables or a secrets manager for server-side storage. Rotate keys regularly from the OrbVPN dashboard.
Security Best Practices
Use HTTPS Everywhere
All API requests must use HTTPS. HTTP requests are rejected. TLS 1.2+ is required for all connections to the OrbNET platform.
Store Tokens Securely
Use HTTP-only cookies, platform keychains, or encrypted storage. Never store tokens in localStorage on web apps or embed them in URLs.
Implement Token Refresh
Build automatic token refresh logic into your client. On receiving a 401, attempt a silent refresh before prompting the user to re-authenticate.
Enable 2FA for Sensitive Accounts
Require two-factor authentication for admin accounts and users with elevated privileges. It significantly reduces the risk of account takeover.
Rotate API Keys
Periodically rotate API keys from the dashboard. Revoke any keys that may have been exposed. Use separate keys for development and production.
Monitor for Anomalies
Watch for unusual authentication patterns such as logins from new locations, rapid token refreshes, or simultaneous sessions from different regions.
Error Reference
Common authentication error codes and how to handle them.
INVALID_CREDENTIALS
Email or password is incorrect. Prompt the user to check their credentials and try again.
TOKEN_EXPIRED
The access token has expired. Use the refresh token to obtain a new access token.
INVALID_REFRESH_TOKEN
The refresh token is expired or revoked. The user must log in again with their credentials.
TWO_FACTOR_REQUIRED
The account has 2FA enabled. Submit a TOTP code via the 2FA verify endpoint to complete login.
EMAIL_NOT_VERIFIED
The account exists but the email has not been verified. Redirect the user to the verification flow.
RATE_LIMITED
Too many authentication attempts. Respect the retryAfter value in the error response before retrying.
ACCOUNT_LOCKED
The account has been temporarily locked due to suspicious activity. Contact support or wait for the lockout period to expire.
INVALID_API_KEY
The provided API key is invalid, expired, or revoked. Generate a new key from the OrbVPN dashboard.
Need Help?
If you are experiencing authentication issues, check our troubleshooting guide or contact developer support. For account-specific issues, visit the support portal.
Start Building with OrbNET
You are now ready to authenticate and make secure API requests. Explore the full OrbNET API reference to manage VPN connections, users, subscriptions, and more.