Owner: Engineering Team | Last Updated: 2026-01-30 | Status: Current
This guide explains how to integrate a new client application (web, mobile, desktop, browser extension, or third-party plugin) with the WWAI backend API. WWAI currently supports a Next.js web app, Flutter mobile app, and Chrome/Shopify/WordPress plugins. Each new frontend follows the same integration contract described here.
WWAI uses Bearer token authentication for all API requests.
Authorization: Bearer <access_token>
| Token | Lifetime | Purpose |
|---|---|---|
| Access token | Short-lived (configurable) | Authenticates API requests |
| Refresh token | Long-lived | Obtains new access tokens without re-login |
Login endpoint:
POST /api/auth/login/
Content-Type: application/json
{
"email": "user@example.com",
"password": "secure_password"
}
Response:
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOi...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOi...",
"user": {
"id": "uuid",
"email": "user@example.com",
"name": "User Name"
}
}
Refreshing tokens:
POST /api/auth/token/refresh/
Content-Type: application/json
{
"refresh": "<refresh_token>"
}
For social login (Google, GitHub, etc.):
POST /api/auth/social/<provider>/
Content-Type: application/json
{
"access_token": "<provider_access_token>"
}
Every new frontend must integrate with these core endpoints at a minimum:
| Endpoint | Method | Description |
|---|---|---|
/api/auth/login/ |
POST | Email + password login |
/api/auth/register/ |
POST | New user registration |
/api/auth/token/refresh/ |
POST | Refresh access token |
/api/auth/logout/ |
POST | Invalidate refresh token |
/api/auth/password/reset/ |
POST | Request password reset email |
| Endpoint | Method | Description |
|---|---|---|
/api/users/me/ |
GET | Current user profile |
/api/users/me/ |
PATCH | Update profile |
/api/users/me/subscription/ |
GET | Subscription status and limits |
| Endpoint | Method | Description |
|---|---|---|
/api/humanize/ |
POST | Submit text for humanization |
/api/humanize/history/ |
GET | User's humanization history |
/api/detect/ |
POST | Run AI detection on text |
| Endpoint | Method | Description |
|---|---|---|
/api/payments/checkout/ |
POST | Create Stripe checkout session |
/api/payments/plans/ |
GET | Available subscription plans |
User opens app
|
+--> Check for stored refresh token
| |
| +--> Token exists --> Attempt refresh
| | |
| | +--> Success --> Store new access token --> Authenticated
| | |
| | +--> Failure (401) --> Clear tokens --> Show login
| |
| +--> No token --> Show login/register
|
+--> On login success --> Store access + refresh tokens
|
+--> On every API request --> Attach Bearer token
|
+--> On 401 response --> Attempt token refresh
|
+--> Refresh succeeds --> Retry original request
|
+--> Refresh fails --> Redirect to login
| Platform | Recommended Storage | Notes |
|---|---|---|
| Web (SPA) | httpOnly cookies or secure in-memory store |
Avoid localStorage for tokens |
| Mobile (Flutter/native) | Secure storage (Keychain / Keystore) | Encrypted at rest |
| Browser extension | chrome.storage.session |
Cleared when browser closes |
| Desktop | OS keychain | Platform-specific secure storage |
interface UserSession {
isAuthenticated: boolean;
user: {
id: string;
email: string;
name: string;
} | null;
subscription: {
plan: string;
wordsRemaining: number;
expiresAt: string;
} | null;
tokens: {
access: string;
refresh: string;
} | null;
}
All WWAI API errors follow this format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Human-readable description",
"details": {
"field_name": ["Specific field error"]
}
}
}
| HTTP Status | Meaning | Client Action |
|---|---|---|
| 400 | Validation error | Display field-level errors to user |
| 401 | Unauthorized | Attempt token refresh; if fails, redirect to login |
| 403 | Forbidden | Show "access denied" message; check subscription |
| 404 | Not found | Show "not found" UI |
| 429 | Rate limited | Show "try again later"; implement exponential backoff |
| 500 | Server error | Show generic error; log to error tracking |
| 503 | Service unavailable | Show maintenance message; retry with backoff |
// Pseudocode - adapt to your platform
async function apiRequest(method: string, url: string, data?: unknown) {
try {
const response = await httpClient.request({
method,
url: `${API_BASE_URL}${url}`,
data,
headers: {
Authorization: `Bearer ${getAccessToken()}`,
"Content-Type": "application/json",
},
});
return response.data;
} catch (error) {
if (error.status === 401) {
const refreshed = await attemptTokenRefresh();
if (refreshed) {
return apiRequest(method, url, data); // Retry once
}
redirectToLogin();
}
throw normalizeError(error);
}
}
.github/workflows/<client-name>.yml:name: <Client Name> CI
on:
push:
paths:
- "<client-directory>/**"
pull_request:
paths:
- "<client-directory>/**"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup environment
# Platform-specific setup
- name: Lint
run: <lint-command>
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: <test-command>
build:
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- name: Build
run: <build-command>
Dockerfile in the client's root directory.docker-compose.yml for local development.When you add a new frontend, create a documentation page using this template:
# [Client Name] Frontend
> **Owner**: Engineering Team | **Last Updated**: YYYY-MM-DD | **Status**: Current
## Overview
Brief description of the client, its target users, and its distribution channel.
## Architecture
- Framework/language
- State management approach
- Navigation structure
- Key dependencies
## Local Development
- Prerequisites
- Setup steps
- Running locally
- Environment variables needed
## API Integration
- Base URL configuration
- Auth flow implementation details
- Key API endpoints used
## Build & Deploy
- Build command
- Deployment target
- CI/CD pipeline reference
## Testing
- Test framework
- Running tests
- Coverage expectations
## Platform-Specific Notes
- Distribution (App Store, Chrome Web Store, etc.)
- Platform-specific APIs or permissions
- Review/approval process
Use this checklist when integrating a new frontend:
| Date | Author | Change |
|---|---|---|
| 2026-01-30 | Admin | Initial creation |
Prev: Adding a New Feature | Next: Guide: Adding a New AI Model | Up: General