Skip to main content

API Service

This document describes the REST API service for the E2E stack.


Terragraph's api_service provides a REST API for the E2E controller and NMS aggregator. The service translates HTTP/JSON requests into ZMQ/Thrift calls to the controller or aggregator, then returns the responses to the client JSON-encoded.

API Service is written in C++ using a Proxygen web server, and includes documentation generated from Javadoc-style annotations in the source code using apiDoc.


The service exposes three routes:

  • /api/: A comprehensive REST API for E2E services.
  • /api/stream/: A push API using server-sent events (SSE).
  • /docs/: Static API documentation.

The classes containing the request handlers and method definitions are shown in the table below.

RouteRequest HandlerMethod Definitions

API Responses

Upon success, every API method returns with status 200 OK and "Content-Type" header set to "application/json". A "success" response is sent if API service is able to translate the request and receive a response from the underlying service, regardless of whether the actual service endpoint returned a logic error.

The following HTTP error codes may also be returned:

  • 400 Bad Request - malformed request
  • 401 Unauthorized - missing or malformed authorization header (more details below)
  • 403 Forbidden - authorization failure (more details below)
  • 503 Service Unavailable - connection error to the underlying service, or request deserialization failure


API Service can perform permission enforcement and sender verification on its /api/ route using a public key. If a key is provided, each request must contain a signed JWT (JSON Web Token) in the "Authorization" HTTP header as follows:

Authorization: Bearer <token>

The token payload must contain a "roles" claim. Each role is effectively a permission, with the format <prefix><ApiCategory>_<ApiLevel>. A request is permitted only if any role meets the base permission level required by the endpoint.

API categories and levels are defined in Permissions.thrift. The category ALL is a special case representing all categories. Levels are defined in a hierarchy, such that a higher enum value implies all lower values (e.g. WRITE implies READ).


API Service creates a separate audit log for all "write" requests received. This log is written to /data/audit_logs/api_audit.log (or --audit_log_path, if provided). Each entry is a JSON object containing the endpoint, request body, and values from the authorization token.


Refer to src/terragraph-api/ for instructions on building the REST API documentation from the source files (listed below). The generated HTML files are checked into the apidoc/ directory.

Source Files

apiDoc collects data from the following places:

  • The method-level comments (@api) in ApiClient.cpp and StreamApiClient.cpp.
  • The imported parameter-level comments (@apiUse/@apiDefine) in all referenced .thrift files.
  • The ordering of methods specified in apidoc.json.


The example below describes the /api/getNodeConfig endpoint.


 1: /**
2: * @api {post} /getNodeConfig Get Node Config
3: * @apiName GetNodeConfig
4: * @apiPermission CONFIG_READ
5: * @apiGroup NodeConfiguration
6: *
7: * @apiDescription Retrieves the full configuration for the given node.
8: *
9: * @apiUse GetCtrlConfigReq
10: * @apiExample {curl} Example:
11: * curl -id '{"node": "terra111.f5.tb.a404-if", "swVersion": "RELEASE_M21"}' http://localhost:443/api/getNodeConfig
12: * @apiUse GetCtrlConfigResp_SUCCESS
13: * @apiSuccessExample {json} Success-Response:
14: * {
15: * "config": "{...}"
16: * }
17: */
2@api {[method]} /[apiPath] [Method Title]Method declaration/api is prepended to all paths
3@apiName [MethodName]Method nameNot rendered in HTML
4@apiPermission [PermissionName]Permission nameIf authorization is enabled, the minimum required permission level (excluding prefix)
5@apiGroup [CategoryName]Category nameTo render with spaces, declare elsewhere:
@apiDefine [CategoryName] [Name With Spaces]
7@apiDescription [Long method description.]Method descriptionAllows multi-line strings
9@apiUse [ApiDefineName{_GROUP}]Import an @apiDefine block by nameWrite all request fields here
10-11@apiExample {[type]} Example:
    [example command]
Request example-
12@apiUse [ApiDefineName_SUCCESS]Import an @apiDefine block by nameWrite all response fields here
13-16@apiSuccessExample {[type]} Success-Response:
    [example JSON response]
Response example-

Note that a block imported via @apiUse cannot @apiUse another block (i.e. nesting is not supported). All nested request parameters must be written in the method definition blocks.


 1: /**
2: * @apiDefine GetCtrlConfigReq
3: * @apiParam {String} node The node name
4: * @apiParam {String} [swVersion]
5: * The software version to use as the base config.
6: * If this is omitted, the controller will use the last version that
7: * the node reported; if no version is known to the controller, an
8: * error will be returned.
9: */
10: struct GetCtrlConfigReq {
11: 1: string node;
12: 2: optional string swVersion;
13: }
15: /**
16: * @apiDefine GetCtrlConfigResp_SUCCESS
17: * @apiSuccess {String} config The full node config (JSON)
18: */
19: struct GetCtrlConfigResp {
20: 1: string config;
21: }
2@apiDefine [ThriftName{_GROUP}]Block declarationUse the Thrift struct name (with optional _GROUP suffix for nested request parameters)
3, 4-8@apiParam (:[GroupName]) {[DataType]{=[enum]}} [field]{=[default]}
    [Long field description.]
Request parameterFor nested structs, add _GROUP suffix and (:Group) tag; for enumerations, fill in list of allowed values (comma-separated); for optional fields, wrap field name in square brackets []
16@apiDefine [ThriftName_SUCCESS]Block declarationUse the Thrift struct name (with mandatory _SUCCESS suffix for response parameters)
17@apiSuccess (:[GroupName]) {[DataType]{=[enum]}} [field]
    [Long field description.]
Response parameterSee @apiParam

Note that using groups (not to be confused with @apiGroup, which represents categories) is mandatory for nested Thrift structs. Otherwise, apiDoc will render the parameters for all structs in one combined block.


"order": [

The "order" property determines the order of the methods in the generated HTML files. Use method names as written in @apiName and category names as written in @apiGroup.


  • Proxygen - Meta's C++ HTTP libraries
  • apiDoc - Documentation generator for REST APIs