Skip to content

Authentication

The Backend API uses OAuth2 Password Flow for authentication. All authenticated endpoints require a valid access token.


OAuth2 Password Flow

Obtain Access Token

Exchange credentials for an access token:

curl -X POST https://api.sartiq.com/api/v1/login/access-token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=your@email.com&password=yourpassword"

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600
}

Using the Token

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

curl https://api.sartiq.com/api/v1/brands/ \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Token Lifecycle

stateDiagram-v2
    [*] --> Valid: Login successful
    Valid --> Valid: Use token
    Valid --> Expired: Token expires
    Expired --> Valid: Refresh/Re-login
    Expired --> [*]: Session ended

Token Expiration

Token Type Lifetime Refresh
Access Token 1 hour Re-authenticate

Handling Expiration

When a token expires, the API returns:

{
  "detail": "Could not validate credentials"
}

HTTP Status: 401 Unauthorized

Re-authenticate to obtain a new token.


Security Best Practices

Do

  • Store tokens securely (never in localStorage for web apps)
  • Use HTTPS for all requests
  • Implement token refresh before expiration
  • Log out users by discarding tokens client-side

Don't

  • Include tokens in URLs
  • Log tokens in application logs
  • Share tokens between users
  • Store tokens in version control

Error Responses

Invalid Credentials

{
  "detail": "Incorrect email or password"
}
Status: 401 Unauthorized

Missing Token

{
  "detail": "Not authenticated"
}
Status: 401 Unauthorized

Insufficient Permissions

{
  "detail": "Not enough permissions"
}
Status: 403 Forbidden


Code Examples

import httpx

# Authenticate
response = httpx.post(
    "https://api.sartiq.com/api/v1/login/access-token",
    data={
        "username": "your@email.com",
        "password": "yourpassword"
    }
)
token = response.json()["access_token"]

# Use token
client = httpx.Client(
    headers={"Authorization": f"Bearer {token}"}
)
brands = client.get("https://api.sartiq.com/api/v1/brands/")
// Authenticate
const authResponse = await fetch(
  "https://api.sartiq.com/api/v1/login/access-token",
  {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      username: "your@email.com",
      password: "yourpassword",
    }),
  }
);
const { access_token } = await authResponse.json();

// Use token
const brandsResponse = await fetch(
  "https://api.sartiq.com/api/v1/brands/",
  {
    headers: { Authorization: `Bearer ${access_token}` },
  }
);
# Authenticate and extract token
TOKEN=$(curl -s -X POST https://api.sartiq.com/api/v1/login/access-token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=your@email.com&password=yourpassword" \
  | jq -r '.access_token')

# Use token
curl https://api.sartiq.com/api/v1/brands/ \
  -H "Authorization: Bearer $TOKEN"