Skip to main content
The Skillhouse API uses JWT-based authentication. When you log in, you receive a short-lived access token and a long-lived refresh token. Include the access token on every protected request.

How it works

1

Log in

Call POST /api/auth/login with your email and password. The response includes an accessToken and sets an httpOnly refreshToken cookie.
2

Send authenticated requests

Include the access token in the Authorization header as Bearer <accessToken>.
3

Refresh when expired

Access tokens expire after 2 hours. Call POST /api/auth/refresh-token to get a new one using the refresh token cookie.

Token lifetimes

TokenLifetimeTransport
Access token2 hoursResponse body
Refresh token7 daysHttpOnly cookie

Logging in

POST /api/auth/login

Authenticates a user with email and password. Returns an access token in the response body and sets a refreshToken httpOnly cookie. Request body
email
string
required
The user’s email address.
password
string
required
The user’s password.
Response
message
string
Human-readable result message.
accessToken
string
JWT access token. Include this in the Authorization header for subsequent requests.
role
string
The authenticated user’s role: client, freelancer, or admin.
user
object
curl -X POST https://your-api-domain.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "yourpassword"}'

Making authenticated requests

Pass the access token in the Authorization header using the Bearer scheme.
curl https://your-api-domain.com/api/client/get-jobs \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Browser-based clients that rely on cookies do not need to attach the header manually — the refreshToken cookie is sent automatically with same-origin requests.
Never expose your access token in client-side code, URLs, or logs. Store it in memory (not localStorage) in browser applications.

Refreshing an access token

POST /api/auth/refresh-token

Issues a new access token using the refreshToken cookie. No request body is needed — the cookie is read automatically.
curl -X POST https://your-api-domain.com/api/auth/refresh-token \
  --cookie "refreshToken=YOUR_REFRESH_TOKEN"
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Call this endpoint when a protected request returns a 401 with the message "Invalid token" or "Token is required".

Google OAuth login

POST /api/auth/google-login

Authenticates a user with a Google credential token. If no Skillhouse account exists for the Google email, a new account is created automatically.
token
string
required
The credential token returned by the Google Identity Services SDK after the user completes the Google sign-in flow.
role
string
required
The role to assign if a new account is created: client or freelancer. Ignored for existing accounts.
The response shape is identical to a standard login response — you receive an accessToken and the user object, and the refreshToken cookie is set.
curl -X POST https://your-api-domain.com/api/auth/google-login \
  -H "Content-Type: application/json" \
  -d '{"token": "GOOGLE_CREDENTIAL_TOKEN", "role": "freelancer"}'

Role-based access

After authentication, each request is checked against the role encoded in the JWT. Some endpoints are restricted to specific roles.
RoleAccess
clientClient job posting, contracts, and payment endpoints
freelancerFreelancer application, contract, and wallet endpoints
adminAdmin user management, category, escrow, and revenue endpoints
Your role is returned in the login response and encoded in the JWT. You cannot change your role after registration.

Error responses

401 Unauthorized

Returned when the token is missing, expired, or invalid. Re-authenticate by calling /api/auth/login or refresh your access token with /api/auth/refresh-token.
{
  "message": "Invalid token",
  "status": 401
}

403 Forbidden

Returned when your token is valid but your role does not have permission to access the endpoint.
{
  "message": "Access denied",
  "status": 403
}
A 403 can also be returned if your account has been blocked by an admin. In that case, re-authenticating will not resolve the error.

Logging out

POST /api/auth/logout

Clears the refreshToken cookie. After logging out, the access token you hold remains valid until it expires (up to 2 hours). Discard it client-side immediately.
curl -X POST https://your-api-domain.com/api/auth/logout \
  --cookie "refreshToken=YOUR_REFRESH_TOKEN"

Auth endpoints

Full reference for all /api/auth/* routes including registration and password reset.

Authentication feature

Overview of how authentication works across the Skillhouse platform.

Build docs developers (and LLMs) love