This document contains all TypeScript interfaces and types used in the Groupify API, ready for React Native implementation.
type ApiResponse<T> = {
data: T;
message?: string;
};type ApiError = {
message: string;
status: number;
errors?: Record<string, string[]>;
};interface Pagination {
total: number;
page: number;
limit: number;
totalPages: number;
next?: string | null;
previous?: string | null;
}type LoginCredentials = {
email: string;
password: string;
};type RegisterCredentials = {
name: string;
email: string;
password: string;
encryptedPassword: string;
};type LoginResponse = {
user: {
id: string;
email: string;
name: string;
};
token?: string;
};type RegisterResponse = {
user: {
id: string;
email: string;
name: string;
};
token?: string;
message: string;
};type ForgotPasswordRequest = {
email: string;
encrypted_password: string;
};type ForgotPasswordResponse = {
message: string;
success: boolean;
};type SubscriptionConfirmRequest = {
token: string;
};type SubscriptionConfirmResponse = {
success: boolean;
message: string;
};type DeleteAccountResponse = {
success: boolean;
};type UpdatePasswordRequest = {
password: string;
passwordConfirmation: string;
};type UpdatePasswordResponse = {
success: boolean;
};interface User {
id: string;
email: string;
username: string;
createdAt: string;
updatedAt: string;
planName: string;
maxChannels: number;
maxGroups: number;
canCreateSubgroups: boolean;
priceMonthly: number;
priceYearly: number;
subscriptionStartDate: string;
subscriptionEndDate: string;
groupCount: number;
channelCount: number;
canAddChannel: boolean;
canAddGroup: boolean;
}interface Group {
id: string;
name: string;
description?: string;
icon?: string;
channels?: Channel[];
category?: string;
nestingLevel?: number;
displayOrder?: number;
parentId?: string | null;
enableGroupshelf?: boolean;
createdAt: string;
channelCount: number;
videoCount?: number;
updatedAt: string;
}interface GroupsResponse {
data: Group[];
pagination: Pagination;
}interface CreateGroupRequest {
name: string;
description?: string;
icon?: string;
category?: string;
parentId?: string | null;
enableGroupshelf?: boolean;
}interface UpdateGroupRequest {
name?: string;
description?: string;
icon?: string;
category?: string;
parentId?: string | null;
enableGroupshelf?: boolean;
}interface Channel {
id: string;
name: string;
channelId: string;
url: string;
thumbnail?: string;
contentType?: string;
subscriberCount?: number;
videoCount?: number;
groupId: string;
groupName?: string;
groupIcon?: string;
createdAt?: string;
updatedAt?: string;
}interface ChannelsResponse {
data: Channel[];
pagination: Pagination;
}interface CreateChannelRequest {
name: string;
channelId: string;
url: string;
thumbnail?: string;
subscriberCount?: number;
videoCount?: number;
groupId: string;
}interface UpdateChannelRequest {
id: string;
contentType?: string;
name?: string;
channelId?: string;
url?: string;
thumbnail?: string;
subscriberCount?: number;
videoCount?: number;
groupId?: string;
}interface BatchUpdateChannelRequest {
channels: UpdateChannelRequest[];
}interface Anime {
id: string;
userId?: string | null;
groupId?: string | null;
name: string;
channelId: string;
thumbnail?: string;
createdAt?: string;
contentType?: string;
updatedAt?: string;
groupName?: string;
groupIcon?: string;
url?: string;
}interface PaginatedAnimesResponse {
data: Anime[];
pagination: Pagination;
}interface Website {
id: string;
name: string;
url: string;
thumbnail?: string;
groupId: string;
groupName?: string;
createdAt?: string;
updatedAt?: string;
}interface WebsitesResponse {
data: Website[];
pagination: Pagination;
}interface ShareLink {
id: string;
groupId: string;
group_id: string;
linkCode: string;
linkType: string;
permission?: string;
createdAt?: string;
expiresAt?: string;
}interface ConsumedShareLinkResponse {
groupId: string;
groupName: string;
groupDescription: string | null;
linkType: string;
permission: string | null;
channelCount: number;
channels: Channel[];
}interface ShareLinksResponse {
data: ShareLink[];
pagination: {
total: number;
page: number;
limit: number;
totalPages: number;
};
}interface GenerateShareLinkVariables {
id: string;
linkType: string;
permission: string;
}interface GenerateShareLinkResponseData {
shareLink: string;
}interface GroupShelf {
id: string;
name: string;
description?: string;
icon?: string;
userId: string;
createdAt: string;
}interface GroupShelfResponse {
data: GroupShelf[];
pagination: Pagination;
}interface BlogPost {
id: number;
status: string;
sort: number | null;
date_created: string;
date_updated: string;
image: string;
slug: string;
title: string;
description: string;
readTime: string;
category: string;
featured: boolean;
content: string;
author?: string;
}interface BlogPostsResponse {
data: BlogPost[];
total: number;
}interface SingleBlogPostsResponse {
data: BlogPost;
total: number;
}interface BlogQueryParams {
status?: string;
category?: string;
featured?: boolean;
limit?: number;
page?: number;
search?: string;
slug?: string;
}interface Video {
id: string;
title: string;
description?: string;
thumbnail?: string;
channelId: string;
channelName?: string;
publishedAt: string;
duration?: string;
viewCount?: number;
likeCount?: number;
}interface GroupVideosResponse {
data: Video[];
pagination: Pagination;
}type DashboardTotalResponse = {
groups: number;
channels: number;
youtubeChannels: number;
sharedGroups: number;
animeChannels: number;
};interface CreateCheckoutSessionRequest {
priceId: string;
interval: 'monthly' | 'yearly';
}interface CheckoutSessionResponse = {
url: string;
};type UpdateProfileRequest = {
name?: string;
email?: string;
};type UpdateProfileResponse = {
success: boolean;
user?: User;
};interface SocialLoginSessionStatus {
status: 'pending' | 'completed' | 'failed';
user?: User;
token?: string;
}POST /authorize- LoginPOST /registration- RegisterPOST /forget-password- Forgot passwordPOST /auth/update_password- Update passwordDELETE /account- Delete account
GET /api/v3/me- Get current userPOST /logout- Logout
GET /api/v3/groups- List groups (paginated)GET /api/v2/groups/:id- Get single groupPOST /api/v2/groups- Create groupPUT /api/v2/groups/:id- Update groupDELETE /api/v2/groups/:id- Delete groupPUT /api/v2/groups/:id/display-order- Update display orderPUT /api/v2/groups/display-order/bulk- Bulk update display orderPOST /api/v3/groups/:id/videos/sync- Sync videos
GET /api/v2/channels- List all channels (paginated)GET /api/v2/channels/:id- Get single channelGET /api/v2/channels/group/:groupId- Get channels by groupPOST /api/v2/channels- Create channelPATCH /api/v2/channels/:id- Update channelDELETE /api/v2/channels/:id- Delete channelPOST /api/v3/channels/:groupId/batch- Batch update channelsPOST /api/v3/proxy/fetch-url- Fetch channel from URL
GET /api/v3/animes- List animes (paginated)
GET /api/v3/websites- List websites (paginated)
GET /api/v3/share-links- List share linksPOST /api/v3/share-links- Create share linkDELETE /api/v3/share-links/:id- Delete share linkGET /api/v2/share-link/:id- Get share linkPOST /api/v2/share-link- Generate share linkPOST /api/v2/share-link/:linkType/:linkCode- Consume share link
GET /groupshelf- Get group shelfPOST /groupshelf- Copy group shelf
GET /api/v3/blog- List blog postsGET /api/v3/blog/:slug- Get single blog post
GET /api/v2/dashboard/total- Get dashboard totals
POST /api/v3/payments/checkout- Create checkout sessionPOST /api/v3/payments/cancel- Cancel subscription
// api/client.ts
class ApiClient {
private baseURL: string;
private defaultHeaders: Record<string, string>;
constructor(baseURL: string = "https://your-api.com") {
this.baseURL = baseURL;
this.defaultHeaders = {
"Content-Type": "application/json",
};
}
async get<T>(endpoint: string, params?: Record<string, any>): Promise<T>
async post<T>(endpoint: string, data?: unknown): Promise<T>
async put<T>(endpoint: string, data?: unknown): Promise<T>
async patch<T>(endpoint: string, data?: unknown): Promise<T>
async delete<T>(endpoint: string): Promise<T>
setAuthToken(token: string)
removeAuthToken()
}
export const apiClient = new ApiClient();// App.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000,
gcTime: 10 * 60 * 1000,
},
},
});
export default function App() {
return (
<QueryClientProvider client={queryClient}>
{/* App content */}
</QueryClientProvider>
);
}// hooks/useGroups.ts
import { useQuery } from '@tanstack/react-query';
import { apiClient, type ApiResponse } from '@/api/client';
import type { Group, GroupsResponse } from '@/types';
export function useGroups(params?: { page?: number; limit?: number; search?: string }) {
return useQuery({
queryKey: ['groups', params],
queryFn: () => apiClient.get<GroupsResponse>('api/v3/groups', params),
});
}