Caddy — API Surface#

API types#

Caddy exposes four distinct API surfaces:

  1. REST/HTTP Admin API — runtime config management and introspection
  2. CLI — process lifecycle and tooling
  3. Plugin/Extension system — the primary surface for extensibility
  4. Library API — public Go interfaces for embedding or extending

REST/HTTP Admin API#

  • Router: net/http stdlib ServeMux wrapped in adminHandler
  • Listen address: localhost:2019 (default, overridable via CADDY_ADMIN env var or config)
  • Route registration: Hardcoded routes registered at startup in admin.go:newAdminHandler(); additional routes from modules in the admin.api namespace via the AdminRouter interface
  • Middleware chain: Single layer — host/origin enforcement, CORS checking, Prometheus metrics instrumentation, then dispatch to route handlers. Remote admin endpoint adds mutual TLS in front.
  • Authentication: Local endpoint: host/origin header verification (opt-in CORS enforcement). Remote endpoint: mutual TLS with certificate-based identity (IdentityConfig).

Core built-in endpoints#

PatternMethodsPurpose
/config/GET, POST, PUT, PATCH, DELETEConfig tree traversal and mutation — the primary admin interface. Path segments map to JSON keys.
/id/GET, POST, PUT, PATCH, DELETEAccess any config node by its @id tag (opaque handle across reloads)
/stopPOSTGraceful shutdown
/debug/pprof/GETGo pprof index
/debug/pprof/cmdlineGETProcess command line
/debug/pprof/profileGETCPU profile
/debug/pprof/symbolGETSymbol lookup
/debug/pprof/traceGETExecution trace
/debug/varsGETexpvar key/value dump

Module-registered endpoints (via admin.api namespace)#

Module IDPatternMethodsPurpose
admin.api.load/loadPOSTLoad a full config (JSON body)
admin.api.load/adaptPOSTAdapt config from non-JSON format (returns JSON)
admin.api.metrics/metricsGETPrometheus metrics exposition
admin.api.pki/pki/ca/<id>GETPKI CA info (roots, intermediates)
admin.api.pki/pki/casGETList all configured CAs
admin.api.reverse_proxy/reverse_proxy/upstreamsGETLive upstream health status

Extension point: Any module registered in the admin.api namespace that implements the AdminRouter interface (method Routes() []AdminRoute) gets its routes added to the admin mux at startup. This allows third-party modules to expose admin endpoints without modifying core code.


CLI#

  • Framework: github.com/spf13/cobra with a thin wrapper (caddycmd.Command struct and RegisterCommand() function)
  • Entry point: cmd/caddy/main.gocaddycmd.Main() → cobra root command dispatch

Command structure#

CommandFlagsPurpose
caddy run--config, --adapter, --envfile, --environ, --resume, --watch, --pidfileStart Caddy in foreground (daemon mode)
caddy start--config, --adapter, --envfile, --watch, --pidfileStart Caddy in background and return
caddy stop--config, --adapter, --addressGracefully stop via admin API /stop
caddy reload--config, --adapter, --address, --forcePOST new config to running instance via admin API /load
caddy adapt--config, --adapter, --pretty, --validate, --envfileConvert config to Caddy JSON; outputs to stdout
caddy validate--config, --adapter, --envfileProvision config (dry-run) to check for errors
caddy fmt--config, --overwrite, --diffFormat Caddyfile
caddy list-modules--packages, --versions, --skip-standard, --jsonList all registered modules
caddy build-infoPrint Go build metadata
caddy versionPrint version string
caddy environ--envfilePrint environment variables
caddy storage export--config, --outputExport TLS/storage as tarball
caddy storage import--config, --inputImport storage tarball
caddy upgrade--keep-backupDownload updated binary (EXPERIMENTAL)
caddy add-package--keep-backupAdd plugin packages to binary (EXPERIMENTAL)
caddy remove-package--keep-backupRemove packages from binary (EXPERIMENTAL)
caddy manpage--directoryGenerate man pages (section 8)
caddy completionbash|zsh|fish|powershellShell completion scripts

Flag patterns#

  • Global flags: None — all flags are per-command.
  • Config selection: --config (path) + --adapter (adapter name) appear on most commands.
  • Address override: --address on commands that contact the admin API (stop, reload) to handle non-default admin listen addresses.
  • Env injection: --envfile pre-loads KEY=VALUE pairs before config parsing; available on run/start/validate/adapt/environ.
  • Extension point: RegisterCommand(cmd Command) in cmd/commands.go allows third-party plugins to add new CLI subcommands from init() — same pattern as module registration. Command.CobraFunc gives access to the raw *cobra.Command for full cobra feature support.

Plugin / Extension System#

This is Caddy’s primary extensibility surface. Everything in Caddy is a module.

Core mechanism#

caddy.RegisterModule(m Module) // called from init()
caddy.GetModule(id string) (ModuleInfo, error)
caddy.GetModules(namespace string) []ModuleInfo

A module implements the Module interface:

type Module interface {
    CaddyModule() ModuleInfo  // returns ID + constructor
}

ModuleInfo.ID is a dotted namespace string (e.g. http.handlers.reverse_proxy). The namespace prefix determines where in the config JSON tree the module can appear, and which parent module will load it.

Extension namespaces#

NamespaceInterface to implementPurpose
http.handlers.*caddyhttp.MiddlewareHandlerHTTP request handlers (middleware)
http.matchers.*caddyhttp.RequestMatcherWithErrorHTTP route matchers
http.encoders.*(encoding module)Response body encoders (gzip, zstd)
http.authentication.providers.*(auth provider)HTTP Basic/bearer auth providers
http.authentication.hashes.*(hash module)Password hashing algorithms
http.ip_sources.*(IP source module)Client IP extraction strategies
http.precompressed.*(precompressed module)Pre-compressed file handling
http.reverse_proxy.*(load balancer / health check)Reverse proxy sub-components
tls.certificates.*caddytls.CertificateLoaderTLS certificate sources
tls.stek.*caddytls.SessionTicketServiceSession ticket key providers
tls.client_auth.*(client auth module)mTLS client auth verifiers
caddy.storage.*certmagic.StorageStorage backends for certs/data
caddy.logging.encoders.*caddy.LogEncoderLog format encoders
caddy.logging.writers.*caddy.WriterOpenerLog output destinations
caddy.listeners.*caddy.ListenerWrapperNetwork listener wrappers
caddy.filesystemsfs.FSFilesystem abstractions
caddy.config_loaders.*caddy.ConfigLoaderRuntime config sources (e.g. HTTP loader)
caddy.network_proxy.*(network proxy module)Network-level proxy control
admin.api.*caddy.AdminRouterAdmin HTTP API extensions
events.*caddyevents.EventHandlerEvent bus subscribers

Caddyfile directive registration#

Modules that want Caddyfile support register parsers:

// For directives that produce route config values:
httpcaddyfile.RegisterDirective(dir string, fn UnmarshalFunc)

// For directives that produce a MiddlewareHandler:
httpcaddyfile.RegisterHandlerDirective(dir string, fn UnmarshalHandlerFunc)

// For declaring directive ordering relative to other directives:
httpcaddyfile.RegisterDirectiveOrder(dir string, position Positional, relTo string)

Built-in Caddyfile directives registered at init: bind, tls, fs, root, vars, redir, respond, abort, error, route, handle, handle_errors, invoke, log, skip_log, log_skip, log_name.

Standard modules bundled in caddy binary#

HTTP handlers (18): file_server, reverse_proxy, rewrite, static_response, error, headers, encode, templates, authentication, authorization (caddyauth), map, vars, push, request_body, intercept, invoke, tracing, log_append, metrics, acme_server, copy_response, copy_response_headers

HTTP matchers (13): host, path, path_regexp, method, header, header_regexp, query, remote_ip, client_ip, protocol, tls, expression, vars, vars_regexp, file, not

TLS: ACME (HTTP-01, TLS-ALPN-01, DNS-01), OCSP stapling, session ticket rotation (standardstek, distributedstek), PKI CA with embedded ACME server

Storage: file_system (default on-disk)

Logging: console, json, filter encoders; stdout, stderr, discard, file, net writers


Library API#

Caddy is designed to be recompiled with custom modules rather than imported as a library, but it does expose public Go APIs:

Core package (github.com/caddyserver/caddy/v2)#

Key public types and functions:

  • caddy.RegisterModule(Module) — register a module (called from init())
  • caddy.Load(rawCfg []byte, forceReload bool) error — programmatic config load
  • caddy.Context — passed to modules during Provision(ctx); provides ctx.App(name), ctx.LoadModule(cfg, fieldName), ctx.Logger(), ctx.Filesystems()
  • caddy.Module, caddy.ModuleInfo, caddy.ModuleID — module identity types
  • caddy.App (Start() / Stop() error) — app lifecycle
  • caddy.Provisioner (Provision(Context) error) — module setup hook
  • caddy.Validator (Validate() error) — config validation hook
  • caddy.CleanerUpper (Cleanup() error) — module teardown hook

caddyhttp package#

  • caddyhttp.MiddlewareHandler — primary interface for HTTP handler modules
  • caddyhttp.RequestMatcherWithError — interface for request matcher modules
  • caddyhttp.Handler, caddyhttp.HandlerFunc — simplified handler types
  • caddyhttp.Middlewarefunc(Handler) Handler type alias
  • caddyhttp.GetVar(ctx, key) / caddyhttp.SetVar(ctx, key, val) — per-request variable store

API style#

The library API follows the module interface pattern: implement one or more lifecycle interfaces, call RegisterModule() in init(), import the package in a custom binary. There is no builder or fluent API for constructing Caddy configs in Go — the intended programmatic interface is the admin API over HTTP or JSON config construction.

Backward compatibility: Caddy uses semantic versioning (v2 module path). The Module interface and core registration functions are stable. Individual module JSON config schemas are treated as stable within a major version. The RequestMatcher interface is explicitly deprecated in favor of RequestMatcherWithError, showing the evolution path.