API
The api block exposes a gRPC management surface that lets external tools (xray api ..., observability dashboards, dynamic-rule clients) talk to a running Xray instance. The block configures an internal inbound that the routing engine then needs to route to — typically via an inboundTag rule.
Options
| Field | Type | Default | Allowed values | Description |
|---|---|---|---|---|
tag | string | (required) | <inbound tag> | Tag used to expose the API inbound to the routing engine. A non-empty value is required; an empty tag is rejected at parse time. |
listen | string | 127.0.0.1:0 | <host:port> | Address the gRPC API listens on. If unset, an internal in-process inbound is registered instead of a TCP listener. |
services | []string | [] | HandlerService | LoggerService | StatsService | ObservatoryService | RoutingService | ReflectionService | List of API services to expose. Matched case-insensitively; unknown names are silently ignored. |
Source: infra/conf/api.go:16-20 · pinned at v26.6.1 (94ffd50)
Allowed services
The names in the services array are mapped to gRPC service registrations in APIConfig.Build (infra/conf/api.go:28-43). The mapping is case-insensitive — "HandlerService", "handlerservice" and "HANDLERSERVICE" are all accepted.
| Service | Purpose |
|---|---|
HandlerService | Add/remove inbounds and outbounds at runtime. |
LoggerService | Reopen log files (useful with logrotate). |
StatsService | Read counters published when stats is enabled. |
ObservatoryService | Query the latency observer's latest results. |
RoutingService | Test routing decisions and reload rules. |
ReflectionService | Standard gRPC reflection so generic clients can introspect. |
Examples
A minimal management endpoint with stats counters available:
json
{
"stats": {},
"api": {
"tag": "api",
"listen": "127.0.0.1:10085",
"services": ["HandlerService", "StatsService"]
},
"routing": {
"rules": [
{ "type": "field", "inboundTag": ["api"], "outboundTag": "api" }
]
}
}Notes
tagcannot be empty —Buildreturns"API tag can't be empty."(infra/conf/api.go:23-25).- Pair
api.serviceswith a routing rule that catchesinboundTag: ["api"]and forwards it to a same-tagged in-process outbound. Without that, the API is reachable on the listening port but the routing engine has no rule for the traffic. - For Prometheus-style scraping, prefer the
metricsblock — it exposes a plain HTTP endpoint without gRPC machinery.
Source: infra/conf/api.go:16-20 · v26.6.1 (94ffd50)
