Authentication
Vulcan uses JWT-based authentication. All API endpoints require authentication unless explicitly marked as public.
Endpoints
Login
Authenticates a user and returns a JWT token.
http
POST /api/auth/loginRequest Body
json
{
"email": "user@example.com",
"password": "password123"
}Success Response 200 OK
json
{
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresAt": "2026-01-13T10:00:00Z"
},
"error": null,
"meta": {
"timestamp": "2026-01-12T10:00:00Z",
"requestId": "jkl-012"
}
}Error Response 401 Unauthorized
json
{
"data": null,
"error": {
"code": "INVALID_CREDENTIALS",
"message": "Invalid email or password"
},
"meta": {
"timestamp": "2026-01-12T10:00:00Z",
"requestId": "mno-345"
}
}Refresh Token
Refreshes an expired JWT token using a refresh token.
http
POST /api/auth/refreshRequest Body
json
{
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
}Success Response 200 OK
json
{
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"expiresAt": "2026-01-13T10:00:00Z"
},
"error": null,
"meta": {
"timestamp": "2026-01-12T10:00:00Z",
"requestId": "pqr-678"
}
}Error Response 401 Unauthorized
json
{
"data": null,
"error": {
"code": "INVALID_REFRESH_TOKEN",
"message": "Invalid or expired refresh token"
},
"meta": {
"timestamp": "2026-01-12T10:00:00Z",
"requestId": "stu-901"
}
}Logout
Invalidates the current session and refresh token.
http
POST /api/auth/logoutHeaders
http
Authorization: Bearer <token>Success Response 204 No Content
No response body.
Using Authentication
Request Header
Include the JWT token in the Authorization header for all authenticated requests:
http
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...Token Expiration
- Access tokens expire after 1 hour
- Refresh tokens expire after 7 days
- Use the refresh endpoint to get a new access token before expiration
Frontend Integration
typescript
// Using TanStack Query
export function useLogin() {
return useMutation({
mutationFn: (credentials: LoginRequest) =>
authApi.login(credentials),
onSuccess: (data) => {
localStorage.setItem('token', data.token);
},
});
}
// API client interceptor
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});Security Best Practices
Important
- Never store tokens in cookies without
HttpOnlyandSecureflags - Always use HTTPS in production
- Implement token refresh before expiration
- Clear tokens on logout
- Handle 401 responses by redirecting to login