Skip to main content

Bearer Tokens (JWT)

Bearer tokens (JWT) are used to authenticate user-authenticated requests to the OrcaRail API.

Sign in via Dashboard

The simplest way to get a Bearer token is to sign in at the Dashboard. The dashboard uses the same login endpoint and stores the token for you (in cookies); you do not need to handle tokens manually when using the dashboard.

Overview

Bearer tokens are JSON Web Tokens (JWT) that are obtained after a user logs in. They're used for user-facing operations where you need to identify which user is making the request.

Getting a Bearer Token

Login

Authenticate a user to receive a JWT token:

POST /api/v1/auth/email/login

Request Body:

{
"email": "[email protected]",
"password": "secure-password"
}

Response:

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "refresh_token_here",
"tokenExpires": 3600,
"user": {
"id": 1,
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe"
}
}

Using the Token

Include the token in the Authorization header:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Example: Login and Use Token

JavaScript

// Login
const loginResponse = await fetch(
'https://api.orcarail.com/api/v1/auth/email/login',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
password: 'secure-password',
}),
}
)

const { token, refreshToken, user } = await loginResponse.json()

// Store token securely (e.g., in memory, secure cookie, etc.)
localStorage.setItem('authToken', token)

// Use token for subsequent requests
const response = await fetch(
'https://api.orcarail.com/api/v1/payment_intents',
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: '100.00',
currency: 'usd',
payment_method_types: ['crypto'],
tokenId: 1,
networkId: 1,
return_url: 'https://merchant.example.com/return',
}),
}
)

cURL

# Login
TOKEN=$(curl -X POST https://api.orcarail.com/api/v1/auth/email/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "secure-password"
}' | jq -r '.token')

# Use token
curl https://api.orcarail.com/api/v1/payment_intents \
-X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": "100.00",
"currency": "usd",
"payment_method_types": ["crypto"],
"tokenId": 1,
"networkId": 1,
"return_url": "https://merchant.example.com/return"
}'

Token Expiration

JWT tokens expire after a set period (typically 1 hour). When a token expires, you'll receive a 401 Unauthorized response.

Refresh Token

Use the refresh token to get a new access token:

POST /api/v1/auth/refresh
Authorization: Bearer YOUR_REFRESH_TOKEN

Response:

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "new_refresh_token_here",
"tokenExpires": 3600
}

Example: Token Refresh

async function refreshToken(refreshToken) {
const response = await fetch('https://api.orcarail.com/api/v1/auth/refresh', {
method: 'POST',
headers: {
Authorization: `Bearer ${refreshToken}`,
},
})

if (!response.ok) {
// Refresh token expired, need to login again
throw new Error('Refresh token expired')
}

const { token, refreshToken: newRefreshToken } = await response.json()
return { token, refreshToken: newRefreshToken }
}

// Use in your API client
async function apiRequest(url, options = {}) {
let token = localStorage.getItem('authToken')

let response = await fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${token}`,
},
})

// If token expired, try to refresh
if (response.status === 401) {
const refreshToken = localStorage.getItem('refreshToken')
const { token: newToken, refreshToken: newRefreshToken } =
await refreshToken(refreshToken)

localStorage.setItem('authToken', newToken)
localStorage.setItem('refreshToken', newRefreshToken)

// Retry request with new token
response = await fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${newToken}`,
},
})
}

return response
}

Logout

Log out and invalidate the current session:

POST /api/v1/auth/logout
Authorization: Bearer YOUR_JWT_TOKEN

Response: 204 No Content

Getting Current User

Get information about the authenticated user:

GET /api/v1/auth/me
Authorization: Bearer YOUR_JWT_TOKEN

Response:

{
"id": 1,
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"role": "user",
"status": "active"
}

Error Responses

Invalid Token

{
"statusCode": 401,
"message": "Unauthorized",
"error": "Unauthorized"
}

Expired Token

{
"statusCode": 401,
"message": "Token expired",
"error": "Unauthorized"
}

Missing Authorization Header

{
"statusCode": 401,
"message": "Unauthorized",
"error": "Unauthorized"
}

Security Best Practices

1. Store Tokens Securely

  • Web Applications: Store in HTTP-only cookies or secure memory
  • Mobile Apps: Use secure storage (Keychain on iOS, Keystore on Android)
  • Server Applications: Store in environment variables or secret management systems

2. Never Expose Tokens

  • Don't log tokens
  • Don't include tokens in URLs
  • Don't commit tokens to version control

3. Handle Token Expiration

Always implement token refresh logic to handle expired tokens gracefully.

4. Use HTTPS

Always use HTTPS in production to protect tokens in transit.

Next Steps