The Backend GraphQL API is the primary interface for all AIQLick business operations. It is built with NestJS 11 and Apollo Server 4, serving an auto-generated schema with over 320 types.
Endpoint: https://api.aiqlick.com/graphql (production) | https://api-dev.aiqlick.com/graphql (development)
Authentication
All authenticated operations require a valid JWT in the Authorization header:
Authorization: Bearer <jwt_token>
On the server side, resolvers are protected with the @UseGuards(JwtAuthGuard) decorator. The @CurrentUser() parameter decorator injects the authenticated User entity into the resolver method.
mutation {
signIn(input: { email: "user@example.com", password: "..." }) {
token
temporaryToken
message
user {
id
email
}
}
}
Queries
Users
| Query | Description | Auth Required |
|---|
whoAmI | Returns the currently authenticated user with full profile | Yes |
user(id: ID!) | Returns a user profile by ID | Yes |
companyMembers(companyId: ID!) | Lists users belonging to a company | Yes |
Companies
| Query | Description | Auth Required |
|---|
company(id: ID!) | Returns a single company by ID | Yes |
companies | Lists companies the current user belongs to | Yes |
allRoles | Lists all 8 platform roles (Super Admin, Company Admin, Internal Sales, Recruiter/HR, External Sales, Economy, Auditor/Viewer, support) | Yes |
roleById(id: ID!) | Returns a single role by ID with its permissions | Yes |
roleByName(name: String!) | Returns a single role by name with its permissions | Yes |
Jobs
| Query | Description | Auth Required |
|---|
allJobs | Lists all jobs accessible to the current user | Yes |
job(id: ID!) | Returns a single job by ID | Yes |
Talents
| Query | Description | Auth Required |
|---|
talents | Lists talents accessible to the current user | Yes |
talent(id: ID!) | Returns a single talent by ID | Yes |
companyTalents(companyId: String!) | Lists talents associated with a company | Yes |
Candidates
| Query | Description | Auth Required |
|---|
candidates | Lists candidates accessible to the current user | Yes |
companyCandidates(companyId: String!) | Lists candidates across company jobs | Yes |
Pipelines
| Query | Description | Auth Required |
|---|
companyPipelines | Lists pipelines for the current user's company | Yes |
pipeline(id: ID!) | Returns a single pipeline with items | Yes |
| Query | Description | Auth Required |
|---|
contacts | Lists contacts accessible to the current user | Yes |
contactsByCompany(companyId: ID!, query: ContactsQueryInput) | Lists contacts for a specific company | Yes |
Notifications
| Query | Description | Auth Required |
|---|
myNotifications(input: GetNotificationsInput) | Lists user notifications | Yes |
unreadNotificationCount(companyId: ID) | Returns count of unread notifications | Yes |
Billing
| Query | Description | Auth Required |
|---|
creditBalance | Returns current credit balance for the user/company context | Yes |
creditTransactions(filter: CreditTransactionsFilterInput) | Lists credit transaction history | Yes |
creditPacks | Lists available credit packs for purchase | Yes |
plans | Lists all available subscription plans | Yes |
activeSubscription | Returns active subscription for the current context | Yes |
planUsageSummary | Returns usage against plan limits for the current context | Yes |
Meetings
| Query | Description | Auth Required |
|---|
myMeetings(input: ListMeetingsInput) | Lists the current user's meetings | Yes |
companyMeetings(input: ListCompanyMeetingsInput!) | Lists meetings for a company | Yes |
upcomingMeetings(limit: Int) | Lists upcoming meetings (default 10) | Yes |
pastMeetings(limit: Int) | Lists past meetings (default 20) | Yes |
meeting(id: ID!) | Returns a single meeting with details | Yes |
Admin (Super Admin Only)
| Query | Description | Auth Required |
|---|
adminPlatformOverview | Aggregate platform statistics | Super Admin |
adminUserStatistics | User growth and engagement stats | Super Admin |
adminRevenueStatistics | Revenue and billing stats | Super Admin |
The admin module provides 15+ statistical queries covering user activity, billing, system health, and more. All admin queries require the SuperAdmin role.
Mutations
Authentication
| Mutation | Description | Auth Required |
|---|
signUp(input: SignUpsInput!) | Register a new user account | No |
signIn(input: SignInInput!) | Authenticate and receive JWT (AuthPayload) | No |
requestPasswordReset(input: RequestPasswordResetInput!) | Initiate password reset flow | No |
resetPassword(input: ResetPasswordInput!) | Complete password reset | No |
Jobs
| Mutation | Description | Auth Required |
|---|
createJob(input: CreateJobInput!) | Create a new job posting | Yes |
updateJob(id: ID!, input: UpdateJobInput!) | Update an existing job | Yes |
removeJob(id: ID!) | Soft-delete a job | Yes |
Candidates
| Mutation | Description | Auth Required |
|---|
createCandidate(input: CreateCandidateInput!) | Add a talent as a candidate to a job | Yes |
updateCandidate(id: ID!, input: UpdateCandidateInput!) | Update candidate status or details | Yes |
Pipelines
| Mutation | Description | Auth Required |
|---|
createPipeline(input: CreatePipelineInput!) | Create a new recruitment pipeline | Yes |
createPipelineItem(input: CreatePipelineItemInput!) | Add a candidate to a pipeline stage | Yes |
updatePipelineItem(id: ID!, input: UpdatePipelineItemInput!) | Move a candidate between stages | Yes |
Billing
| Mutation | Description | Auth Required |
|---|
startSubscriptionCheckout(input: CheckoutInput!) | Initiate Stripe checkout for a plan | Yes |
purchaseCreditPack(input: PurchaseCreditPackInput!) | Purchase a credit pack via Stripe | Yes |
transferCredits(input: TransferCreditsInput!) | Transfer credits from user to company balance | Yes |
Meetings
| Mutation | Description | Auth Required |
|---|
createMeeting(input: CreateMeetingInput!) | Schedule a new meeting | Yes |
updateMeeting(id: ID!, input: UpdateMeetingInput!) | Update meeting details | Yes |
| Mutation | Description | Auth Required |
|---|
createContact(input: CreateContactInput!) | Create a new contact | Yes |
updateContact(id: ID!, input: UpdateContactInput!) | Update contact details | Yes |
Admin (Super Admin Only)
| Mutation | Description | Auth Required |
|---|
adminAssignSubscription(input: AdminAssignSubscriptionInput!) | Manually assign a subscription to a company | Super Admin |
adminGrantCredits(input: AdminGrantCreditsInput!) | Grant credits to a user or company | Super Admin |
adminDeleteUser(id: ID!) | Soft-delete a user account | Super Admin |
adminBulkDeleteUsers(ids: [ID!]!) | Bulk soft-delete (max 50 users) | Super Admin |
Subscriptions
The Backend exposes five GraphQL subscriptions, all using the graphql-ws protocol over WebSocket.
notificationCreated
Emits real-time notifications filtered by the authenticated user's ID.
subscription {
notificationCreated {
id
type
title
message
status
category
createdAt
}
}
unreadCountChanged
Emits updated unread notification counts, optionally filtered by company.
subscription {
unreadCountChanged(companyId: "optional-company-id") {
count
}
}
messageReceived
Emits real-time updates for new, edited, or deleted messages in conversations.
subscription {
messageReceived {
id
content
conversationId
sender { id firstName lastName }
createdAt
}
}
unreadMessageCountChanged
Emits updated unread message counts across conversations.
subscription {
unreadMessageCountChanged {
count
}
}
logStream
Available to super admins only. Streams live system logs for deployment diagnostics.
subscription {
logStream {
level
message
timestamp
metadata
}
}
Error Handling
The API returns structured GraphQL errors with extension codes. Common error codes and their meanings:
| Code | HTTP Equivalent | Description |
|---|
UNAUTHENTICATED | 401 | Missing or invalid JWT token |
FORBIDDEN | 403 | Insufficient permissions for the requested operation |
BAD_USER_INPUT | 400 | Invalid input data or validation failure |
PLAN_LIMIT_EXCEEDED | 403 | Operation exceeds current subscription plan limits |
NOT_FOUND | 404 | Requested resource does not exist |
INTERNAL_SERVER_ERROR | 500 | Unexpected server error |
Example error response:
{
"errors": [
{
"message": "Job posting limit reached for your current plan",
"extensions": {
"code": "PLAN_LIMIT_EXCEEDED",
"planLimit": 10,
"currentUsage": 10
}
}
]
}
Plan Limit Enforcement
Certain mutations are guarded by the @CheckPlanLimit decorator, which validates the operation against the company's active subscription plan. Plan limits use the following convention:
-1: Unlimited access
0: Feature disabled
> 0: Specific numeric limit
When a plan limit is exceeded, the API returns a PLAN_LIMIT_EXCEEDED error with details about the current limit and usage.