Skip to content

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

FieldTypeDefaultAllowed valuesDescription
tagstring(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.
listenstring127.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 | ReflectionServiceList 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.

ServicePurpose
HandlerServiceAdd/remove inbounds and outbounds at runtime.
LoggerServiceReopen log files (useful with logrotate).
StatsServiceRead counters published when stats is enabled.
ObservatoryServiceQuery the latency observer's latest results.
RoutingServiceTest routing decisions and reload rules.
ReflectionServiceStandard 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

  • tag cannot be empty — Build returns "API tag can't be empty." (infra/conf/api.go:23-25).
  • Pair api.services with a routing rule that catches inboundTag: ["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 metrics block — it exposes a plain HTTP endpoint without gRPC machinery.

Source: infra/conf/api.go:16-20 · v26.6.1 (94ffd50)

Core Tutorial by Argsment