Octopus
1.x
Docs/Octopus/FARP Registration API
Open

Reading8 min
Updated31 Jul 2026
Sourcev1/api-reference/farp.mdx

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:

PrefixPurpose
/_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.

Note

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.

http
POST /farp/register
Content-Type: application/json
Warning

The 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-7f9c

Response — 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-service

Response — 200 OK:

{
  "success": true,
  "message": "Service 'user-service' deregistered successfully"
}

Service discovery04

GET /farp/services

List all registered services.

curl http://gateway:8080/__/farp/services

Response — 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-service

Response — 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.json

GET /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/federate

Response — 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