Skip to main content

config_endpoint

ReferenceAudience: API consumerUse: add, update, or delete an MQTT endpoint configuration on the reader

Overview​

config_endpoint provisions the reader's MQTT endpoints — it adds, updates, or deletes an endpoint configuration (chosen by epConfig.operation). One payload defines an endpoint's type, protocol, broker url/port, TLS verificationType and certificates, MQTT keepAlive/session/reconnect settings, publish/subscribe topics, optional broker credentials, and per-endpoint event routing. It is a state-changing command on the device-management (MGMT) endpoint; the response is status-only. Read the result back with get_endpoint_config.

config_endpoint is state-changing and can carry broker credentials — and reconfiguring the endpoint that carries your own control session can sever it. See the session-sever callout in Notes and Caveats and the credential/TLS handling in Request Semantics. A saved endpoint is reversible with operation: delete.

Saving an endpoint does not connect it

An endpoint connects only when it is active. activate: false saves the endpoint; activate: true saves it and marks it active. With activate: true, the reader checks the endpoint’s parameters. If they are valid, it disconnects from the current configuration and connects to the new endpoint; no reboot is needed. Wait for a CONNECTED mqttConnEVT on the endpoint’s connection-state topic to confirm the connection. get_endpoint_config lists the endpoint under activeEndpoints as soon as it is stored as active, which does not show that it connected.

What happens when you add an endpoint with activate: true:

Diagram

Details​

PropertyValue
Interaction PatternRequest / Response (app publishes a command; device publishes the correlated reply)
State ChangeSTATE-CHANGING (writes/removes a saved endpoint; may activate it)
ReversibilityREVERSIBLE (remove with operation: delete; change with operation: update)
Supported Operationsadd (new), update (existing), delete (existing)
Required Request Fieldscommand, requestId, epConfig (with operation and configuration)
Applies ToEndpoint: Management (MGMT). Reader: RFD40 series, RFD90 series
API VersionV1.1 (API Version Reporting)
Relatedget_endpoint_config, config_events, install_certificate, reboot

When to Use​

Use config_endpoint to provision or maintain the reader's MQTT wiring after the initial MDM endpoint exists (that first endpoint is set up with 123RFID Desktop; all others are added remotely with config_endpoint).

  • add — create a new endpoint (MGMT, CTRL, DATA1, …). The endpointName must not already exist (duplicate → code 10).
  • update — modify an existing endpoint (e.g. change url, or flip activate). The endpointName must already exist.
  • delete — remove an existing endpoint (the contract's example sends only endpointName + epType).
  • Pre-provision safely — send activate: false to save an endpoint without activating it, then activate later with update. A saved endpoint does not connect until it is active.

Topic Mapping​

MessageDirectionTopicNote
RequestApp → Reader<tenantId>/MGMT/clients/cmnd/<serial>On the management endpoint.
ResponseReader → App<tenantId>/MGMT/clients/resp/<serial>Correlated reply; the in-payload requestId links the twin topics.

Topics follow the pattern <tenantId>/<topic>/<serial> — the tenant id assigned to you at provisioning (a slot you fill in, never a literal), the base topic you configure on the endpoint, and the reader's serial number, which the reader appends itself in its model-prefixed form (for example RFD40-212735201D0053). App → Reader means your app publishes and the reader subscribes; Reader → App means the reader publishes and your app subscribes.

The topic values you configure inside mqttParams are base topics (e.g. MGMT/clients/resp). The reader constructs the full topic at runtime as <tenantId>/<topic>/<serial> — never include the tenant or serial in topic.

Credentials are presented once at CONNECT (and, for a configured endpoint, via mqttParams). The requestId you send is echoed in the response so you can pair reply to request.

See Topics and Channels.

Key Fields​

  • epConfig.operation (request) — add / update / delete; determines the action.
  • configuration.endpointName (request) — the endpoint's identity (create target / update / delete key).
  • configuration.epType (request) — the endpoint's role (MGMT, CTRL, DATA1, …).
  • configuration.activate (request) — true saves the endpoint and marks it active, and the reader connects for it without a reboot if the parameters are valid; false only saves it.
  • configuration.securityParams (request) — for MQTT_TLS; the referenced certificates must be pre-installed via install_certificate.
  • response.code (response) — read this to determine success vs failure (see Response Codes).

Request Payload​

The envelope is command, requestId, and the epConfig payload (operation + configuration). Pick an operation / endpoint below; the Example and Schema update together. Use the Schema tab for the full field reference and the Example tab for the concrete payload.

Request payload
Example: add, MGMT, MQTT_TLS
{
"command": "config_endpoint",
"requestId": "1233",
"epConfig": {
"operation": "add",
"configuration": {
"endpointName": "mgmt_tls",
"epType": "MGMT",
"protocol": "MQTT_TLS",
"activate": true,
"url": "broker.ip.com",
"port": 8883,
"verificationType": "VERIFY_HOST_AND_PEER",
"qosCommon": 1,
"tenantId": "ZEBRA",
"mqttParams": {
"keepAlive": 300,
"cleanSession": true,
"reconnectDelayMin": 5,
"reconnectDelayMax": 60,
"publishTopics": [
{
"topic": "MGMT/clients/resp",
"qos": 1,
"retain": false
},
{
"topic": "MGMT/clients/event",
"qos": 1,
"retain": false
},
{
"topic": "MGMT/clients/rfid",
"qos": 0,
"retain": true
}
],
"subscribeTopics": [
{
"topic": "MGMT/clients/cmnd",
"qos": 0
}
]
},
"securityParams": {
"format": "PEM",
"caCertificateFile": "mqtt_ca_cert",
"clientCert": "mqtt_client_cert",
"clientKey": "mqtt_client_key"
}
}
}
}

Request Semantics​

Modes. epConfig.operation selects the action. The contract requires the same seven configuration fields for every operation — endpointName, epType, protocol, activate, url, verificationType and port — but its own delete example sends only endpointName and epType, and its update example omits verificationType and port. A validator built strictly from the contract rejects both examples; this is a known issue in the source schema:

  • add — creates a new endpoint. Supply the full configuration (the 7 fields add requires — endpointName, epType, protocol, activate, url, verificationType, port — plus optional mqttParams / securityParams / eventConfiguration). Fails with code 10 if the endpointName already exists.
  • update — modifies an existing endpoint (matched by endpointName). The contract's example sends endpointName and epType plus the fields being changed.
  • delete — removes an existing endpoint. The contract's example sends only endpointName and epType.

add is not idempotent. If a response is lost (e.g. a timeout), the endpoint may already have been created — read back with get_endpoint_config before retrying rather than blindly re-sending, or the retry will be a duplicate add.

  • Payloads can carry broker credentials. mqttParams.username / password are supplied in the request when the broker requires them — masked in the example on this page. Redact them in logs, tickets, and screenshots, and send config_endpoint only over secured channels. (Certificate fields — caCertificateFile / clientCert / clientKey — are reference names of already-installed certificates, not key material.)
  • Optional MQTT connection fields. mqttParams.clientId sets the MQTT client ID used for the broker connection; cleanSession defaults to true.
  • TLS needs pre-installed certificates. For protocol: MQTT_TLS, the securityParams caCertificateFile / clientCert / clientKey must reference certificates already installed via install_certificate. Only format: PEM is supported today. The protocol literal is spelled MQTT_TLS in both directions — one enum governs the request and the get_endpoint_config read-back — so send and match it exactly.
  • Topic slots are positional. publishTopics accepts at most 3 entries (exceeding → code 25) and subscribeTopics at most 1 (exceeding → code 26); both arrays are optional — the contract's own DATA1 read-back returns subscribeTopics: []. The three publish slots carry command responses (…/clients/resp), events — heartbeat, alerts (…/clients/event), then the endpoint's connection-event topic (…/clients/rfid, which carries mqttConnEVT); subscribeTopics[0] is command ingress, where the host publishes and the reader subscribes (…/clients/cmnd). Position is what routes — the reader binds each entry by index, not by base name — so keep the configured order, leave omitted indices unused, and match a get_endpoint_config read-back by index rather than by topic name. Configure only the base topic; the reader wraps it as <tenantId>/<topic>/<serial>.
  • DATA endpoints: put the tag-data topic at publishTopics[1]. On epType DATA1 the reader streams tag data from the second publish entry (DATA2 is currently not supported), so configure an unused placeholder at [0] and the tag-data topic (e.g. DATA/clients/data1event) at [1]: [{ "topic": "DATA/clients/unused", "qos": 0, "retain": false }, { "topic": "DATA/clients/data1event", "qos": 1, "retain": false }]. Every DATA1 example on this page uses this two-entry layout. A single-entry array is the trap: the one entry lands in the reply slot, the add still succeeds, and no tag data ever arrives. A read-back showing activate: true shows only that the endpoint is stored as active; it does not show that the endpoint connected or that tag data is flowing.
  • verificationType: use VERIFY_HOST_AND_PEER. It verifies the broker's certificate chain and that the certificate matches the host. VERIFY_NONE turns verification off; use it only on an isolated test network, and never on an MQTT_TLS endpoint, which rejects it with code 37. get_endpoint_config reads back the value you sent, so a client doing read-modify-write can echo it.
  • Event routing. configuration.eventConfiguration uses the same shape as config_events; only 7 of its toggles are functional today (the rest are reserved). See the Event routing fields table on the get_endpoint_config page for the full supported-vs-reserved split.

Topic slots by epType. How the positional layout above lands per endpoint type. The contract's examples show the command/response layout; the data-endpoint layout (†) is firmware guidance that the contract does not state:

epTypepublishTopics[0]publishTopics[1]publishTopics[2]subscribeTopics[0]
MGMT · MDMcommand responses (…/resp)events (…/event)connection events (…/rfid)command ingress (…/cmnd)
CTRLcommand responses (…/resp)stored, not used for eventsconnection events (…/rfid)command ingress (…/cmnd)
MGMT_EVTnot usednot usedLast Willevents are currently published here (a firmware defect)
DATA1unused placeholder †tag-data stream (…/data1event) †—— (does not subscribe)

The command/response endpoints (MGMT, MDM, CTRL) share the [0] and [2] layout; on CTRL, slot [1] is stored but not used for events. A MGMT_EVT endpoint currently publishes its events on its subscribe topic instead of publishTopics[1], which the API owners record as a firmware defect; see Endpoints and Topic Slots. Match read-back entries by index, not by base name — the resp / event / rfid names are conventions.

† Tag data binds to publishTopics[1], so a data endpoint needs a throwaway entry at [0] to push the real topic into slot [1] — see the DATA-endpoint bullet above.

Response Payload​

config_endpoint returns a status-only envelope — command, requestId, apiVersion, and response. There is no configuration echo; confirm the change with get_endpoint_config.

Response payload
{
"command": "config_endpoint",
"requestId": "abc123",
"apiVersion": "V1.1",
"response": {
"code": 0,
"description": "Success"
}
}

Response Codes​

config_endpoint returns response.code. The codes applicable to this command are below; for the full table see the Response Codes and Correlation and Request/Response Pairing.

CodeDescription
0Success — the endpoint was added, updated, or deleted.
10Configuration already exists (IOT_ERROR_CONFIG_ALREADY_EXIST) — an add used an endpointName that already exists. Use update, or delete it first.
23Invalid enum value (IOT_ERROR_INVALID_ENUM) — a field (e.g. operation, epType, protocol, verificationType, format) is outside its allowed set.
25Max 3 publish topics exceeded (IOT_ERROR_PUBLISH_TOPICS_EXCEEDED) — more than 3 publishTopics.
26Max 1 subscribe topic exceeded (IOT_ERROR_SUBSCRIBE_TOPIC_EXCEEDED) — more than 1 subscribeTopics.
27Invalid tenant ID length (IOT_ERROR_INVALID_TENANTID_LENGTH) — tenantId exceeds the allowed length.
33Endpoint already configured (IOT_ERROR_ENDPOINT_ALREADY_CONFIGURED) — an endpoint with the same configuration already exists.
35Can't modify an active endpoint (IOT_ERROR_CANT_MODIFY_ACTIVE_ENDPOINT) — the target endpoint is currently active. Deactivate it before modifying it.
37Invalid verification type for MQTT TLS (IOT_INVALID_MQTT_TLS_VERIFICATION_TYPE) — protocol: MQTT_TLS was sent with verificationType: VERIFY_NONE. Use VERIFY_HOST_AND_PEER.
101Default error — generic catch-all. See the duplicate-add note below.

Duplicate add may return the generic 101. The documented code for adding an endpointName that already exists is 10 ("Configuration already exists"), but the firmware has been observed returning the generic 101 ("Default error") for a duplicate add instead of 10. Treat a 101 after a re-sent add as a probable duplicate and verify with get_endpoint_config.

Examples​

Publish a config_endpoint request; the device replies with the status-only envelope under Response Payload. Every contract example — each add, the delete and the partial update — is in the Operation / endpoint dropdown under Request Payload. The examples below show what the dropdown does not.

A plain-MQTT DATA1 add with broker credentials (activate: true), the tag-data topic at publish slot [1] with an unused placeholder at [0] — the layout the firmware guidance under Request Semantics describes — and no TLS:

Request — add (plain MQTT, with credentials)
{
"command": "config_endpoint",
"requestId": "abc123",
"epConfig": {
"operation": "add",
"configuration": {
"endpointName": "dataEP",
"epType": "DATA1",
"protocol": "MQTT",
"activate": true,
"url": "broker.example.com",
"verificationType": "VERIFY_NONE",
"port": 1883,
"qosCommon": 1,
"tenantId": "zebra",
"mqttParams": {
"keepAlive": 300,
"cleanSession": true,
"reconnectDelayMin": 50,
"reconnectDelayMax": 500,
"username": "********",
"password": "XXXXXXXX",
"publishTopics": [
{
"topic": "DATA/clients/unused",
"qos": 0,
"retain": false
},
{
"topic": "DATA/clients/data1event",
"qos": 1,
"retain": false
}
]
}
}
}
}

A duplicate add returns code 10 (or, on some firmware, the generic 101 — see the note above):

Response — duplicate add (code 10)
{
"command": "config_endpoint",
"requestId": "abc123",
"apiVersion": "V1.1",
"response": {
"code": 10,
"description": "Configuration already exists"
}
}

Notes and Caveats​

Reconfiguring the active control endpoint can sever your session

Activating a new endpoint of a different role coexists with the endpoint carrying your control session (e.g. activating a DATA1 endpoint does not drop the MDM/MGMT control channel). But changing the broker url/port/protocol of — or deleting — the endpoint that carries your own control session can sever it. When in doubt, save with activate: false and switch deliberately.

Because the response is status-only, verify the result with get_endpoint_config — confirm the endpoint appears in savedEndpoints.epNames[] and (if activate: true) under activeEndpoints. A CONNECTED mqttConnEVT on the endpoint’s connection-state topic confirms that it connected. For the concept-level view, see Endpoints and Topic Slots.

Related: 📕 Endpoints and Topic Slots · 📕 get_endpoint_config · 📕 config_events · 📕 install_certificate · 📕 Response Codes

Was this helpful?