Skip to Content
✨ New: Plugin Support. Extend the core functionality with ease. Read more... 🎉
API Reference

API Reference

Complete reference for all functions, types, and interfaces.

Core Functions

createApiClient()

Creates a type-safe API client from endpoint definitions.

Signature:

function createApiClient<TEndpoints extends EndpointDefinitions>( endpoints: TEndpoints, config: ApiConfig ): Client<TEndpoints>

Parameters:

ParameterTypeDescription
endpointsTEndpointsObject mapping names to endpoint configs or groups
configApiConfigClient configuration object

Returns: Type-safe client with methods for each endpoint.

Example:

const api = createApiClient({ users: group({ endpoints: { list: get<void, User[]>('/users'), } }), }, { baseUrl: 'https://api.example.com', });

Helper Functions

get()

Creates a GET endpoint configuration.

Signature:

function get<TInput = void, TOutput = any, TError = any>( path: string | ((input: TInput) => string), handler?: CustomHandler<TInput, TOutput>, hooks?: Hooks ): EndpointConfig<TInput, TOutput, TError>

Parameters:

ParameterTypeRequiredDescription
pathstring | ((input: TInput) => string)YesStatic path or function returning path
handlerCustomHandler<TInput, TOutput>NoCustom request handler
hooksHooksNoEndpoint-specific hooks

Example:

const listUsers = get<void, User[]>('/users'); const getUser = get<{ id: string }, User>((input) => `/users/${input.id}`);

post()

Creates a POST endpoint configuration.

Signature:

function post<TInput, TOutput = any, TError = any>( path: string | ((input: TInput) => string), handler?: CustomHandler<TInput, TOutput>, hooks?: Hooks ): EndpointConfig<TInput, TOutput, TError>

Example:

const createUser = post<CreateUserInput, User>('/users');

put()

Creates a PUT endpoint configuration.

Signature:

function put<TInput, TOutput = any, TError = any>( path: string | ((input: TInput) => string), handler?: CustomHandler<TInput, TOutput>, hooks?: Hooks ): EndpointConfig<TInput, TOutput, TError>

Example:

const replaceUser = put<User, User>((input) => `/users/${input.id}`);

patch()

Creates a PATCH endpoint configuration.

Signature:

function patch<TInput, TOutput = any, TError = any>( path: string | ((input: TInput) => string), handler?: CustomHandler<TInput, TOutput>, hooks?: Hooks ): EndpointConfig<TInput, TOutput, TError>

Example:

const updateUser = patch<Partial<User> & { id: string }, User>( (input) => `/users/${input.id}` );

del()

Creates a DELETE endpoint configuration.

Signature:

function del<TInput = void, TOutput = any, TError = any>( path: string | ((input: TInput) => string), handler?: CustomHandler<TInput, TOutput>, hooks?: Hooks ): EndpointConfig<TInput, TOutput, TError>

Example:

const deleteUser = del<{ id: string }, void>((input) => `/users/${input.id}`);

endpoint()

Creates a generic endpoint configuration with full control.

Signature:

function endpoint<TInput = any, TOutput = any, TError = any>( config: EndpointConfig<TInput, TOutput, TError> ): EndpointConfig<TInput, TOutput, TError>

Example:

const searchUsers = endpoint<SearchInput, User[], ApiError>({ method: 'POST', path: '/users/search', handler: async ({ input, fetch, baseUrl, path }) => { const response = await fetch(`${baseUrl}${path}`, { method: 'POST', body: JSON.stringify(input), }); return response.json(); }, });

group()

Creates a group configuration for organizing related endpoints.

Signature:

function group<T extends GroupConfig>(config: T): T

Example:

const usersGroup = group({ hooks: { beforeRequest: async (url, init) => ({ url, init }), }, endpoints: { list: get<void, User[]>('/users'), }, groups: { posts: group({ endpoints: { list: get<{ userId: string }, Post[]>( (input) => `/users/${input.userId}/posts` ), } }), }, });

Plugin Functions

createPlugin()

Creates a plugin with proper typing.

Signature:

function createPlugin<TConfig = void>( factory: Plugin<TConfig> ): Plugin<TConfig>

Example:

export const loggingPlugin = createPlugin(() => ({ hooks: { beforeRequest: async (url, init) => { console.log(`→ ${init.method} ${url}`); return { url, init }; }, }, }));

Type Definitions

ApiConfig

Configuration for the API client.

type ApiConfig = { baseUrl: string; fetch?: typeof fetch; defaultHeaders?: HeadersInit; hooks?: Hooks; plugins?: PluginOptions[]; };

Properties:

PropertyTypeRequiredDescription
baseUrlstringYesBase URL for all requests
fetchtypeof fetchNoCustom fetch instance
defaultHeadersHeadersInitNoDefault headers for all requests
hooksHooksNoGlobal hooks
pluginsPluginOptions[]NoArray of plugins

EndpointConfig

Configuration for a single endpoint.

type EndpointConfig<TInput = any, TOutput = any, TError = any> = { method: HttpMethod; path: string | ((input: TInput) => string); hooks?: Hooks; handler?: CustomHandler<TInput, TOutput>; };

Properties:

PropertyTypeRequiredDescription
methodHttpMethodYesHTTP method
pathstring | ((input: TInput) => string)YesPath string or function
hooksHooksNoEndpoint-specific hooks
handlerCustomHandler<TInput, TOutput>NoCustom request handler

GroupConfig

Configuration for a group of endpoints.

type GroupConfig = { hooks?: Hooks; endpoints?: EndpointDefinitions; groups?: Record<string, GroupConfig>; };

Properties:

PropertyTypeRequiredDescription
hooksHooksNoGroup-level hooks
endpointsEndpointDefinitionsNoEndpoint definitions
groupsRecord<string, GroupConfig>NoNested groups

Hooks

Lifecycle hooks for requests and responses.

type Hooks = { beforeRequest?: ( url: string, init: RequestInit ) => Promise<{ url: string; init: RequestInit }> | { url: string; init: RequestInit }; afterResponse?: ( response: Response, url: string, init: RequestInit ) => Promise<Response> | Response; onError?: (error: unknown) => Promise<void> | void; };

Properties:

HookParametersReturnsDescription
beforeRequesturl: string, init: RequestInit{ url, init }Called before request
afterResponseresponse: Response, url: string, init: RequestInitResponseCalled after response
onErrorerror: unknownvoidCalled on error

CustomHandler

Custom handler function type.

type CustomHandler<TInput, TOutput> = (context: { input: TInput; fetch: typeof fetch; method: HttpMethod; path: string; baseUrl: string; }) => Promise<TOutput>;

Context Properties:

PropertyTypeDescription
inputTInputTyped input passed to endpoint
fetchtypeof fetchFetch instance (with hooks)
methodHttpMethodHTTP method
pathstringResolved path
baseUrlstringBase URL

PluginOptions

Options returned by plugin factory functions.

type PluginOptions = { hooks?: Hooks; handlerWrapper?: <TInput, TOutput, TError>( originalHandler: ( input: TInput, context: { fetch: typeof fetch; method: HttpMethod; path: string; baseUrl: string; } ) => Promise<TOutput>, endpoint: EndpointConfig<TInput, TOutput, TError> ) => ( input: TInput, context: { fetch: typeof fetch; method: HttpMethod; path: string; baseUrl: string; } ) => Promise<TOutput>; };

HttpMethod

Supported HTTP methods.

type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';

EndpointDefinitions

Map of endpoint names to configurations or groups.

type EndpointDefinitions = Record<string, EndpointConfig<any, any> | GroupConfig>;

Error Object Structure

When an endpoint throws an error, it has this structure:

{ status: number; // HTTP status code statusText: string; // HTTP status text error: TError; // Typed error response body }

Example:

type ApiError = { message: string; code: string }; try { await api.users.getById({ id: '123' }); } catch (err: unknown) { const error = err as { status: number; statusText: string; error: ApiError }; console.log(error.status); // 404 console.log(error.statusText); // "Not Found" console.log(error.error.code); // "USER_NOT_FOUND" }

Utility Functions

buildUrl()

Builds a complete URL from path and base URL.

Signature:

function buildUrl(path: string, baseUrl: string): string

Example:

import { buildUrl } from 'endpoint-fetcher'; const url = buildUrl('/users', 'https://api.example.com'); // Result: "https://api.example.com/users"

mergeHooks()

Merges multiple hook objects with proper priority.

Signature:

function mergeHooks(...hooksList: (Hooks | undefined)[]): Hooks

Example:

import { mergeHooks } from 'endpoint-fetcher'; const merged = mergeHooks( { beforeRequest: hook1 }, { beforeRequest: hook2 }, { afterResponse: hook3 } );

createEnhancedFetch()

Creates a fetch instance with hooks applied.

Signature:

function createEnhancedFetch( fetchInstance: typeof fetch, hooks: Hooks ): typeof fetch

Example:

import { createEnhancedFetch } from 'endpoint-fetcher'; const enhancedFetch = createEnhancedFetch(fetch, { beforeRequest: async (url, init) => ({ url, init }), });

isGroupConfig()

Type guard to check if config is a GroupConfig.

Signature:

function isGroupConfig( config: EndpointConfig | GroupConfig ): config is GroupConfig

Example:

import { isGroupConfig } from 'endpoint-fetcher'; if (isGroupConfig(config)) { // config is GroupConfig }

Constants

HTTP Methods

const methods = { GET: 'GET', POST: 'POST', PUT: 'PUT', PATCH: 'PATCH', DELETE: 'DELETE', } as const;

Type Utilities

Extract Endpoint Input Type

type ExtractInput<T> = T extends EndpointConfig<infer TInput, any, any> ? TInput : never;

Extract Endpoint Output Type

type ExtractOutput<T> = T extends EndpointConfig<any, infer TOutput, any> ? TOutput : never;

Extract Endpoint Error Type

type ExtractError<T> = T extends EndpointConfig<any, any, infer TError> ? TError : never;