Skip to content

Authentication

The Sherpai Partner API uses Firebase Authentication with JWT tokens for secure access to protected endpoints.

Authentication Flow

1. Login Process

To access protected endpoints, you first need to authenticate:

curl -X POST "https://partner-api.sherp.ai/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "your-email@example.com",
    "password": "your-password"
  }'

Success Response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
  "token_type": "bearer",
  "expires_in": 3600,
  "user_id": "firebase_user_uid"
}

2. Using the Token

Include the access token in the Authorization header for protected endpoints:

curl -X GET "https://partner-api.sherp.ai/protected-endpoint" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6..."

Token Management

Token Expiration

  • Lifetime: 1 hour (3600 seconds)
  • Renewal: Re-authenticate when tokens expire
  • Validation: Tokens are validated on each request

Security Best Practices

  1. Store Securely: Never store tokens in plain text or localStorage in production
  2. HTTPS Only: Always use HTTPS in production environments
  3. Token Rotation: Implement automatic token renewal
  4. Error Handling: Handle authentication errors gracefully

Error Responses

Invalid Credentials

{
  "detail": "Invalid email or password"
}
Status Code: 401 Unauthorized

Invalid Token

{
  "detail": "Could not validate credentials"
}
Status Code: 401 Unauthorized

Expired Token

{
  "detail": "Token has expired"
}
Status Code: 401 Unauthorized

Protected Endpoints

The following endpoints require authentication:

  • GET /analytics/
  • GET /posts
  • GET /me

Implementation Examples

Python (httpx)

import httpx
import asyncio

class APIClient:
    def __init__(self, base_url: str):
        self.base_url = base_url
        self.token = None

    async def login(self, email: str, password: str):
        async with httpx.AsyncClient() as client:
            response = await client.post(
                f"{self.base_url}/auth/login",
                json={"email": email, "password": password}
            )
            if response.status_code == 200:
                data = response.json()
                self.token = data["access_token"]
                return data
            else:
                raise Exception(f"Login failed: {response.status_code}")

    async def make_authenticated_request(self, endpoint: str):
        if not self.token:
            raise Exception("Not authenticated")

        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"{self.base_url}{endpoint}",
                headers={"Authorization": f"Bearer {self.token}"}
            )
            return response.json()

JavaScript (Fetch)

class APIClient {
    constructor(baseURL) {
        this.baseURL = baseURL;
        this.token = null;
    }

    async login(email, password) {
        const response = await fetch(`${this.baseURL}/auth/login`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ email, password })
        });

        if (response.ok) {
            const data = await response.json();
            this.token = data.access_token;
            return data;
        } else {
            throw new Error(`Login failed: ${response.status}`);
        }
    }

    async makeAuthenticatedRequest(endpoint) {
        if (!this.token) {
            throw new Error('Not authenticated');
        }

        const response = await fetch(`${this.baseURL}${endpoint}`, {
            headers: { 'Authorization': `Bearer ${this.token}` }
        });

        return response.json();
    }
}

Troubleshooting

Common Issues

"Could not validate credentials" - Check that the Authorization header is properly formatted - Ensure the token hasn't expired - Verify Firebase configuration is correct

"Invalid email or password" - Confirm user exists in Firebase Authentication - Check password is correct - Verify Firebase project configuration

CORS Errors - Ensure CORS is properly configured for your domain - Check that you're using the correct API URL