Data Delivery: Output Profiles
MQcentral separates two distinct concepts that are often confused: Applications are OAuth2 service accounts for API access; Output Profiles are the mechanism for routing device data to downstream systems. This page covers Output Profiles. For creating and managing API service accounts, see Applications.
An output profile defines how device data is delivered to a downstream system. Each output profile contains one or more delivery targets: REST/webhook, MQTT, AWS IoT Core, or Azure IoT Hub. The profile is then assigned to one or more devices.
Output profiles are the primary data routing mechanism in MQcentral. A device without an output profile still receives and decodes uplinks, but no data is pushed to external systems.
Important: Every delivery target (REST, MQTT, AWS, Azure) accepts an optional
Environmentfield with valuesproduction,staging, ordevelopment. Always set this; it tells MachineQ's engineering and operations teams the criticality of the destination, which determines the level of support provided if delivery issues arise. It also makes it easy to distinguish endpoints across environments in the console.
Before You Begin
You need:
- An MQcentral account with the following permissions (see Roles for details):
- CRU permissions for device administration, and
- CRU permissions for user administration.
$MQ_TOKENexported from the authentication step. See Authentication & API Access.- For output profile assignment: at least one device provisioned. See Device Onboarding & Lifecycle.
Creating an Output Profile
An output profile is created by sending a request to POST /v1/outputprofiles with a Name and at least one delivery target. The delivery target you include determines how MachineQ pushes data to your system. There are four options:
| Delivery Type | Use When |
|---|---|
| REST / Webhook | You have an HTTP endpoint that can receive JSON payloads. Simplest to set up; works with any backend that can handle incoming HTTP requests. |
| MQTT | You run an MQTT broker (e.g. Mosquitto, HiveMQ, EMQX) and want pub/sub delivery with topic-based routing. |
| AWS IoT Core | You're building on AWS and want device data delivered directly into IoT Core using X.509 certificate authentication. |
| Azure IoT Hub | You're building on Azure and want device data delivered as IoT Hub device-to-cloud messages using shared access policies. |
Each delivery type is configured by including its corresponding params block (RestParams, MqttParams, AWSParams, or AzureParams) in the request body. You can include multiple entries in each array to deliver to more than one destination of the same type, and you can combine different types in a single profile.
Pick the delivery type that matches your infrastructure and continue to the corresponding section below.
REST / Webhook Delivery
Include a RestParams array to push payloads to an HTTP endpoint. Each entry in the array represents a separate webhook destination; you can deliver to multiple endpoints from a single output profile.
Minimal Example
At minimum, provide the destination URL and an OutputFormat:
curl -sS -X POST https://api.machineq.net/v1/outputprofiles \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Name": "warehouse-webhook",
"RestParams": [
{
"URL": "https://api.example.com/lorawan/events",
"OutputFormat": "extended"
}
]
}' | jq
Recommendation: Use
extendedfor OutputFormat. It delivers a rich JSON payload including decoded data, multi-gateway reception details, geolocation, battery level, and LoRaWAN control flags. Thesimpleformat delivers a compact, flat structure with the raw hex payload and basic RF metadata (RSSI, SNR, frequency), but omits decoded payloads and multi-gateway information.
Authenticated Webhook
If your endpoint requires authentication, add TokenType and TokenValue. MachineQ will include an Authorization header on every delivery:
curl -sS -X POST https://api.machineq.net/v1/outputprofiles \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Name": "warehouse-webhook",
"RestParams": [
{
"URL": "https://api.example.com/lorawan/events",
"OutputFormat": "extended",
"TokenType": "Bearer",
"TokenValue": "<your-token>",
"Environment": "production",
"Active": true
}
]
}' | jq
The resulting HTTP request from MachineQ to your endpoint will include the header:
Authorization: Bearer <your-token>
Best Practices for the Access Token
The TokenValue you provide here is stored by MachineQ and sent with every delivery. Because webhook output profile are long-lived, the token you use needs to be as well. A few approaches:
- Static API Key: Generate a long-lived, random API key (e.g. a 256-bit hex string) on your server and validate it on incoming requests. This is the simplest approach and avoids token expiration entirely. Most webhook receivers work this way.
- Rotate when needed: If your token does expire, update the output profile with a new
TokenValuevia aPUTbefore the old one lapses. You can automate this with a cron job or scheduled task that refreshes the token and updates the output profile.
Avoid using short-lived user session tokens. If the token expires, MachineQ deliveries will begin failing with
401responses and data will be lost.
| Field | Required | Description |
|---|---|---|
URL |
Yes | Full HTTP URL including scheme (e.g. https://). Must be reachable from the public internet. |
OutputFormat |
Yes | simple or extended (extended recommended). |
TokenType |
No | Token type for the Authorization header (e.g. Bearer, Basic, Token). |
TokenValue |
No | Token value sent alongside TokenType in the Authorization header. |
Environment |
No | production, staging, or development. Strongly recommended. |
Active |
No | Defaults to true. Set to false to pause delivery without deleting. |
MQTT Delivery
Include a MqttParams array to push payloads to an MQTT broker:
curl -sS -X POST https://api.machineq.net/v1/outputprofiles \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Name": "warehouse-mqtt",
"MqttParams": [
{
"Host": "your-broker.example.com:8883",
"Username": "mquser",
"Password": "<your-password>",
"Topic": "devices/${DEVEUI}/uplink",
"SSL": true,
"ClientId": "mq-${DEVEUI}",
"Environment": "production",
"Active": true
}
]
}'
${DEVEUI}and${FPORT}are replacement variables substituted at delivery time.
| Field | Required | Description |
|---|---|---|
Host |
Yes | Broker hostname and port (e.g. your-broker.example.com:8883). |
Username |
Yes | MQTT username for broker authentication. |
Password |
Yes | MQTT password for broker authentication. |
Topic |
Yes | Publish topic. Supports ${DEVEUI} and ${FPORT} substitution variables. |
SSL |
No | Set to true to connect over TLS. Defaults to false. |
ClientId |
No | MQTT client ID. Supports ${DEVEUI} substitution. |
Environment |
No | production, staging, or development. Strongly recommended. |
Active |
No | Defaults to true. Set to false to pause delivery without deleting. |
AWS IoT Core Delivery
Include an AWSParams array to push directly into AWS IoT Core:
curl -sS -X POST https://api.machineq.net/v1/outputprofiles \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Name": "warehouse-aws",
"AWSParams": [
{
"Endpoint": "<prefix>.iot.<region>.amazonaws.com",
"x509Certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
"Environment": "production",
"Active": true
}
]
}'
| Field | Required | Description |
|---|---|---|
Endpoint |
Yes | IoT Core endpoint in the form {prefix}.iot.{region}.amazonaws.com. No scheme or port. |
x509Certificate |
Yes | X.509 certificate PEM. Replace newlines with \n. |
PrivateKey |
Yes | Private key PEM. Replace newlines with \n. |
Environment |
No | production, staging, or development. Strongly recommended. |
Active |
No | Defaults to true. Set to false to pause delivery without deleting. |
Azure IoT Hub Delivery
Include an AzureParams array to push into Azure IoT Hub:
curl -sS -X POST https://api.machineq.net/v1/outputprofiles \
#!api: POST /v1/outputprofiles | https://docs.machineq.net/machineq-api-v1.html#outputprofile_createoutputprofile
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Name": "warehouse-azure",
"AzureParams": [
{
"Host": "your-hub.azure-devices.net",
"SharedAccessPolicyName": "iothubowner",
"SharedAccessKey": "<primary-key>",
"ApiVersion": "2016-11-14",
"OutputFormat": "azure",
"Environment": "production",
"Active": true
}
]
}'
| Field | Required | Description |
|---|---|---|
Host |
Yes | IoT Hub hostname in the form {hubname}.azure-devices.net. No scheme or port. |
SharedAccessPolicyName |
Yes | Shared access policy name with Device access enabled. |
SharedAccessKey |
Yes | Primary shared access key from the policy. |
ApiVersion |
Yes | API version; current value is 2016-11-14. |
OutputFormat |
No | raw (default) or azure (IoT Hub D2C format). |
Environment |
No | production, staging, or development. Strongly recommended. |
Active |
No | Defaults to true. Set to false to pause delivery without deleting. |
Assigning an Output Profile to Devices
Once you've created an output profile with one or more delivery targets, you need to associate it with devices. There are two approaches depending on whether you're working with a single device or many.
Assign via the Devices Endpoint
Include the OutputProfile field when creating or updating a device. This is the simplest approach when you're provisioning a new device or updating one at a time:
curl -sS -X POST https://api.machineq.net/v1/devices \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"DevEUI": "2CC407FFFE500C3F",
"Name": "warehouse-temp-sensor-001",
"ActivationType": "OTAA",
"ServiceProfile": "<service_profile_id>",
"DeviceProfile": "<device_profile_id>",
"OutputProfile": "<output_profile_id>"
}'
To add or change the output profile on an existing device, use a PATCH:
curl -sS -X PATCH https://api.machineq.net/v1/devices/2CC407FFFE500C3F \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Name": "warehouse-temp-sensor-001",
"DevEUI": "2CC407FFFE500C3F",
"OutputProfile": "<output_profile_id>"
}'
Bulk Assign via the Output Profiles Endpoint
To assign an output profile to multiple devices at once, use the output profiles endpoint. Pass an array of DevEUIs in the request body:
curl -sS -X PATCH https://api.machineq.net/v1/outputprofiles/<output_profile_id>/devices \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"Id": "<output_profile_id>",
"Devices": [
"2CC407FFFE500C3F",
"2CC407FFFE500C40"
]
}'
Each device in the response includes an individual success/fail result, so you can identify any devices that failed to update.
Removing an Output Profile from a Device
To disassociate an output profile from a device without assigning a new one, set RemoveOutputProfile to true in a PATCH to the devices endpoint:
curl -sS -X PATCH https://api.machineq.net/v1/devices/2CC407FFFE500C3F \
-H "Authorization: Bearer $MQ_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"DevEUI": "2CC407FFFE500C3F",
"RemoveOutputProfile": true
}'
The device will continue to receive and decode uplinks, but no data will be pushed to external systems until a new output profile is assigned.
Best Practices for All Delivery Types
Setting the Environment
Always set Environment to production, staging, or development on every delivery target. This tells MachineQ's operations team the criticality of your endpoint; production destinations receive priority attention during delivery incidents.
Pausing Delivery
Set Active to false to temporarily stop delivery to any target without deleting it. This is useful during maintenance windows on your receiving infrastructure. Set it back to true when you're ready to resume.
What's Next?
- Working with Device Data: Query uplinks, configure payload decoders, and send downlinks once data is flowing.
- Device Onboarding & Lifecycle: Provision additional devices or update existing ones to use this output profile.