Skip to main content

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

ServiceProduction URLDev URLStack
Backendhttps://api.aiqlick.com/graphqlhttps://api-dev.aiqlick.com/graphqlNestJS 11 + Apollo Server 4
AI Servicehttps://ai.aiqlick.com/graphqlhttps://ai-dev.aiqlick.com/graphqlFastAPI + 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. Run npm run schema:generate in the backend project to regenerate it.
  • Transport: HTTP POST for queries and mutations; WebSocket (graphql-ws) for subscriptions.
  • Subscriptions: notificationCreated, unreadCountChanged, messageReceived, unreadMessageCountChanged, and logStream (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 Authorization header.
  • WebSocket connections: Pass the JWT in connectionParams when 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.

authLink -> logLink (dev only) -> errorLink -> splitLink
|-- uploadLink (file uploads)
|-- retryLink -> httpLink

Key Settings

SettingValueDescription
Timeout90 secondsMaximum time for any HTTP request
Fetch policycache-and-networkReturns cached data immediately, then updates from network
File uploadsCustom customUploadLinkMultipart/form-data, skips retry to avoid timeout on large files
Error handlingAuto-redirect on 401Auth errors (UNAUTHENTICATED) redirect to /auth/signin

WebSocket Split

The Apollo Client uses a split link to route operations:

  • Subscriptions are sent over WebSocket (graphql-ws protocol).
  • Queries and mutations are sent over HTTP.
  • AI streaming subscriptions are routed through the NestJS AI gateway (subscribeAi) over the same NEXT_PUBLIC_GRAPHQL_WS_URL WebSocket 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*Input and Update*Input types 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.