This page documents the frontend API client layer: the Axios-based HTTP client, its request and response interceptors, the SSE streaming handler, and the catalog of plain async API functions. For the authentication context that consumes tokens managed here, see Authentication Context. For how the build system uses SSE events from this layer, see Build and Execution Flow.
The API client layer sits in src/frontend/src/controllers/API/ and is responsible for all communication between the React frontend and the Langflow backend. It has two main parts:
api.tsx — the Axios instance, the ApiInterceptor React component that registers request/response interceptors, and the performStreamingRequest function for SSE.index.ts — a flat module of async functions, each wrapping one backend endpoint.There is also a queries/ subdirectory (referenced throughout the codebase but not detailed here) that wraps individual API calls in TanStack React Query hooks (useMutation, useQuery).
Request flow diagram
Sources: src/frontend/src/controllers/API/api.tsx1-30 src/frontend/src/controllers/API/index.ts1-20
The singleton api Axios instance is created at module load time in api.tsx:
const api: AxiosInstance = axios.create({
baseURL: baseURL,
withCredentials: getAxiosWithCredentials(),
});
| Property | Value source | Purpose |
|---|---|---|
baseURL | @/customization/constants → baseURL | Resolves the backend origin |
withCredentials | getAxiosWithCredentials() from @/customization/utils/get-fetch-credentials | Sends cookies with cross-origin requests when needed |
The api object is exported and used directly by every function in index.ts.
Sources: src/frontend/src/controllers/API/api.tsx24-28
ApiInterceptor ComponentApiInterceptor is a render-nothing React component (return null) whose sole job is to register and tear down Axios interceptors via useEffect. It must be mounted once inside the React tree so that interceptors have access to Zustand store state and React Query mutation hooks.
Lifecycle of interceptors
Sources: src/frontend/src/controllers/API/api.tsx29-183
Registered via api.interceptors.request.use(...) at src/frontend/src/controllers/API/api.tsx146-175
Responsibilities:
checkDuplicateRequestAndStoreRequest(config) (from helpers/check-duplicate-requests). If a duplicate is detected it aborts the request via AbortController.window.location.origin, all entries from useCustomApiHeaders() are merged into config.headers. External URLs (GitHub, Segment, etc.) are excluded.Registered via api.interceptors.response.use(...) at src/frontend/src/controllers/API/api.tsx65-99
Success path: calls setHealthCheckTimeout(null) to clear any pending health-check timeout, then passes the response through unchanged.
Error path:
Key helper functions in ApiInterceptor:
| Function | Behaviour |
|---|---|
checkErrorCount() | Increments authenticationErrorCount; forces logout after 3 failures |
tryToRenewAccessToken(error) | Calls mutationRenewAccessToken; on success retries the original request |
remakeRequest(error) | Replays error.config using bare axios.request() |
clearBuildVerticesState(error) | On 500, resets all vertex build statuses to BuildStatus.BUILT via useFlowStore |
Sources: src/frontend/src/controllers/API/api.tsx65-240
fetchIntercept RegistrationIn addition to the Axios interceptor, ApiInterceptor also intercepts native fetch calls via the fetch-intercept library. The only action taken is injecting custom headers (from useCustomApiHeaders()) into non-external requests. This covers endpoints called outside Axios, such as performStreamingRequest.
Sources: src/frontend/src/controllers/API/api.tsx49-63
performStreamingRequest in api.tsx handles the SSE (Server-Sent Events) protocol used during flow builds. It bypasses Axios entirely and uses the native Fetch API so it can stream a ReadableStream.
Signature:
Processing loop:
The buildController (AbortController) is passed in by the caller; aborting it terminates both the fetch and signals the backend to stop via the Connection: close header.
The sanitizeJsonString helper converts bare NaN literals (which are invalid JSON) to null before parsing.
Sources: src/frontend/src/controllers/API/api.tsx245-368
index.ts exports a set of plain async functions. Each function calls api.get/post/patch and returns typed data. The getBaseUrl() helper (from @/customization/utils/urls) provides the path prefix.
| Function | Method | URL | Returns |
|---|---|---|---|
getRepoStars(owner, repo) | GET | https://api.github.com/repos/{owner}/{repo} | stargazers_count |
getDiscordCount() | GET | https://discord.com/api/v9/invites/EqksyE2EX9 | approximate_member_count |
getAppVersions | — | (delegated to customGetAppVersions) | version list |
getLatestVersion | — | (delegated to customGetLatestVersion) | latest version string |
| Function | Method | URL | Returns |
|---|---|---|---|
createApiKey(name) | POST | /api_key/ | created key data |
| Function | Method | URL | Returns |
|---|---|---|---|
getVerticesOrder(flowId, startNodeId?, stopNodeId?, nodes?, edges?) | POST | /build/{flowId}/vertices | AxiosResponse<VerticesOrderTypeAPI> |
postBuildVertex(flowId, vertexId, input_value, files?) | POST | /build/{flowId}/vertices/{vertexId} | AxiosResponse<VertexBuildTypeAPI> |
getVerticesOrder accepts optional start_component_id or stop_component_id as query params and an optional inline graph (nodes + edges) in the request body.
postBuildVertex sends inputs.input_value plus inputs.client_request_time (millisecond timestamp) and an optional files array.
| Function | Method | URL | Returns |
|---|---|---|---|
getStoreComponents({...}) | GET | /store/components/ + query string | StoreComponentResponse |
getComponent(component_id) | GET | /store/components/{component_id} | component data |
saveFlowStore(newFlow, tags, publicFlow) | POST | /store/components/ | FlowType |
updateFlowStore(newFlow, tags, publicFlow, id) | PATCH | /store/components/{id} | FlowType |
checkHasApiKey() | GET | /store/check/api_key | boolean |
checkHasStore() | GET | /store/check/ | boolean |
getStoreComponents accepts a rich set of optional filters and builds the query string manually before calling api.get:
component_id, search, private, tags, fields, sort, liked, filter_by_user, page, limit, is_component
Sources: src/frontend/src/controllers/API/index.ts1-307
Beyond the plain async functions, many API calls are wrapped in TanStack React Query hooks located in src/frontend/src/controllers/API/queries/. These hooks are referenced throughout the codebase but not present in index.ts. Examples observed in the source files:
| Hook | File hint | Mutation or Query |
|---|---|---|
useLoginUser | queries/auth | Mutation — POST /login |
useLogout | queries/auth | Mutation — POST /logout |
useRefreshAccessToken | queries/auth | Mutation — POST token refresh endpoint |
useGetUserData | queries/auth | Mutation — GET current user |
useGetUsers | queries/auth | Mutation — GET user list (admin) |
useAddUser | queries/auth | Mutation — POST new user |
useDeleteUsers | queries/auth | Mutation — DELETE user |
useUpdateUser | queries/auth | Mutation — PATCH user |
useGetGlobalVariablesMutation | queries/variables | Mutation — GET global variables |
These hooks use the same api Axios instance and follow the same interceptor pipeline.
Sources: src/frontend/src/controllers/API/api.tsx22-23 src/frontend/src/contexts/authContext.tsx8-9 src/frontend/src/pages/AdminPage/index.tsx5-9
The following diagram maps the major code entities and their relationships:
Sources: src/frontend/src/controllers/API/api.tsx1-368 src/frontend/src/controllers/API/index.ts1-307
The interceptor does not read tokens from state to set Authorization headers. Instead, the backend sets HttpOnly cookies on login, and the browser sends them automatically on every request. The withCredentials: true Axios option (set via getAxiosWithCredentials()) ensures cookies are forwarded on cross-origin requests.
When a 401/403 response is received, ApiInterceptor calls mutationRenewAccessToken (which hits the refresh endpoint) and then replays the failed request via remakeRequest. If refresh fails more than 3 times in succession, mutationLogout is called and the session is cleared.
Sources: src/frontend/src/controllers/API/api.tsx65-240 src/frontend/src/contexts/authContext.tsx67-125
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.