Traefik — API Surface#

API types#

Traefik exposes five distinct API surfaces:

  1. REST/HTTP management API — read-only introspection of live routing state
  2. CLI — startup, healthcheck, and version commands
  3. Middleware system — extensive built-in HTTP and TCP middleware catalog
  4. Plugin / Extension system — Yaegi (interpreted Go) and WASM plugins for middleware and providers
  5. Dynamic configuration interface — provider-based config (Docker labels, K8s CRDs, files, HTTP polling) — the primary operational surface

REST/HTTP API#

  • Router: github.com/gorilla/mux (pkg/api/handler.go:86)
  • Route registration: All routes registered manually in Handler.createRouter() at startup. No annotations, no code generation. Routes are hard-coded.
  • Middleware chain: None explicitly set on the API router; the API is served as a standard Traefik route through the regular pipeline (auth, IP allow-listing, etc. can be layered via dynamic config). The internal provider creates the API router and services.
  • Authentication: Not built into the API handler itself. Users secure the API by attaching auth middlewares (BasicAuth, ForwardAuth, IPAllowList) via dynamic config on the router pointing to the API service.
  • Base path: Configurable via static.Configuration.API.BasePath (defaults to empty — routes live at /api/...).

Key endpoints#

MethodPathHandlerDescription
GET/api/rawdatagetRuntimeConfigurationFull runtime config dump — all routers, services, middlewares for HTTP/TCP/UDP
GET/api/overviewgetOverviewSummary counts (experimental)
GET/api/support-dumpgetSupportDumpSupport bundle for debugging
GET/api/entrypointsgetEntryPointsList all entrypoints
GET/api/entrypoints/{entryPointID}getEntryPointSingle entrypoint detail
GET/api/http/routersgetRoutersList HTTP routers
GET/api/http/routers/{routerID}getRouterSingle HTTP router
GET/api/http/servicesgetServicesList HTTP services
GET/api/http/services/{serviceID}getServiceSingle HTTP service
GET/api/http/middlewaresgetMiddlewaresList HTTP middlewares
GET/api/http/middlewares/{middlewareID}getMiddlewareSingle HTTP middleware
GET/api/tcp/routersgetTCPRoutersList TCP routers
GET/api/tcp/routers/{routerID}getTCPRouterSingle TCP router
GET/api/tcp/servicesgetTCPServicesList TCP services
GET/api/tcp/services/{serviceID}getTCPServiceSingle TCP service
GET/api/tcp/middlewaresgetTCPMiddlewaresList TCP middlewares
GET/api/tcp/middlewares/{middlewareID}getTCPMiddlewareSingle TCP middleware
GET/api/udp/routersgetUDPRoutersList UDP routers
GET/api/udp/routers/{routerID}getUDPRouterSingle UDP router
GET/api/udp/servicesgetUDPServicesList UDP services
GET/api/udp/services/{serviceID}getUDPServiceSingle UDP service
GET/api/versionversion.Handler.AppendTraefik version info

Debug endpoints (when api.debug = true)#

Registered via DebugHandler.Append() (pkg/api/debug.go):

MethodPathDescription
GET/debug/varsGo expvar metrics (goroutine count, etc.)
GET/debug/pprof/pprof index
GET/debug/pprof/cmdlinepprof cmdline
GET/debug/pprof/profilepprof CPU profile
GET/debug/pprof/symbolpprof symbol lookup
GET/debug/pprof/tracepprof trace

Ping endpoint#

Registered separately from the main API, handled by pkg/ping/ping.Handler which implements http.Handler:

  • Path: /ping (on a configurable entrypoint, default: traefik)
  • Method: Any (responds to HEAD and GET)
  • Responses: 200 OK during normal operation; configurable non-200 status (TerminatingStatusCode) during graceful shutdown

Design note: The API is entirely read-only (all GET). There are no write endpoints — configuration is changed exclusively through providers. This is a deliberate design choice: the API is for observability, not control. The dashboard (pkg/api/dashboard/dashboard.go) is served from the same router using gorilla/mux.Router.PathPrefix to serve embedded web assets.


gRPC API#

Not present. The only .proto file in the repository (integration/helloworld/helloworld.proto) is an integration test fixture used to test gRPC-proxying capabilities — Traefik proxies gRPC traffic but does not expose a gRPC management API.


CLI#

  • Framework: Custom — github.com/traefik/paerser/cli (Traefik’s own CLI library, extracted from the main repo)
  • Command structure:
traefik                    # Main binary — starts the proxy
  healthcheck              # Checks liveness via the ping endpoint
  version                  # Prints version info
  • Command definition: Each command is a *cli.Command struct with Name, Description, Configuration (the typed config struct), and a Run function. Subcommands added via AddCommand().

  • Flag patterns:

    • Configuration struct fields are auto-exposed as flags via paerser’s reflection-based flag encoder (flag.Encode / flag.Decode)
    • Struct tags (description, json, toml, yaml, export) drive both documentation and serialization
    • Environment variable binding: TRAEFIK_<UPPERCASE_FLAG_PATH> — handled by EnvLoader
    • Config file (YAML/TOML): handled by FileLoader
    • Deprecation warnings for renamed flags: handled by DeprecationLoader
    • Loader precedence: DeprecationLoader → FileLoader → FlagLoader → EnvLoader
    • No global persistent flags — the config struct is passed through to all loaders

Middleware system (built-in)#

Traefik’s middleware catalog is the richest part of its operational API surface. All middlewares are referenced by name in dynamic config and constructed by pkg/server/middleware.Builder.BuildMiddlewareChain() using containous/alice for composition.

HTTP middlewares (pkg/middlewares/)#

MiddlewarePackageDescription
AddPrefixaddprefixPrepends a path prefix before forwarding
BasicAuthauthHTTP Basic authentication
DigestAuthauthHTTP Digest authentication
ForwardAuthauthDelegates auth to an external service
BufferingbufferingBuffers request/response bodies
ChainchainGroups multiple middleware into a named chain
CircuitBreakercircuitbreakerOpens circuit on error thresholds; uses gobreaker
CompresscompressResponse compression (gzip, brotli, zstd)
ContentTypecontenttypeAuto-detects Content-Type on responses
EncodedCharactersencodedcharactersHandles encoded characters in paths
CustomErrorscustomerrorsReturns custom error pages for configured status codes
GrpcWebgrpcwebTranslates gRPC-Web to gRPC for browser clients
HeadersheadersAdd/modify/remove request and response headers
IPAllowListipallowlistRestricts access by client IP
IPWhiteListipwhitelistDeprecated alias for IPAllowList
InFlightReqinflightreqLimits concurrent in-flight requests
PassTLSClientCertpasstlsclientcertPasses client TLS cert info as request header
RateLimiterratelimiterToken-bucket rate limiting per client
RedirectSchemeredirectForces HTTPS redirect
RedirectRegexredirectRegex-based URL redirect
ReplacePathreplacepathReplaces the request path
ReplacePathRegexreplacepathregexRegex-based path replacement
RetryretryRetries failed requests (up to N attempts)
StripPrefixstripprefixStrips a path prefix before forwarding
StripPrefixRegexstripprefixregexRegex-based prefix stripping
GatewayAPI: HeaderModifiergatewayapi/headermodifierGateway API header manipulation
GatewayAPI: Redirectgatewayapi/redirectGateway API redirect filter
GatewayAPI: URLRewritegatewayapi/urlrewriteGateway API URL rewrite filter
IngressNginx: RewriteTargetingressnginx/rewritetargetNginx-compat rewrite-target annotation
IngressNginx: AuthTLSPassingressnginx/authtlspasscertificatetoupstreamNginx-compat TLS cert passthrough
IngressNginx: Snippetingressnginx/snippetNginx-compat nginx.ingress.kubernetes.io/configuration-snippet

TCP middlewares (pkg/middlewares/tcp/)#

MiddlewarePackageDescription
InFlightConninflightconnLimits concurrent TCP connections
IPAllowListipallowlistRestricts TCP access by IP
IPWhiteListipwhitelistDeprecated alias for IPAllowList

Middleware composition#

Middleware chains are built via alice.Chain from github.com/containous/alice. Each middleware wraps http.Handler using the standard func(http.Handler) http.Handler constructor signature. Multi-type middleware configs are rejected at build time — each middleware name maps to exactly one type.


Plugin / Extension system#

This is the primary extensibility surface for third-party code.

  • Mechanism: Two runtimes, unified behind the same plugin descriptor format:

    • Yaegi (github.com/traefik/yaegi): Go source code interpreted at runtime. No compilation required, version-independent. For both middleware and provider plugins.
    • WASM (github.com/tetratelabs/wazero): WebAssembly modules. Language-agnostic (any language that compiles to WASM). For middleware plugins only.
  • Plugin types:

    • middleware — wraps HTTP handlers; implements the standard func(http.Handler) http.Handler signature at the yaegi/WASM boundary
    • provider — emits dynamic config; implements the Provider interface (via yaegi only)
  • Plugin manifest: Each plugin ships a .traefik.yml manifest declaring:

    • type (middleware | provider)
    • runtime (yaegi | wasm)
    • import (Go package path, for yaegi)
    • wasmPath (path to .wasm binary, for WASM)
    • displayName, summary, testData (required for catalog submission)
  • Plugin sources:

    • Remote: Downloaded from the Traefik plugin catalog (plugins.traefik.io) via pkg/plugins.Manager.InstallPlugin(). Pinned by module name + version + optional hash. Archives stored locally between restarts.
    • Local: Placed in ./plugins-local/<module-name>/. No version pinning.
  • Static config registration:

    experimental:
      plugins:
        my-plugin:
          moduleName: github.com/example/my-traefik-plugin
          version: v0.1.0
  • Builder wiring: pkg/plugins.Builder is created at startup by createPluginBuilder() in setupServer(). It is passed to both middleware.NewBuilder() (for plugin middlewares) and aggregator.NewProviderAggregator() (for plugin providers), behind the middleware.PluginsBuilder interface.

  • Extension points: Third-party code can hook in at:

    1. Middleware position in any router’s middleware chain (via plugin middleware)
    2. Provider position in the provider aggregator (via plugin provider, emitting dynamic.Message just like a built-in provider)
  • WASM sandbox: WASM plugins run in a wazero sandbox. The Settings struct allows opt-in exposure of environment variables (Envs), host directory mounts (Mounts), and unsafe syscall access (UseUnsafe).


Dynamic configuration interface (provider-based)#

While not an API in the traditional REST/gRPC sense, the provider interface is Traefik’s primary operational control plane — how operators tell it what to route and how.

ProviderMechanismHow users define config
DockerDocker Events API (push)Container labels (traefik.http.routers.*, etc.)
Kubernetes IngressK8s watchkubernetes.io/ingress.class annotation + standard Ingress spec
Kubernetes CRDsK8s watchIngressRoute, IngressRouteTCP, IngressRouteUDP, Middleware, TLSOption, etc.
Kubernetes Gateway APIK8s watchGateway, HTTPRoute, TCPRoute, GRPCRoute, etc.
ConsulConsul watchKV entries
etcdetcd watchKV entries
Fileinotify / pollingYAML or TOML config files (supports directory: for multi-file)
HTTPHTTP pollingJSON/TOML/YAML served by a remote URL
ECSAWS API pollingECS task labels
NomadNomad API watchNomad service tags
TailscaleTailscale APIAutomatic cert resolver per Tailscale host
InternalBuilt-in (no user config)Wires /api, /ping, /dashboard routes

All providers implement the same two-method interface:

type Provider interface {
    Init() error
    Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error
}

Config keys follow a consistent naming scheme: traefik.http.routers.<name>.rule, traefik.http.services.<name>.loadbalancer.server.port, etc. The same DSL works uniformly across Docker labels, K8s annotations, and file config — the config struct (pkg/config/dynamic) is the canonical schema.