Invite-Only Early Access — Think Throo GitHub App is currently invite-only. Request access here.
2025May

Data fetching in '/apps/[appName]' route in open source ACI.dev platform.

In this article, we are going to review API layer in /apps/GITHUB route in ACI.dev platform. We will look at:

  1. Locating the /apps/GITHUB route

  2. apps/GITHUB folder

  3. API Layer in apps/GITHUB/page.tsx

This /apps/GITHUB route loads a page that looks like below:

ACI.dev is the open source platform that connects your AI agents to 600+ tool integrations with multi-tenant auth, granular permissions, and access through direct function calling or a unified MCP server.

Locating the /apps/GITHUB route

ACI.dev is open source, you can find their code at aipotheosis-labs/aci. This codebase has the below project structure:

  1. apps

  2. backend

  3. frontend

frontend

ACI.dev is built using Next.js, I usually confirm this by looking for next.config.ts at the root of the frontend folder.

And there is a src folder and app folder inside this src folder. This means this project is built using app router.

From here on, it makes it super easy to locate /apps/GITHUB route since this is going to be a folder, according to how app router works in Next.js

You will find the apps/[appName] folder in the above image. [appName] here indicates that this is dynamic route. There won’t be any GITHUB folder, instead this is a param accessible in apps/[appName]/page.tsx

apps/[appName] folder

apps folder has the below structure:

  1. page.tsx- file

It contains only 1 file, page.tsx.

API layer in apps/[appName]

This below code is picked from aci.dev/frontend/…/apps/[appName]/page.tsx.

useEffect(() => {
  async function loadData() {
    try {
      const apiKey = getApiKey(activeProject);
 
      const app = await getApp(appName, apiKey);
      setApp(app);
 
      const functions = await getFunctionsForApp(appName, apiKey);
      setFunctions(functions);
 
      const appConfig = await getAppConfig(appName, apiKey);
      setAppConfig(appConfig);
    } catch (error) {
      console.error("Error fetching app data:", error);
    }
  }
 
  loadData();
}, [appName, activeProject]);

getApiKey:

This below code is imported from /lib/util.ts

import { Project } from "@/lib/types/project";
 
export function getApiKey(project: Project, agentId?: string): string {
  if (
    !project ||
    !project.agents ||
    project.agents.length === 0 ||
    !project.agents[0].api_keys ||
    project.agents[0].api_keys.length === 0
  ) {
    throw new Error(
      `No API key available in project: ${project.id} ${project.name}`,
    );
  }
  if (agentId) {
    const agent = project.agents.find((agent) => agent.id === agentId);
    if (!agent) {
      throw new Error(`Agent ${agentId} not found in project ${project.id}`);
    }
    return agent.api_keys[0].key;
  }
  return project.agents[0].api_keys[0].key;
}

getApp

getApp is defined as shown below:

export async function getApp(
  appName: string,
  apiKey: string,
): Promise<App | null> {
  const apps = await getApps([appName], apiKey);
  return apps.length > 0 ? apps[0] : null;
}

getFunctionsForApp

export async function getFunctionsForApp(
  appName: string,
  apiKey: string,
): Promise<AppFunction[]> {
  const params = new URLSearchParams();
  params.append("app_names", appName);
 
  const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_URL}/v1/functions?${params.toString()}`,
    {
      method: "GET",
      headers: {
        "X-API-KEY": apiKey,
      },
    },
  );
 
  if (!response.ok) {
    throw new Error(
      `Failed to fetch functions: ${response.status} ${response.statusText}`,
    );
  }
 
  const functions = await response.json();
  return functions;
}

This above code is picked from frontend/lib/api/appFunction.ts.

About me:

Hey, my name is Ramu Narasinga. Email: ramu.narasinga@gmail.com

Tired of AI-generated code that works but nobody understands?

I spent 3+ years studying OSS codebases and wrote 350+ articles on what makes them production-grade. I built an open source tool that reviews your PR against your existing codebase patterns.

Your codebase. Your patterns. Enforced.

Get started for free —thinkthroo.com

References:

  1. https://platform.aci.dev/apps/GITHUB

  2. https://github.com/aipotheosis-labs/aci/blob/main/frontend/src/app/apps/%5BappName%5D/page.tsx

  3. https://github.com/aipotheosis-labs/aci/blob/main/frontend/src/lib/api/app.ts#L48