/v1/topologyGet topology#
Topology
The targets of the current configuration, their links as declared and as bound, readiness with its reasons, configuration revision and leases.
Responses
200The topology and its state.application/json
configrequiredstring
Current configuration revision.
environmentsrequiredarray of string
Environments.
policiesrequiredmap of EnvironmentPolicy
Policies of each environment.
EnvironmentPolicy · 2 fields
allow_draft requiredboolean
Whether draft packages are accepted.
human_orchestration one of HumanOrchestrationView | null
targetsrequiredarray of TargetView
Targets.
TargetView · 8 fields
namerequiredstring
Name.
platformrequiredstring
Platform, package@version.
environmentsrequiredarray of string
Environments where it can be engaged.
linksrequiredarray of LinkView
Links.
LinkView · 7 fields
namerequiredstring
Name.
defaultrequiredboolean
Whether it is the default link.
driverrequiredstring
Driver required: package@versions.
transportstring
Transport required, when the link has one: package@versions.
gatewayrequiredstring
Gateway required: an instance, or any(tag: …).
boundone of BoundView | null
availableboolean
Whether its gateway reports the link available (in pass, station in service).
readyboolean
Whether it can be engaged; None when the reconciler published nothing yet.
reasonsrequiredarray of string
Why it is not ready.
configstring
Configuration revision it runs with.
leaseone of LeaseView | null
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/topology"import requests
BASE_URL = "http://localhost:8080"
response = requests.get(f"{BASE_URL}/v1/topology")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/topology"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"config": "string",
"environments": [
"string"
],
"policies": {
"key": {
"allow_draft": true,
"human_orchestration": {
"identity": "string",
"hazardous_confirmation": [
null
],
"hazardous_requires_plan": true
}
}
},
"targets": [
{
"name": "string",
"platform": "string",
"environments": [
"string"
],
"links": [
{
"name": "string",
"default": true,
"driver": "string",
"transport": "string",
"gateway": "string",
"bound": null,
"available": true
}
],
"ready": true,
"reasons": [
"string"
],
"config": "string",
"lease": {
"runs": [
null
],
"shared": true
}
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/instancesList instances#
Instances
The drivers, transports, gateways, connectors and components registered with the reconciler, with their health and the links bound to them.
Responses
200Instances.application/json
instancesrequiredarray of InstanceView
Instances registered, drivers and gateways first.
InstanceView · 16 fields
kindrequiredstring
Kind: driver, gateway, or an MCS component.
instancerequiredstring
Instance name.
softwarerequiredstring
Software.
versionrequiredstring
Version.
registered_at requiredstring · date-time
Registration.
last_seen requiredstring · date-time
Last registration or heartbeat.
aliverequiredboolean
Whether heard within three heartbeat periods.
healthone of Health | null
reasonstring
Why degraded.
link_available boolean
For a gateway: whether its link is available.
cataloguestring
For a driver: catalogue implemented, name@version.
tagsrequiredarray of string
For a gateway: tags.
uplinkstring
For a gateway: uplink and downlink types and theoretical rates.
downlinkstring
Downlink.
framesstring
For a transport: what it frames and produces, csp1 → can.
boundrequiredarray of string
Links bound to it: <target>.<link>.
Request
curl "http://localhost:8080/v1/instances"import requests
BASE_URL = "http://localhost:8080"
response = requests.get(f"{BASE_URL}/v1/instances")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/instances"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"instances": [
{
"kind": "string",
"instance": "string",
"software": "string",
"version": "string",
"registered_at": "2026-09-29T08:30:00Z",
"last_seen": "2026-09-29T08:30:00Z",
"alive": true,
"health": "healthy",
"reason": "string",
"link_available": true,
"catalogue": "string",
"tags": [
"string"
],
"uplink": "string",
"downlink": "string",
"frames": "string",
"bound": [
"string"
]
}
]
}/v1/instances/{kind}/{instance}Get instance#
An instance
An instance, what it implements (a driver: catalogue coverage against the current configuration) or offers (a gateway: tags, link types and rates), its own status (the status verb), and the links bound to it with the consumers of their telecommands (delivered, pending, not acknowledged, redelivered).
Path parameters
kindrequiredstring
driver, transport, gateway, connector or a component of the MCS.
instancerequiredstring
Instance name.
Responses
200The instance.application/json
kindrequiredstring
Kind: driver, gateway, or an MCS component.
instancerequiredstring
Instance name.
softwarerequiredstring
Software.
versionrequiredstring
Version.
registered_at requiredstring · date-time
Registration.
last_seen requiredstring · date-time
Last registration or heartbeat.
aliverequiredboolean
Whether heard within three heartbeat periods.
healthone of Health | null
reasonstring
Why degraded.
link_available boolean
For a gateway: whether its link is available.
cataloguestring
For a driver: catalogue implemented, name@version.
tagsrequiredarray of string
For a gateway: tags.
uplinkstring
For a gateway: uplink and downlink types and theoretical rates.
downlinkstring
Downlink.
framesstring
For a transport: what it frames and produces, csp1 → can.
boundrequiredarray of string
Links bound to it: <target>.<link>.
heartbeat_period_ms requiredinteger · int64
Heartbeat period, in milliseconds.
public_key requiredstring
Public key of its nkey.
driverone of DriverDetail | null
gatewayone of GatewayDetail | null
statusone of Status | null
status_error string
Why the status could not be asked.
bindingsrequiredarray of BindingDetail
Links bound to it.
BindingDetail · 10 fields
targetrequiredstring
Target.
linkrequiredstring
Link.
driverrequiredstring
Driver bound.
transportstring
Transport bound, when the link has one.
gatewayrequiredstring
Gateway bound.
configrequiredstring
Configuration revision of the target.
config_current requiredboolean
Whether it is the current configuration.
encoderequiredstring
Subject of the telecommands to encode.
uplinkrequiredstring
Subject of the frames to uplink.
consumerone of ConsumerStats | null
404No such instance.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/instances/<kind>/<instance>"import requests
BASE_URL = "http://localhost:8080"
kind = "<kind>" # `driver`, `transport`, `gateway`, `connector` or a component of the MCS.
instance = "<instance>" # Instance name.
response = requests.get(f"{BASE_URL}/v1/instances/{kind}/{instance}")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let kind = "<kind>"; // `driver`, `transport`, `gateway`, `connector` or a component of the MCS.
let instance = "<instance>"; // Instance name.
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/instances/{kind}/{instance}"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"kind": "string",
"instance": "string",
"software": "string",
"version": "string",
"registered_at": "2026-09-29T08:30:00Z",
"last_seen": "2026-09-29T08:30:00Z",
"alive": true,
"health": "healthy",
"reason": "string",
"link_available": true,
"catalogue": "string",
"tags": [
"string"
],
"uplink": "string",
"downlink": "string",
"frames": "string",
"bound": [
"string"
],
"heartbeat_period_ms": 0,
"public_key": "string",
"driver": {
"codec": "string",
"catalogue": "string",
"catalogue_version": "string",
"telecommands": [
"string"
],
"measures": [
"string"
],
"missing_telecommands": [
"string"
],
"missing_measures": [
"string"
]
},
"gateway": {
"tags": [
"string"
],
"uplink": {
"link_type": null,
"rate_bps": null
},
"downlink": {
"link_type": null,
"rate_bps": null
}
},
"status": {
"bound": true,
"heartbeat": {
"health": null,
"link_available": true,
"reason": "string",
"sent_at": "string"
},
"instance": "string",
"kind": "string",
"software": {
"name": "string",
"version": "string"
},
"started_at": "string"
},
"status_error": "string",
"bindings": [
{
"target": "string",
"link": "string",
"driver": "string",
"transport": "string",
"gateway": "string",
"config": "string",
"config_current": true,
"encode": "string",
"uplink": "string",
"consumer": {
"name": null,
"delivered": null,
"pending": null,
"ack_pending": null,
"redelivered": null,
"last_active": null
}
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/instances/gateway/{instance}/throughputWatch throughput#
Throughput of a gateway (WebSocket)
The throughput reports of a gateway, per target, as it publishes them every metrics_period.
Path parameters
instancerequiredstring
Gateway instance.
Responses
101WebSocket: one ThroughputView per message.application/json
downlink_bps requirednumber · double
Mean downlink throughput over the window, in bits per second.
downlink_bytes requiredinteger · uint64
Bytes received from the target since the gateway started.
uplink_bps requirednumber · double
Mean uplink throughput over the window, in bits per second.
uplink_bytes requiredinteger · uint64
Bytes sent to the target since the gateway started.
window_ms requiredinteger · uint64
Length of the window, in milliseconds.
targetrequiredstring
Target.
atrequiredstring · date-time
Reception by the API.
404Invalid instance.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/instances/gateway/<instance>/throughput"import requests
BASE_URL = "http://localhost:8080"
instance = "<instance>" # Gateway instance.
response = requests.get(f"{BASE_URL}/v1/instances/gateway/{instance}/throughput")
response.raise_for_status()let base_url = "http://localhost:8080";
let instance = "<instance>"; // Gateway instance.
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/instances/gateway/{instance}/throughput"))
.send()
.await?
.error_for_status()?;Response
{
"downlink_bps": 0.0,
"downlink_bytes": 0,
"uplink_bps": 0.0,
"uplink_bytes": 0,
"window_ms": 0,
"target": "string",
"at": "2026-09-29T08:30:00Z"
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/targets/{target}/catalogueGet catalogue#
Catalogue of a target
The components of the platform of the target, their instances, measures (limits included) and telecommands (arguments, changes_state, hazardous), with their descriptions.
Path parameters
targetrequiredstring
Target, as named in the topology (sim-1).
Responses
200The catalogue.application/json
platformrequiredstring
Platform, package@version.
componentsrequiredarray of ComponentView
Components.
ComponentView · 5 fields
namerequiredstring
Name.
descriptionstring
Description, from the catalogue.
instancesrequiredarray of string
Instances of a multi-instance component.
measuresrequiredarray of MeasureView
Measures, derived ones included.
MeasureView · 7 fields
namerequiredstring
Name.
descriptionstring
Description, from the catalogue.
typerequiredstring
Type.
unitstring
Unit.
softarray of number · double
Soft limits, [low, high].
hardarray of number · double
Hard limits.
derivedrequiredboolean
Whether derived from other measures.
telecommandsrequiredarray of TelecommandView
Telecommands.
TelecommandView · 5 fields
namerequiredstring
Name.
descriptionstring
Description, from the catalogue.
argsrequiredarray of ArgumentView
Arguments.
ArgumentView · 7 fields
namerequiredstring
Name.
descriptionstring
Description, from the catalogue.
typerequiredstring
Type.
unitstring
Unit.
valuesrequiredarray of string
Values of an enum.
rangearray of number · double
Accepted range.
defaultstring
Value when omitted, as written.
changes_state requiredboolean
Whether it changes the on-board state.
hazardousrequiredboolean
Whether it needs a confirmation.
404Unknown target.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/targets/<target>/catalogue"import requests
BASE_URL = "http://localhost:8080"
target = "<target>" # Target, as named in the topology (`sim-1`).
response = requests.get(f"{BASE_URL}/v1/targets/{target}/catalogue")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let target = "<target>"; // Target, as named in the topology (`sim-1`).
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/targets/{target}/catalogue"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"platform": "string",
"components": [
{
"name": "string",
"description": "string",
"instances": [
"string"
],
"measures": [
{
"name": "string",
"description": "string",
"type": "string",
"unit": "string",
"soft": [
null
],
"hard": [
null
],
"derived": true
}
],
"telecommands": [
{
"name": "string",
"description": "string",
"args": [
null
],
"changes_state": true,
"hazardous": true
}
]
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/proceduresList procedures#
Procedures
The procedures of every library of the current configuration, with their roles, inputs, environments, maximum duration and whether they send a hazardous telecommand: what a run request needs.
Responses
200Procedures.application/json
proceduresrequiredarray of ProcedureView
Procedures of every library.
ProcedureView · 9 fields
namerequiredstring
Name.
descriptionstring
Description, from the library.
libraryrequiredstring
Library package: the library of a run request.
versionrequiredstring
Library version.
rolesrequiredarray of RoleView
Roles and their platform.
RoleView · 2 fields
namerequiredstring
Name.
platformrequiredstring
Platform package.
inputsrequiredarray of InputView
Inputs.
InputView · 5 fields
namerequiredstring
Name.
kindrequiredstring
value, file_id or content.
typestring
Type, or file type for file_id.
unitstring
Unit.
valuesrequiredarray of string
Values of an enum.
allowed_in requiredarray of string
Environments where it may run; empty when not restricted.
max_duration requiredstring
Longest duration.
hazardousrequiredboolean
Whether it sends a hazardous telecommand.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/procedures"import requests
BASE_URL = "http://localhost:8080"
response = requests.get(f"{BASE_URL}/v1/procedures")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/procedures"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"procedures": [
{
"name": "string",
"description": "string",
"library": "string",
"version": "string",
"roles": [
{
"name": "string",
"platform": "string"
}
],
"inputs": [
{
"name": "string",
"kind": "string",
"type": "string",
"unit": "string",
"values": [
null
]
}
],
"allowed_in": [
"string"
],
"max_duration": "string",
"hazardous": true
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/connectorsList connectors#
Output connectors
The output connectors of the topology, their instance, and the lag of each of their consumers computed now (messages not delivered, not acknowledged, age of the oldest, at risk of being removed by the retention).
Responses
200Connectors.application/json
connectorsrequiredarray of ConnectorView
Connectors of the topology.
ConnectorView · 5 fields
namerequiredstring
Name.
datarequiredarray of string
Kinds of data.
targetsrequiredarray of string
Targets.
instanceone of InstanceView | null
lagsrequiredarray of ConnectorLag
Lag of each consumer created.
ConnectorLag · 14 fields
activerequiredboolean
Whether a client is pulling the consumer now.
atrequiredstring
Computation.
at_risk requiredboolean
Whether the retention is about to remove messages the connector has not read.
connectorrequiredstring
Connector.
consumerrequiredstring
Durable consumer.
fillnumber · double
Filling of the stream against its max_bytes; None when not bounded by volume.
kindrequiredstring
Kind of data.
lag_seconds requirednumber · double
Age of that message, in seconds: 0 when the connector is up to date.
oldest_unread string
Storage of the oldest message not acknowledged, when there is one.
pendingrequiredinteger · uint64
Messages not delivered yet.
reasonstring
Why.
retention_seconds number · double
Maximum age of the stream, in seconds; None when not bounded by age.
streamrequiredstring
JetStream stream.
unackedrequiredinteger · uint64
Messages delivered and not acknowledged.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/connectors"import requests
BASE_URL = "http://localhost:8080"
response = requests.get(f"{BASE_URL}/v1/connectors")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/connectors"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"connectors": [
{
"name": "string",
"data": [
"string"
],
"targets": [
"string"
],
"instance": {
"kind": "string",
"instance": "string",
"software": "string",
"version": "string",
"registered_at": "2026-09-29T08:30:00Z",
"last_seen": "2026-09-29T08:30:00Z",
"alive": true,
"health": null,
"reason": "string",
"link_available": true,
"catalogue": "string",
"tags": [
null
],
"uplink": "string",
"downlink": "string",
"frames": "string",
"bound": [
null
]
},
"lags": [
{
"active": true,
"at": "string",
"at_risk": true,
"connector": "string",
"consumer": "string",
"fill": 0.0,
"kind": "string",
"lag_seconds": 0.0,
"oldest_unread": "string",
"pending": 0,
"reason": "string",
"retention_seconds": 0.0,
"stream": "string",
"unacked": 0
}
]
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/reconciler/eventsReconciler events#
Journal of the reconciler
The changes the reconciler made to the bindings of the links (bound, unbound, rebound) and to the readiness and revision of the targets, newest first.
Query parameters
targetstring
Only the changes of this target.
sincestring
Start of the window (RFC 3339); 24 h ago by default.
limitinteger
Newest entries returned: 200 by default, 5000 at most.
Responses
200The entries, newest first.application/json
eventsrequiredarray of Entry
Entries, newest first.
Entry · 9 fields
atrequiredstring · date-time
When the reconciler made the change.
targetrequiredstring
Target.
linkstring
Link, for a change of a link.
changerequiredWhat changed.
driverstring
Driver bound after the change.
transportstring
Transport bound after the change.
gatewaystring
Gateway bound after the change.
configstring
Configuration revision of the target after the change.
reasonsarray of string
Why, in the words of the readiness: the reasons of the target or of the link.
truncatedrequiredboolean
Whether older entries of the window were left out by the limit.
400Invalid query: api::invalid-query.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
404Invalid target: api::invalid-target.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/reconciler/events"import requests
BASE_URL = "http://localhost:8080"
response = requests.get(f"{BASE_URL}/v1/reconciler/events")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/reconciler/events"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"events": [
{
"at": "2026-09-29T08:30:00Z",
"target": "string",
"link": "string",
"change": "bound",
"driver": "string",
"transport": "string",
"gateway": "string",
"config": "string",
"reasons": [
"string"
]
}
],
"truncated": true
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/reconciler/events/watchWatch reconciler events#
Follow the journal of the reconciler (WebSocket)
Sends every change of the reconciler from now on.
Query parameters
targetstring
Only the changes of this target.
Responses
101WebSocket: one journal Entry per message.application/json
atrequiredstring · date-time
When the reconciler made the change.
targetrequiredstring
Target.
linkstring
Link, for a change of a link.
changerequiredWhat changed.
driverstring
Driver bound after the change.
transportstring
Transport bound after the change.
gatewaystring
Gateway bound after the change.
configstring
Configuration revision of the target after the change.
reasonsarray of string
Why, in the words of the readiness: the reasons of the target or of the link.
404Invalid target: api::invalid-target.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/reconciler/events/watch"import requests
BASE_URL = "http://localhost:8080"
response = requests.get(f"{BASE_URL}/v1/reconciler/events/watch")
response.raise_for_status()let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/reconciler/events/watch"))
.send()
.await?
.error_for_status()?;Response
{
"at": "2026-09-29T08:30:00Z",
"target": "string",
"link": "string",
"change": "bound",
"driver": "string",
"transport": "string",
"gateway": "string",
"config": "string",
"reasons": [
"string"
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}