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​