Admin API

March 25, 2026 · View on GitHub

Aperture includes an optional admin gRPC and REST API for managing services, viewing transaction history, and monitoring revenue. When enabled, a web dashboard is also served at the root path.

Enabling

Add the admin section to your aperture.yaml:

admin:
  enabled: true
  macaroonpath: "/path/to/admin.macaroon"  # optional, defaults to ~/.aperture/admin.macaroon
  corsorigin:                               # optional, for cross-origin browser access
    - "http://localhost:3000"

Requirements:

  • Database backend: Must be sqlite or postgres (etcd does not support the transaction store needed by the admin API).
  • Authenticator: An LND or LNC connection is required for invoice creation and payment tracking.

On first startup, aperture generates a random 32-byte root key and an admin macaroon. The macaroon file is written to the configured macaroonpath (or ~/.aperture/admin.macaroon by default). The root key is stored alongside it at admin.rootkey.

Authentication

All admin API endpoints except GetHealth require a macaroon. For REST requests, pass it as a hex-encoded header:

ADMIN_MAC=$(xxd -ps -c 1000 /path/to/admin.macaroon)
curl -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" http://localhost:8081/api/admin/info

For gRPC, attach the macaroon as metadata with key macaroon.

REST Endpoints

The admin REST API is served under the /api/admin/ prefix via gRPC-gateway.

MethodPathAuthDescription
GET/api/admin/healthNoHealth check, returns {"status": "ok"}
GET/api/admin/infoYesServer info (network, listen address, insecure flag, MPP config)
GET/api/admin/servicesYesList all configured proxy services
POST/api/admin/servicesYesCreate a new service
PUT/api/admin/services/{name}YesUpdate an existing service (partial update)
DELETE/api/admin/services/{name}YesDelete a service
GET/api/admin/transactionsYesList L402 transactions (paginated, filterable)
GET/api/admin/tokensYesList active L402 tokens (settled transactions)
DELETE/api/admin/tokens/{token_id}YesRevoke an L402 token
GET/api/admin/statsYesRevenue statistics with optional date range

Service Management

Create a Service

curl -X POST \
  -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-api",
    "address": "127.0.0.1:8080",
    "protocol": "http",
    "host_regexp": ".*",
    "path_regexp": "^/api/v1/.*",
    "price": 100,
    "auth": "on"
  }' \
  http://localhost:8081/api/admin/services

Fields:

FieldRequiredDefaultDescription
nameYesUnique service name
addressYesBackend host:port
protocolNohttphttp or https
host_regexpNo.*Regex matching request Host header
path_regexpNoRegex matching request URL path. Must not match reserved paths (/api/admin/, /api/proxy/, /_next/).
priceNo0Price in satoshis per request
authNo""Auth level: on, off, or freebie N (N free requests per IP)
auth_schemeNoAUTH_SCHEME_L402Payment auth scheme: AUTH_SCHEME_L402 (0), AUTH_SCHEME_MPP (1), or AUTH_SCHEME_L402_MPP (2)

Update a Service

Partial updates — only provided fields are changed:

curl -X PUT \
  -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  -H "Content-Type: application/json" \
  -d '{"price": 250}' \
  http://localhost:8081/api/admin/services/my-api

Delete a Service

curl -X DELETE \
  -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  http://localhost:8081/api/admin/services/my-api

Services created or modified via the API are persisted to the database and survive restarts. They take precedence over services defined in the config file (matched by name).

Transactions

List Transactions

curl -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  "http://localhost:8081/api/admin/transactions?limit=20&offset=0&service=my-api&state=settled"

Query Parameters:

ParamDescription
limitMax results (1–1000, default 50)
offsetPagination offset
serviceFilter by service name
stateFilter by state: pending or settled
start_dateStart of date range (RFC 3339)
end_dateEnd of date range (RFC 3339)

Revoke a Token

TOKEN_ID=$(curl -s -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  http://localhost:8081/api/admin/tokens | jq -r '.tokens[0].token_id')

curl -X DELETE \
  -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  "http://localhost:8081/api/admin/tokens/$TOKEN_ID"

Revoking a token deletes the transaction record and revokes the underlying secret, forcing the client to obtain a new L402 on their next request.

Statistics

# All-time stats
curl -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  http://localhost:8081/api/admin/stats

# Date-filtered stats
curl -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  "http://localhost:8081/api/admin/stats?from=2026-03-01T00:00:00Z&to=2026-03-31T23:59:59Z"

Response:

{
  "total_revenue_sats": "2450",
  "transaction_count": "17",
  "service_breakdown": [
    {"service_name": "echo-api", "total_revenue_sats": "1200"},
    {"service_name": "premium-api", "total_revenue_sats": "1250"}
  ]
}

gRPC

The admin gRPC service is defined in adminrpc/admin.proto. Connect to the same listen address as the REST API. The gRPC endpoint prefix is /adminrpc.Admin/.

# Using grpcurl
grpcurl -plaintext \
  -H "macaroon: $(xxd -ps -c 1000 admin.macaroon)" \
  localhost:8081 adminrpc.Admin/GetInfo

MPP (Payment HTTP Authentication Scheme)

When enablempp: true is set in the authenticator config, Aperture supports the Payment HTTP Authentication Scheme alongside L402. The GetInfo endpoint reports MPP availability:

{
  "network": "regtest",
  "listen_addr": "localhost:8081",
  "insecure": true,
  "mpp_enabled": true,
  "sessions_enabled": false,
  "mpp_realm": "localhost:8081"
}

Per-Service Auth Scheme

Each service can be configured with a specific auth scheme via the auth_scheme enum field:

ValueEnum NameDescription
0AUTH_SCHEME_L402L402 only (default, backwards compatible)
1AUTH_SCHEME_MPPMPP Payment scheme only
2AUTH_SCHEME_L402_MPPBoth L402 and MPP (client chooses)

Example — create an MPP-only service:

curl -X POST \
  -H "Grpc-Metadata-Macaroon: $ADMIN_MAC" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "mpp-api",
    "address": "127.0.0.1:8080",
    "path_regexp": "^/api/mpp/.*",
    "price": 50,
    "auth": "on",
    "auth_scheme": 1
  }' \
  http://localhost:8081/api/admin/services

When auth_scheme is AUTH_SCHEME_L402_MPP, the 402 response includes both WWW-Authenticate: L402 and WWW-Authenticate: Payment headers, and the response body uses RFC 9457 Problem Details JSON.

Security

  • Macaroon auth: All endpoints except GetHealth require a valid admin macaroon.
  • Reserved path protection: Services cannot be created with path_regexp patterns that match /api/admin/, /api/proxy/, or /_next/ to prevent hijacking internal traffic.
  • CORS: Configurable via admin.corsorigin in the config file. If not set, cross-origin requests are blocked.