FARP Registration API
This is the HTTP API exposed by the gateway's FARP handler (octopus-farp). Services use it to
register themselves, keep their registration alive with heartbeats, and deregister on shutdown.
The same handler serves the federated schemas (OpenAPI / AsyncAPI / GraphQL / gRPC) merged
from every registered service, plus Swagger UI and ReDoc.
For the concepts — how discovery, schema fetching, and route generation fit together — see Service Discovery & FARP and Schema federation.
Path prefixes01
The handler answers the same set of endpoints under several prefixes. The gateway rewrites each
prefix to a canonical /farp/... path before dispatching, so the endpoint behaviour is identical
whichever prefix you use:
| Prefix | Purpose |
/_farp/v1/... | Canonical FARP v1 push protocol. Preferred for service self-registration. |
/__/farp/... and /__farp/... | Internal management prefix. |
/farp/... | Backwards-compatible legacy prefix. |
In addition, the root paths /docs, /swagger, and /redoc are routed to the FARP
documentation UIs.
The endpoint tables below are written with the canonical /farp/... paths. To call them over
the v1 push prefix, swap /farp for /_farp/v1 — for example POST /_farp/v1/register.
Authentication02
The FARP endpoints are not authenticated by the handler itself. Treat them as internal: restrict access with network policy, run them on a non-public listener, or front them with an auth middleware. Do not expose registration to untrusted clients.
Service registration03
POST /farp/register
Register a service instance. The endpoint accepts two request shapes and picks the right one
by inspecting the JSON body: if it contains an instance field it is treated as a FARP v1 push
registration, otherwise it falls back to the legacy manifest form.
POST /farp/register
Content-Type: application/jsonPOST /farp/register
Content-Type: application/jsonThe manifest is validated against the FARP JSON schema before it is stored. An invalid manifest (missing required fields, a bad schema checksum, an unrecognised format) is rejected.
PUT /farp/heartbeat/{instance_id}
Keep a registered instance alive (FARP v1 push protocol). Send periodically from the service.
PUT /farp/heartbeat/user-service-7f9c
Content-Type: application/json{
"status": "up",
"routes_checksum": "a1b2c3d4..."
}routes_checksum is optional. When present, the gateway compares it against its own copy; if
they differ (or the gateway holds no schemas), it re-fetches the manifest so the two sides
reconcile.
Response — 200 OK:
{
"status": "ok",
"routes_checksum": "a1b2c3d4...",
"schemas_applied": 2
}If the gateway has no record of the instance — for example after a restart that lost in-memory
state — it returns 404 Not Found with a re-registration hint:
{
"error": "instance not found",
"action": "re-register",
"message": "Gateway has no record of this instance. Please re-register with full manifest."
}DELETE /farp/deregister/{instance_id}
Deregister a single instance by ID (FARP v1 push protocol). Send on graceful shutdown.
DELETE /farp/deregister/user-service-7f9cResponse — 200 OK:
{ "status": "deregistered" }Returns 404 Not Found ({"error": "instance not found"}) if the instance is unknown.
PUT /farp/services/{service_name}
Update an existing service registration with a new manifest (legacy form). The body is a manifest registration request; the manifest is validated before it replaces the stored one.
PUT /farp/services/user-service
Content-Type: application/json{
"manifest": {
"service_name": "user-service",
"service_version": "1.1.0",
"instance_id": "user-service-7f9c"
}
}Response — 200 OK:
{
"success": true,
"message": "Service 'user-service' updated successfully"
}DELETE /farp/services/{service_name}
Deregister a service by name (removes the whole service, not a single instance).
DELETE /farp/services/user-serviceResponse — 200 OK:
{
"success": true,
"message": "Service 'user-service' deregistered successfully"
}Service discovery04
GET /farp/services
List all registered services.
curl http://gateway:8080/__/farp/servicesResponse — 200 OK:
{
"services": [
{
"name": "user-service",
"version": "1.0.0",
"schema_count": 1,
"updated_at": "1699123456"
}
]
}updated_at is a Unix timestamp (seconds) as a string, and is omitted when unavailable.
GET /farp/services/{service_name}
Get the full record for one service — its manifest, stored schemas, and timestamps.
curl http://gateway:8080/__/farp/services/user-serviceResponse — 200 OK:
{
"service_name": "user-service",
"manifest": { "service_name": "user-service", "service_version": "1.0.0" },
"schemas": [],
"registered_at": 1699123456,
"updated_at": 1699123789
}Returns 404 Not Found if the service is not registered.
Federated schemas05
The gateway merges the schemas of all registered services into a single federated document per format. Structural merging applies to OpenAPI and AsyncAPI; GraphQL and gRPC are concatenated. See Schema federation for the merge behaviour and limits.
All of these read endpoints respond 200 OK. When no services are registered they return a valid
empty document rather than an error.
GET /farp/openapi.json
The merged OpenAPI document (application/json). When a router is wired in, gateway routes that
are missing from the federated spec are supplemented into it.
curl http://gateway:8080/__/farp/openapi.jsonGET /farp/asyncapi.json
The merged AsyncAPI document (application/json).
GET /farp/graphql
The merged GraphQL schema (text/plain).
GET /farp/grpc
The merged gRPC protobuf (text/plain).
GET /farp/schemas
List which federated formats are currently available and their source services.
{
"schemas": [
{
"format": "openapi",
"sources": ["user-service", "post-service"],
"updated_at": 1699123456
}
]
}GET /farp/schema/{format}
Fetch one federated schema by format. {format} is openapi, asyncapi, graphql, or grpc.
OpenAPI and AsyncAPI return application/json; GraphQL and gRPC return text/plain.
400 Bad Request—{"error": "invalid_format", ...}for an unknown format.404 Not Found—{"error": "not_found", ...}if that format has not been federated.
POST /farp/federate
Manually trigger federation of all registered service schemas.
curl -X POST http://gateway:8080/__/farp/federateResponse — 200 OK:
{
"success": true,
"message": "Schema federation completed",
"schemas_processed": 3,
"formats_generated": ["openapi", "asyncapi"],
"services": ["user-service", "post-service"]
}When there is nothing to federate it returns {"success": true, "message": "No schemas to federate", "schemas_processed": 0}.
Documentation UIs06
GET /farp/docs
Serves a Swagger UI page (HTML) pointed at the federated /farp/openapi.json. Also reachable at
the root path /docs (and /swagger).
GET /farp/redoc
Serves a ReDoc page (HTML) for the federated OpenAPI document. Also reachable at the root path
/redoc.
Errors07
Unmatched routes return 404 Not Found:
{
"error": "not_found",
"message": "Endpoint not found"
}Other failures (malformed JSON, an invalid manifest, a failed registration) return an error status with a message describing the cause.
Next steps08
Service Discovery & FARP — the protocol and discovery backends.
Schema federation — which formats generate routes and how merging works.
FARP configuration — enabling FARP and configuring discovery.
Admin REST API — the gateway's management API.