Skip to content

API Authentication

Overview

The UptimeHunt API uses JWT (JSON Web Token) based authentication to secure all API endpoints. This guide provides comprehensive documentation for implementing authentication in your applications, including token management, user registration, login workflows, and password reset functionality.

Authentication Flow

Token Types

UptimeHunt issues two types of tokens:

Token Type Lifetime Purpose
Access Token 15 minutes Authenticates API requests
Refresh Token 7 days Generates new access tokens

Token Management Workflow

  1. Initial Authentication: User registers or logs in to receive both access and refresh tokens
  2. API Requests: Include access token in the Authorization header for authenticated requests
  3. Token Refresh: When access token expires, use refresh token to obtain new access token
  4. Re-authentication: When refresh token expires, user must log in again

Base URL

All API endpoints use the following base URL:

https://app.uptimehunt.io/api

Authentication Endpoints

User Registration

Create a new user account and receive authentication tokens.

Endpoint: POST /v1/auth/register

Authentication: Not required

Request Headers:

Content-Type: application/json

Request Body:

{
  "email": "user@example.com",
  "password": "securepassword123",
  "first_name": "John",
  "last_name": "Doe"
}

Request Schema:

Field Type Required Description
email string Yes Valid email address (must be unique)
password string Yes Password (minimum 8 characters)
first_name string No User's first name
last_name string No User's last name

Success Response (201 Created):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "user": {
    "id": 1,
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "date_joined": "2024-01-15T10:30:00Z"
  }
}

Error Responses:

Status Code Error Description
400 Email and password are required Missing required fields
400 User with this email already exists Email already registered

cURL Example:

curl -X POST https://app.uptimehunt.io/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securepassword123",
    "first_name": "John",
    "last_name": "Doe"
  }'

User Login

Authenticate existing user and receive authentication tokens.

Endpoint: POST /v1/auth/login

Authentication: Not required

Request Headers:

Content-Type: application/json

Request Body:

{
  "email": "user@example.com",
  "password": "securepassword123"
}

Request Schema:

Field Type Required Description
email string Yes User's email address
password string Yes User's password

Success Response (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "user": {
    "id": 1,
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "date_joined": "2024-01-15T10:30:00Z"
  }
}

Error Responses:

Status Code Error Description
400 Must include "email" and "password" Missing required fields
400 Invalid credentials Incorrect email or password
400 User account is disabled Account has been deactivated

cURL Example:

curl -X POST https://app.uptimehunt.io/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securepassword123"
  }'

Refresh Access Token

Generate a new access token using a valid refresh token.

Endpoint: POST /v1/auth/refresh

Authentication: Not required (uses refresh token)

Request Headers:

Content-Type: application/json

Request Body:

{
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Request Schema:

Field Type Required Description
refresh_token string Yes Valid refresh token

Success Response (200 OK):

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 900
}

Error Responses:

Status Code Error Description
400 Refresh token is required Missing refresh token
401 Invalid refresh token Token is invalid, expired, or malformed

cURL Example:

curl -X POST https://app.uptimehunt.io/api/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }'

Get Current User

Retrieve authenticated user information.

Endpoint: GET /v1/auth/me

Authentication: Required

Request Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Success Response (200 OK):

{
  "data": {
    "id": 1,
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "date_joined": "2024-01-15T10:30:00Z"
  }
}

Error Responses:

Status Code Error Description
401 Authentication credentials were not provided Missing Authorization header
401 Given token not valid for any token type Invalid or expired access token

cURL Example:

curl -X GET https://app.uptimehunt.io/api/v1/auth/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Update User Profile

Update authenticated user's profile information.

Endpoint: PUT /v1/auth/profile or PATCH /v1/auth/profile

Authentication: Required

Request Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

Request Body (all fields optional for PATCH):

{
  "email": "newemail@example.com",
  "first_name": "Jane",
  "last_name": "Smith"
}

Request Schema:

Field Type Required Description
email string No New email address (must be unique)
first_name string No Updated first name
last_name string No Updated last name

Success Response (200 OK):

{
  "data": {
    "id": 1,
    "email": "newemail@example.com",
    "first_name": "Jane",
    "last_name": "Smith",
    "date_joined": "2024-01-15T10:30:00Z"
  },
  "message": "Profile updated successfully"
}

Error Responses:

Status Code Error Description
400 A user with this email already exists Email already in use
401 Authentication credentials were not provided Missing or invalid token

cURL Example:

curl -X PUT https://app.uptimehunt.io/api/v1/auth/profile \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Jane",
    "last_name": "Smith"
  }'

Change Password

Change authenticated user's password.

Endpoint: POST /v1/auth/change-password

Authentication: Required

Request Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

Request Body:

{
  "current_password": "oldpassword123",
  "new_password": "newsecurepassword456"
}

Request Schema:

Field Type Required Description
current_password string Yes Current password for verification
new_password string Yes New password (minimum 8 characters)

Success Response (200 OK):

{
  "status": "PASSWORD_CHANGED",
  "message": "Password changed successfully"
}

Error Responses:

Status Code Error Description
400 Current password is incorrect Wrong current password provided
400 This field is required Missing required field
400 Ensure this field has at least 8 characters Password too short
401 Authentication credentials were not provided Missing or invalid token

cURL Example:

curl -X POST https://app.uptimehunt.io/api/v1/auth/change-password \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "current_password": "oldpassword123",
    "new_password": "newsecurepassword456"
  }'

Security Notice

A confirmation email is sent to the user after successfully changing their password.


Request Password Reset

Request a password reset link via email.

Endpoint: POST /v1/auth/password-reset/request

Authentication: Not required

Request Headers:

Content-Type: application/json

Request Body:

{
  "email": "user@example.com",
  "frontend_url": "https://app.uptimehunt.com"
}

Request Schema:

Field Type Required Description
email string Yes Email address of the account
frontend_url string No Base URL for password reset link (defaults to configured frontend URL)

Success Response (200 OK):

{
  "status": "PASSWORD_RESET_SENT",
  "detail": "If an account with that email exists, a password reset link has been sent."
}

Error Responses:

Status Code Error Description
400 Email is required Missing email field
500 Failed to send password reset email Email service unavailable

cURL Example:

curl -X POST https://app.uptimehunt.io/api/v1/auth/password-reset/request \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "frontend_url": "https://app.uptimehunt.com"
  }'

Security Design

The response is intentionally vague to prevent email enumeration attacks. The same response is returned whether the email exists or not.


Confirm Password Reset

Complete the password reset process using the token from email.

Endpoint: POST /v1/auth/password-reset/confirm

Authentication: Not required

Request Headers:

Content-Type: application/json

Request Body:

{
  "uid": "MQ",
  "token": "c5h7ke-8f9a2b3c4d5e6f7g8h9i0j1k2",
  "new_password": "newsecurepassword456"
}

Request Schema:

Field Type Required Description
uid string Yes Base64-encoded user ID from reset email
token string Yes Password reset token from email
new_password string Yes New password (minimum 8 characters)

Success Response (200 OK):

{
  "status": "PASSWORD_RESET_CONFIRMED",
  "detail": "Password has been reset successfully"
}

Error Responses:

Status Code Error Description
400 UID, token, and new password are required Missing required fields
400 Invalid reset link Invalid or malformed UID/token
400 Invalid or expired reset link Token has expired or already used
400 Password must be at least 8 characters long Password too short

cURL Example:

curl -X POST https://app.uptimehunt.io/api/v1/auth/password-reset/confirm \
  -H "Content-Type: application/json" \
  -d '{
    "uid": "MQ",
    "token": "c5h7ke-8f9a2b3c4d5e6f7g8h9i0j1k2",
    "new_password": "newsecurepassword456"
  }'

Confirmation Email

A confirmation email is sent to the user after successfully resetting their password.


Using Authentication Tokens

Token Storage

Store tokens securely in your application:

  • Web Applications: Use secure HTTP-only cookies or browser localStorage
  • Mobile Applications: Use secure storage mechanisms (Keychain, KeyStore)
  • Server-to-Server: Use environment variables or secure credential storage

Making Authenticated Requests

Include the access token in the Authorization header for all authenticated API requests:

Authorization: Bearer {access_token}

Example Request:

curl -X GET https://app.uptimehunt.io/api/v1/services \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Handling Token Expiration

Access tokens expire after 15 minutes. Implement token refresh logic:

// JavaScript/TypeScript example
async function apiRequest(url, options = {}) {
  let accessToken = localStorage.getItem('access_token');

  // Add authorization header
  options.headers = {
    ...options.headers,
    'Authorization': `Bearer ${accessToken}`
  };

  let response = await fetch(url, options);

  // If token expired, refresh and retry
  if (response.status === 401) {
    const refreshToken = localStorage.getItem('refresh_token');

    // Refresh the token
    const refreshResponse = await fetch('/api/v1/auth/refresh', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ refresh_token: refreshToken })
    });

    if (refreshResponse.ok) {
      const { access_token } = await refreshResponse.json();
      localStorage.setItem('access_token', access_token);

      // Retry original request with new token
      options.headers['Authorization'] = `Bearer ${access_token}`;
      response = await fetch(url, options);
    } else {
      // Refresh failed, redirect to login
      window.location.href = '/login';
    }
  }

  return response;
}
# Python example using requests
import requests
from datetime import datetime, timedelta

class APIClient:
    def __init__(self, base_url):
        self.base_url = base_url
        self.access_token = None
        self.refresh_token = None
        self.token_expiry = None

    def login(self, email, password):
        response = requests.post(
            f"{self.base_url}/v1/auth/login",
            json={"email": email, "password": password}
        )
        response.raise_for_status()
        data = response.json()

        self.access_token = data['access_token']
        self.refresh_token = data['refresh_token']
        # Token expires in 900 seconds (15 minutes)
        self.token_expiry = datetime.now() + timedelta(seconds=data['expires_in'])

        return data['user']

    def refresh_access_token(self):
        response = requests.post(
            f"{self.base_url}/v1/auth/refresh",
            json={"refresh_token": self.refresh_token}
        )
        response.raise_for_status()
        data = response.json()

        self.access_token = data['access_token']
        self.token_expiry = datetime.now() + timedelta(seconds=data['expires_in'])

    def request(self, method, endpoint, **kwargs):
        # Refresh token if expired or about to expire
        if self.token_expiry and datetime.now() >= self.token_expiry - timedelta(minutes=1):
            self.refresh_access_token()

        headers = kwargs.pop('headers', {})
        headers['Authorization'] = f"Bearer {self.access_token}"

        response = requests.request(
            method,
            f"{self.base_url}{endpoint}",
            headers=headers,
            **kwargs
        )

        # Handle token expiration
        if response.status_code == 401:
            self.refresh_access_token()
            headers['Authorization'] = f"Bearer {self.access_token}"
            response = requests.request(
                method,
                f"{self.base_url}{endpoint}",
                headers=headers,
                **kwargs
            )

        return response

# Usage
client = APIClient("https://app.uptimehunt.io/api")
client.login("user@example.com", "password123")
response = client.request("GET", "/v1/services")
services = response.json()

Security Best Practices

Token Security

  1. Secure Storage: Never store tokens in plain text or client-side code
  2. HTTPS Only: Always use HTTPS in production to prevent token interception
  3. Token Rotation: Implement regular token refresh to minimize security risks
  4. Logout: Invalidate tokens on logout by removing them from storage

Password Security

  1. Minimum Length: Enforce minimum 8-character passwords
  2. Complexity: Use passwords with mixed character types
  3. Unique Passwords: Never reuse passwords across services
  4. Password Managers: Recommend using password managers

API Security

  1. Input Validation: Validate all input data on the client and server
  2. Error Handling: Don't expose sensitive information in error messages
  3. Monitoring: Monitor authentication attempts for suspicious activity

Common Authentication Errors

401 Unauthorized

Cause: Missing, invalid, or expired authentication token

Solutions: - Verify token is included in Authorization header - Check token format: Bearer {token} - Refresh expired access token using refresh token - Re-authenticate if refresh token is expired

400 Bad Request

Cause: Invalid request parameters or validation errors

Solutions: - Verify all required fields are provided - Check field formats (email, password length) - Review error response for specific validation messages

403 Forbidden

Cause: Valid authentication but insufficient permissions

Solutions: - Verify user has necessary permissions - Check resource ownership - Contact administrator for access

JWT Token Structure

UptimeHunt uses JWT tokens with the following configuration:

Setting Value Description
Algorithm HS256 HMAC with SHA-256
Access Token Lifetime 15 minutes Validity period for access tokens
Refresh Token Lifetime 7 days Validity period for refresh tokens
Header Type Bearer Authorization header type
User ID Claim user_id Claim containing user identifier

Token Payload Example

{
  "user_id": 1,
  "token_type": "access",
  "exp": 1705318200,
  "iat": 1705317300,
  "jti": "abc123def456"
}
Claim Description
user_id Unique identifier for the authenticated user
token_type Token type (access or refresh)
exp Expiration timestamp (Unix time)
iat Issued at timestamp (Unix time)
jti JWT ID (unique token identifier)