Single-source API declarations for self-describing Elixir functions.
The api macro is the sole source of truth for function documentation.
It generates @doc text, emits @doc hints: metadata for machine consumption,
validates param names at compile time, and produces __api__/0 and __api__/1
introspection functions.
Usage
defmodule MyLib.Funding do
use Descripex, namespace: "/funding"
api(:annualize, "Annualize a per-period funding rate to APR.",
params: [
rate: [kind: :value, description: "Per-period funding rate as decimal"],
period_hours: [kind: :value, default: 8, description: "Hours per period"]
],
returns: %{type: :float, description: "Annualized percentage rate (APR)"}
)
@spec annualize(number(), pos_integer()) :: float()
def annualize(rate, period_hours \\ 8), do: ...
endNo separate @doc block needed — the macro generates it from the declaration.
Introspection
MyLib.Funding.__api__()
# => [%{name: :annualize, arity: 2, ...}, ...]
MyLib.Funding.__api__(:annualize)
# => %{name: :annualize, arity: 2, param_order: [:rate, :period_hours], spec: "...", hints: %{...}}The param_order field lists the positional parameter names in declaration
order (including defaulted params). Consumers that dispatch named arguments
positionally — e.g. mapping MCP/JSON tool arguments onto
apply(module, fun, args) — must order arguments by param_order, not by
Map.keys(hints.params). The hints[:params] map discards declaration order,
so Map.keys/1 returns hash order and silently swaps multi-parameter calls.
param_order lists every declared positional param, including those with
defaults. A consumer that omits an optional argument must dispatch on the
function's lower arity rather than blindly mapping all of param_order — the
defaulted tail can be dropped from the right.
Summary
Functions
Return the list of modules registered with this library.
Build machine-readable hints map from an api declaration's description and options.
Return a Level 1 overview of all modules in this library.
Return Level 2 function list for a module (by full atom or short name).
Return Level 3 function detail (or nil if not found).
Enrich compile-time api entries with specs fetched at runtime.
Generate human-readable @doc text from an api declaration's description and options.
Functions
@spec __descripex_modules__() :: [module()]
Return the list of modules registered with this library.
Build machine-readable hints map from an api declaration's description and options.
@spec describe() :: [map()]
Return a Level 1 overview of all modules in this library.
Return Level 2 function list for a module (by full atom or short name).
Return Level 3 function detail (or nil if not found).
Enrich compile-time api entries with specs fetched at runtime.
Generate human-readable @doc text from an api declaration's description and options.