GraphQL Overview
AIQLick exposes two independent GraphQL APIs that together power the entire platform. The Backend API handles core business logic, authentication, and data management, while the AI Service API drives all artificial intelligence operations with real-time progress streaming.
API Endpoints
| Service | Production URL | Dev URL | Stack |
|---|---|---|---|
| Backend | https://api.aiqlick.com/graphql | https://api-dev.aiqlick.com/graphql | NestJS 11 + Apollo Server 4 |
| AI Service | https://ai.aiqlick.com/graphql | https://ai-dev.aiqlick.com/graphql | FastAPI + Strawberry GraphQL |
Both endpoints support HTTP for queries and mutations, and WebSocket for subscriptions using the graphql-ws protocol.
Backend API
The Backend API is the primary interface for all business operations. It serves an auto-generated schema weighing approximately 174KB with over 320 types covering users, companies, jobs, talents, candidates, pipelines, billing, meetings, notifications, and administration.
- Schema generation: The schema file (
schema.gql) is auto-generated from NestJS resolver decorators. Runnpm run schema:generatein the backend project to regenerate it. - Transport: HTTP POST for queries and mutations; WebSocket (
graphql-ws) for subscriptions. - Subscriptions:
notificationCreated,unreadCountChanged,messageReceived,unreadMessageCountChanged, andlogStream(super admin only), all backed by Redis pub/sub.
AI Service API
The AI Service API handles all machine learning and AI-powered workflows. Built with FastAPI and Strawberry GraphQL, it provides 12+ subscriptions that stream real-time progress updates as AI operations execute.
- Subscriptions: CV extraction, job parsing, face detection, candidate onboarding, job matching, text rewriting, meeting insights, and streaming agent chat.
- Streaming model: Each subscription emits typed progress events (percentage-based, chunked, or event-based) so the frontend can render live feedback.
- Shared database: The AI Service reads from and writes to the same PostgreSQL database as the Backend, using raw AsyncPG queries rather than Prisma.
Authentication
Both services validate JWTs issued by the Backend. Authentication is consistent across the platform:
Authorization: Bearer <jwt_token>
- HTTP requests: Include the JWT in the
Authorizationheader. - WebSocket connections: Pass the JWT in
connectionParamswhen initiating the WebSocket handshake.
{
"connectionParams": {
"token": "<jwt_token>"
}
}
Tokens are issued by the Backend via the signIn mutation. Both services validate tokens against the same user table in PostgreSQL.
Frontend Apollo Client Configuration
The frontend uses Apollo Client with a carefully structured link chain to route requests to the correct service and handle edge cases.
Link Chain
authLink -> logLink (dev only) -> errorLink -> splitLink
|-- uploadLink (file uploads)
|-- retryLink -> httpLink
Key Settings
| Setting | Value | Description |
|---|---|---|
| Timeout | 90 seconds | Maximum time for any HTTP request |
| Fetch policy | cache-and-network | Returns cached data immediately, then updates from network |
| File uploads | Custom customUploadLink | Multipart/form-data, skips retry to avoid timeout on large files |
| Error handling | Auto-redirect on 401 | Auth errors (UNAUTHENTICATED) redirect to /auth/signin |
WebSocket Split
The Apollo Client uses a split link to route operations:
- Subscriptions are sent over WebSocket (
graphql-wsprotocol). - Queries and mutations are sent over HTTP.
- AI streaming subscriptions are routed through the NestJS AI gateway (
subscribeAi) over the sameNEXT_PUBLIC_GRAPHQL_WS_URLWebSocket as the rest of the backend — there is no separate AI WebSocket since the Phase 3.7 cutover.
Fragments
GraphQL fragments are centralized in graphql/operations/schema/ and organized by entity (e.g., USER_FIELDS, COMPANY_FIELDS, JOB_FIELDS). The frontend has 28 feature directories under graphql/operations/ covering admin, AI agent, candidate, companies, contacts, CV, dashboard, interview, job, meeting insights, notifications, payments, pipelines, skills, talent pools, talents, and users.
Schema Organization
The Backend schema is organized by NestJS module, with each module contributing its own types, queries, mutations, and subscriptions. Key type categories include:
- Entity types:
User,Company,Job,Talent,Candidate,Pipeline,Meeting,CreditBalance,Plan,Subscription - Input types: Corresponding
Create*InputandUpdate*Inputtypes for mutations - Enum types:
JobStatus,CandidateStatus,InterviewStatus,SubscriptionStatus,ViewMode,AIOperationType,BillingMode,ConversationType,NotificationCategory,TalentSource - Connection types: Paginated results following the
{ items, total, hasMore }pattern
Error Handling
Both services return errors using standard GraphQL error format with extension codes:
{
"errors": [
{
"message": "You do not have permission to access this resource",
"extensions": {
"code": "FORBIDDEN"
}
}
]
}
Common error codes include UNAUTHENTICATED, FORBIDDEN, PLAN_LIMIT_EXCEEDED, BAD_USER_INPUT, INTERNAL_SERVER_ERROR, and BILLING_ERROR.