Remote Services
Remote Services is a catalog of the external HTTP and gRPC calls your workflows make. You register a service once, with its address, auth, and the calls it offers. Without additional configuration, these services can be reused across multiple workflows using built-in system tasks like HTTP, HTTP Poll, and gRPC.
When to use:
- Several workflows call the same service, and you want one place to change its address or auth.
- You want teammates to pick a call from a list instead of writing URLs and headers.
- You want the service's schemas registered, or a circuit breaker on it.
Use Remote Services for outbound calls from workflows. For a one-off call, use an HTTP task directly. Use API Gateway when external clients should call a workflow as an API. Use MCP Gateway when AI agents should call workflows as tools.
Here is an overview of how to use the service registry in Conductor workflows:
- Register a remote service.
- Discover or add endpoints.
- (Optional) Configure circuit breaker pattern.
- Test endpoints.
- Add services to workflows.
Register a service
A service holds the address of an external API, its type (HTTP or gRPC), and optional auth. The name must be unique and cannot be changed after the service is created.
Use the Create Service API or go to Definitions > Remote Services, select + New service, and enter the following parameters:
| Parameter | Description |
|---|---|
| name | A unique name for the service. |
| type | The type of service. Supported values: HTTP, gRPC. |
| serviceURI | The service address. For HTTP services, enter the Swagger specification URL, ending in .json. For example: https://petstore.swagger.io/v2/swagger.json. For gRPC services, enter the host and port in the format host:port. |
| servers.url (Optional) | An additional endpoint host. Conductor automatically discovers available hosts from the server during endpoint discovery, but you can add extra hosts here for testing. |
| servers.type (Optional) | The URL type. Supported values: OPENAPI_SPEC, USER_DEFINED. |
| authMetadata.key (Optional) | The HTTP header name, if the endpoint requires authorization. For example: Authorization. |
| authMetadata.value (Optional) | The HTTP header value, if the endpoint requires authorization. For example: Bearer |
The following is a sample JSON for a service:
{
"name": "petstore",
"type": "HTTP",
"serviceURI": "https://petstore.swagger.io/v2/swagger.json",
"servers": [
{
"url": "https://petstore.swagger.io/v2",
"type": "USER_DEFINED"
}
],
"authMetadata": {
"key": "Authorization",
"value": "Bearer <token>"
}
}
Discover or add endpoints
After registering a service, you can either automatically discover its endpoints or manually add them.
a. Discover endpoints
How you discover endpoints depends on the service type:
- HTTP: Conductor reads the Swagger specification.
- Depending on the gRPC configuration, you can:
- Discover endpoints automatically (if reflection is enabled in the gRPC server).
- Upload compiled proto descriptors (if reflection is disabled in the gRPC server).
To automatically fetch the endpoints within the services, use the Discover Service Endpoints API or open your service definition and select Discover methods.
For HTTP services, Conductor fetches all endpoints defined in the Swagger specification. The corresponding schemas are automatically registered under Schemas in Conductor.
To upload proto descriptors (gRPC with reflection disabled):
- Install protoc if not already installed.
-
Generate the compiled binary protobuf files using the
protocutility:
Then use the Upload Proto File API or open your service registry definition in Conductor, go to Proto Files, select + Upload Proto File, and upload the compiled.bin file.
Once uploaded, Conductor extracts and registers the services, making them ready for use in workflows.
b. Add endpoints
To add a new endpoint, use the Add Method to Service API or select + Add New Method from your service definition, enter the following endpoint parameters, and select Add.
View parameters
| Parameter | Description |
|---|---|
| operationName | The action or purpose of the endpoint. |
| description | A description of the endpoint. |
| methodName | The method name for the endpoint. |
| methodType | The method type for the service. Supported values:
|
| accept (HTTP only) | The accept header required by the server. Supported types:
|
| requestContentType (HTTP only) | The content-type of the request to the server. Supported types:
|
| responseContentType (HTTP only) | The content-type of the response from the server. Supported types:
|
| inputType | Select an input schema from existing schemas in Conductor. |
| outputType | Select an output schema from existing schemas in Conductor. |
| requestParams (HTTP only) Available since: v5.4.2 and later |
The request parameters for the endpoint. Each entry has name, type (for example, path), required, and schema. |
| deprecated | Set to true to mark the endpoint as deprecated. |
This saves the endpoint within the service definition.
The following is a sample JSON for an endpoint:
{
"operationName": "findPetsByStatus",
"description": "Finds pets by status",
"methodName": "/pet/findByStatus",
"methodType": "GET",
"accept": "application/json",
"requestContentType": "application/json",
"responseContentType": "application/json",
"inputType": "findPetsByStatus_Request",
"outputType": "findPetsByStatus_Response",
"requestParams": [
{
"name": "status",
"type": "query",
"required": true,
"schema": { "type": "array" }
}
],
"deprecated": false
}
Configure circuit breaker pattern for individual services
Circuit breaker patterns help prevent cascading failures by halting calls to unhealthy services, thus protecting the workflows.
The Circuit Breaker pattern has two circuit states:
- Closed - Normal operation state where all requests pass through normally.
- Open - Failure state where the requests fail fast, thus protecting the service.
To configure the circuit breaker pattern for a service, use the Create Service API or go to the Circuit Breaker Configuration tab in your remote service definition, toggle on Circuit Breaker Configuration, configure the following parameters, and select Save.
| Parameter | Description | Type |
|---|---|---|
| circuitBreakerEnabled | Enables the circuit breaker for the service. | Boolean. |
| config.circuitBreakerConfig. failureRateThreshold | The failure rate threshold is a percentage between 0 and 100; when the failure rate equals or exceeds this value, the circuit breaker opens to block further calls. Default is 50. For example, setting the threshold to 50 means the circuit will open when half of the calls fail. Set it to 0 to disable this behavior. |
Float. |
| config.circuitBreakerConfig. slidingWindowSize | The size of the sliding window, which is used to record the outcome of calls when the circuit breaker is closed. The value ranges between 1 and 1000. Default is 100. | Integer. |
| config.circuitBreakerConfig. minimumNumberOfCalls | The minimum number of calls required within a sliding window before the circuit breaker evaluates the error rate or slow call rate. The minimum value is 1, and the maximum value should not exceed the slidingWindowSize. Default is 100. For example, if this value is 10, then at least 10 calls must be recorded before the failure rate can be calculated. If only 9 calls have been recorded, the Circuit Breaker will not transition to open even if all 9 calls have failed. |
Integer. |
| config.circuitBreakerConfig. waitDurationInOpenState | The time in ms that the circuit breaker must wait before transitioning from open to half-open. The value ranges between 1000-300000. Default is 1000. | Integer. |
| config.circuitBreakerConfig. permittedNumberOfCallsInHalfOpenState | The number of calls allowed while the Circuit Breaker is in the half-open state. The value ranges between 1 and 100. Default is 100. | Integer. |
| config.circuitBreakerConfig. slowCallRateThreshold | The percentage threshold for calls classified as slow. A call is considered slow if its duration exceeds the slowCallDurationThreshold. If the percentage of slow calls within the sliding window equals or exceeds this threshold, the Circuit Breaker transitions to the open state and begins short-circuiting calls. The value ranges between 0 and 100. Set to 0 to disable slow-call triggering. Default is 50. |
Float/Decimal. |
| config.circuitBreakerConfig. slowCallDurationThreshold | The duration threshold (in ms) above which calls are considered slow. Calls exceeding this time increase the slow call rate. The value ranges between 1000-60000. Default is 100. | Integer. |
| config.circuitBreakerConfig. maxWaitDurationInHalfOpenState | The maximum wait duration (in ms) the circuit breaker can remain in the half-open state before transitioning back to the open state. A value of 0 means the circuit breaker will remain half-open indefinitely until all permitted calls are completed. The value can range between 1 and 300000. Default is 1. |
Integer. |
| config.circuitBreakerConfig. automaticTransitionFromOpenToHalfOpenEnabled | If set to true, the circuit breaker automatically transitions from the open state to the half-open state, and no call is required to trigger the transition. Enabled by default. If set to false, the transition to half-open occurs only when a call is made. |
N/A |
The following is a sample JSON for a service with the circuit breaker enabled:
{
"name": "petstore",
"type": "HTTP",
"serviceURI": "https://petstore.swagger.io/v2/swagger.json",
"circuitBreakerEnabled": true,
"config": {
"circuitBreakerConfig": {
"failureRateThreshold": 50,
"slidingWindowSize": 100,
"minimumNumberOfCalls": 10,
"waitDurationInOpenState": 5000,
"permittedNumberOfCallsInHalfOpenState": 10,
"slowCallRateThreshold": 50,
"slowCallDurationThreshold": 2000,
"maxWaitDurationInHalfOpenState": 1000,
"automaticTransitionFromOpenToHalfOpenEnabled": true
}
}
}
Test endpoints
Before you use an endpoint in a workflow, you can test it in the Orkes UI to check that it works.
To test an endpoint, go to Definitions > Remote Services and open your service. Select the test (▶) icon next to the endpoint, make the required configuration changes, and select Execute.
The test returns the server response and a link to the sample workflow execution that made the call. While testing the endpoints, you can also select the required host from the testing interface.
Add services to workflows
Once the services are registered, you can add them to HTTP, HTTP Poll, and gRPC tasks in your workflows.
Go to Definitions > Workflows, create a new workflow or select an existing one, and add an HTTP, HTTP Poll, or gRPC task. Select Populate from remote services and enter the following parameters:
| Parameter | Description |
|---|---|
| Service | The registered service. |
| Host | The required host for the service. |
| Service method | The required endpoint. |
Select Populate. This auto-populates the task parameters in the workflow.
Then configure the parameters specific to the task type:
- For HTTP Poll task: Configure the additional parameters such as Termination condition, Polling interval, and Polling strategy.
- For gRPC task: Enable/disable the fields Use SSL and Trust Certificate as per the requirement.
- For HTTP and gRPC task: In the Hedging config, set the Maximum attempts, which specifies the number of parallel requests the system should make when executing the task. The system returns the response from the first successful attempt, which helps reduce tail latencies for remote services. Hedging sends multiple parallel requests; hence, use this feature only with idempotent services to prevent unintended side effects from duplicate executions.
Note
A registered HTTP service can be reused across both HTTP and HTTP Poll tasks. Global service settings apply to both task types. However, circuit breaker configuration is applied only when the service is used with an HTTP task.
Examples
Call the Petstore API from a workflow
This example registers the public Petstore API, discovers its endpoints, and calls one of them from a workflow. The API calls use Orkes Developer Edition. If you use another cluster, replace https://developer.orkescloud.com with your cluster URL. Petstore is a shared public service, so the data it returns will differ from the sample below.
Get access token
The API calls in this example need an access token. Create an application with an access key, then exchange the key ID and secret for a JWT token:
curl -X POST 'https://developer.orkescloud.com/api/token' \
-H 'Content-Type: application/json' \
-d '{
"keyId": "<KEY_ID>",
"keySecret": "<KEY_SECRET>"
}'
The response contains the token. Use this token as <TOKEN> in the X-Authorization header of the calls below. Tokens expire, so request a new one if a call returns an authorization error.
1. Register the service
For an HTTP service, serviceURI must be the Swagger URL, ending in swagger.json. Discovery reads this URL, so a base URL such as https://petstore.swagger.io/v2 makes discovery fail.
curl -X POST 'https://developer.orkescloud.com/api/registry/service' \
-H 'X-Authorization: <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"name": "petstore",
"type": "HTTP",
"serviceURI": "https://petstore.swagger.io/v2/swagger.json"
}'
A 200 response means the service is registered.
2. Discover the endpoints
Set create=true to save the discovered endpoints on the service. Without it, the call only returns them.
curl 'https://developer.orkescloud.com/api/registry/service/petstore/discover?create=true' \
-H 'X-Authorization: <TOKEN>'
Conductor reads the Swagger file and registers 20 endpoints, such as findPetsByStatus, getPetById, and getInventory. It also registers the hosts it finds in the specification. This is the endpoint we will use:
{
"operationName": "findPetsByStatus",
"methodName": "/pet/findByStatus",
"methodType": "GET",
"outputType": "findPetsByStatus_Response",
"requestParams": [
{
"name": "status",
"type": "query",
"required": true,
"schema": { "type": "array" }
}
],
"description": "Multiple status values can be provided with comma separated strings",
"deprecated": false
}
3. Add the endpoint to a workflow
The workflow has one HTTP task. The task keeps the service name, which Conductor uses to apply the service's circuit breaker. The uri, method, accept, and contentType values come from the endpoint, and status=available is the query parameter.
curl -X POST 'https://developer.orkescloud.com/api/metadata/workflow' \
-H 'X-Authorization: <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"name": "petstore_pets",
"version": 1,
"schemaVersion": 2,
"tasks": [
{
"name": "http",
"taskReferenceName": "http_ref",
"type": "HTTP",
"inputParameters": {
"service": "petstore",
"uri": "http://petstore.swagger.io/v2/pet/findByStatus?status=available",
"method": "GET",
"accept": "application/json",
"contentType": "application/json"
}
}
]
}'
A 200 response means the workflow is registered.
4. Run the workflow and read the response
Start the workflow. The response is the workflow ID.
curl -X POST 'https://developer.orkescloud.com/api/workflow/petstore_pets' \
-H 'X-Authorization: <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{}'
Then get the execution using the workflow ID:
curl 'https://developer.orkescloud.com/api/workflow/<WORKFLOW-ID>?includeTasks=true' \
-H 'X-Authorization: <TOKEN>'
The workflow and the HTTP task have the status COMPLETED. The output of the HTTP task holds the status code and the response body:
{
"response": {
"statusCode": 200,
"body": [
{
"id": 566039,
"category": { "id": 566039, "name": "kangs name" },
"name": "doggie",
"photoUrls": [ "kangs url" ],
"tags": [ { "id": 566039, "name": "kangs tag 566039" } ],
"status": "available"
},
...
]
}
}
The body is the list of every pet with the status available. In this run it had 256 items.
Call a gRPC service from a workflow
This example registers the public grpcb.in test server, discovers its endpoints through server reflection, and calls its SayHello endpoint from a workflow. The API calls use Orkes Developer Edition. If you use another cluster, replace https://developer.orkescloud.com with your cluster URL.
Get access token
The API calls in this example need an access token. Create an application with an access key, then exchange the key ID and secret for a JWT token:
curl -X POST 'https://developer.orkescloud.com/api/token' \
-H 'Content-Type: application/json' \
-d '{
"keyId": "<KEY_ID>",
"keySecret": "<KEY_SECRET>"
}'
The response contains the token. Use this token as <TOKEN> in the X-Authorization header of the calls below. Tokens expire, so request a new one if a call returns an authorization error.
1. Register the service
For a gRPC service, serviceURI is the host and port, in the format host:port.
curl -X POST 'https://developer.orkescloud.com/api/registry/service' \
-H 'X-Authorization: <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"name": "grpcbin",
"type": "gRPC",
"serviceURI": "grpcb.in:9000"
}'
A 200 response means the service is registered.
2. Discover the endpoints
The server has reflection enabled, so Conductor can read its endpoints directly. Set create=true to save them on the service.
curl 'https://developer.orkescloud.com/api/registry/service/grpcbin/discover?create=true' \
-H 'X-Authorization: <TOKEN>'
Conductor registers 37 endpoints from the services on the server, such as hello.HelloService and grpcbin.GRPCBin. This is the endpoint we will use:
{
"operationName": "hello.HelloService",
"methodName": "SayHello",
"methodType": "UNARY",
"inputType": "hello.HelloRequest",
"outputType": "hello.HelloResponse",
"requestParams": [
{
"name": "greeting",
"type": "STRING",
"required": false
}
],
"exampleInput": {
"greeting": ""
},
"deprecated": false
}
3. Add the endpoint to a workflow
The workflow has one gRPC task. The service name links the task to the registered service. The method is the service name and the method name, hello.HelloService/SayHello. The input and output types come from the endpoint, and request holds the message to send.
curl -X POST 'https://developer.orkescloud.com/api/metadata/workflow' \
-H 'X-Authorization: <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"name": "grpcbin_hello",
"version": 1,
"schemaVersion": 2,
"tasks": [
{
"name": "grpc",
"taskReferenceName": "grpc_ref",
"type": "GRPC",
"inputParameters": {
"service": "grpcbin",
"methodType": "UNARY",
"method": "hello.HelloService/SayHello",
"host": "grpcb.in",
"port": 9000,
"request": { "greeting": "Conductor" },
"inputType": "hello.HelloRequest",
"outputType": "hello.HelloResponse",
"useSSL": false,
"trustCert": false
}
}
]
}'
A 200 response means the workflow is registered. Port 9000 on this server does not use TLS, so useSSL is false.
4. Run the workflow and read the response
Start the workflow. The response is the workflow ID.
curl -X POST 'https://developer.orkescloud.com/api/workflow/grpcbin_hello' \
-H 'X-Authorization: <TOKEN>' \
-H 'Content-Type: application/json' \
-d '{}'
Then get the execution using the workflow ID:
curl 'https://developer.orkescloud.com/api/workflow/<WORKFLOW-ID>?includeTasks=true' \
-H 'X-Authorization: <TOKEN>'
The workflow and the gRPC task have the status COMPLETED. The output of the gRPC task is the reply from the server: