Skip to content

Tenant Integration Guide

This document explains the platform from a tenant perspective, including:

  • Platform architecture and request flow
  • Two integration modes: device-level and tenant-level
  • HTTP and MQTT interfaces, plus documentation entry points
  • Tenant HTTP callback wrapper protocol

Protocol priority note: for device message fields, topic definitions, and error codes, always use the latest Device Protocol as the source of truth.

2. Platform Architecture from the Tenant Perspective

Section titled “2. Platform Architecture from the Tenant Perspective”
flowchart LR
    U[End User] --> A[Tenant App]
    A --> TP[Tenant Platform]
    A --> CP[Cloud Print Platform]
    TP --> CP[Cloud Print Platform]

    CP --> AI1[Text-to-Image Module]
    CP --> AI2[LLM Module]
    CP --> MQ[MQTT Service]
    CP --> ASR[ASR Service]

    AI1 -.Can be integrated through the tenant text-to-image standard.- TTI[Tenant Text-to-Image Service]
    AI2 -.OpenAPI-compatible integration supported.- LLM[Tenant LLM Service]
    ASR -.Can connect to a tenant-provided ASR platform.- TASR[Tenant ASR Platform]

    D[Device] <--> CP
    D <--> MQ
    D <--> ASR

Notes:

  • A tenant app integrates with either the tenant platform or the cloud print platform, but does not communicate with devices directly.
  • Devices communicate directly with the cloud print platform and its MQTT and ASR services. They do not communicate directly with tenant apps, tenant platforms, or any other tenant-side infrastructure.
  • ASR capabilities are handled by the cloud print platform’s ASR service and can be connected to a tenant-provided ASR platform.

3. Two Integration Modes and Their Advantages

Section titled “3. Two Integration Modes and Their Advantages”
ModeCore CharacteristicsMain Advantages
Device-level integrationThe app calls the cloud platform directly with a temporary device tokenLower platform integration cost, shorter interaction chain, faster response, easier troubleshooting
Tenant-level integrationThe tenant backend calls the full platform API with a tenant tokenRicher API capabilities, easier unified resource management, better extensibility, centralized governance
sequenceDiagram
    autonumber
    participant App as Tenant App
    participant Dev as Device
    participant TP as Tenant Platform
    participant CP as Cloud Print Platform

    App->>TP: Submit SN and binding request

    alt Device verification code is required
      TP->>CP: Push device verification code
      CP->>Dev: Device prints verification code
      App->>TP: Submit SN + verification code
    else Verification code is not required
      TP->>CP: Start binding directly
    end

    TP->>CP: Bind device and get appAuthCode
    CP-->>TP: Return appAuthCode
    TP->>CP: Exchange SN + appAuthCode for a temporary device token
    CP-->>TP: Return token + expiresIn
    TP-->>App: Return token + expiresIn

    App->>CP: Call APIs with the device token (for example, create print jobs)
    App->>CP: Subscribe to device MQTT topics with the device token

4.1 Core HTTP APIs for Device-Level Integration

Section titled “4.1 Core HTTP APIs for Device-Level Integration”
  • The app subscribes to device topics as a device application client to receive status and acknowledgements.
  • Common topics:
    • devices/{tenantCode}/{userName}/{sn}/up/state
    • devices/{tenantCode}/{userName}/{sn}/up/print/ack
    • devices/{tenantCode}/{userName}/{sn}/up/upgrade/ack
    • devices/{tenantCode}/{userName}/{sn}/up/control/ack
sequenceDiagram
    autonumber
    participant TP as Tenant Platform
    participant CP as Cloud Print Platform

    TP->>CP: Get tenant token with APIKey + Secret
    CP-->>TP: Return tenant token

    TP->>CP: Upload files, create jobs, query jobs, control queues
    CP-->>TP: Return business result

    par Message receiving (HTTP)
      CP-->>TP: Callback device messages based on tenant configuration
    and Message receiving (MQTT)
      TP-->>CP: Subscribe to device/{tenantCode}/#
      CP-->>TP: Forward tenant-scoped message streams
    end

5.1 Core HTTP APIs for Tenant-Level Integration

Section titled “5.1 Core HTTP APIs for Tenant-Level Integration”

Callback method: POST {endpointUrl} with a unified JSON request body. For detailed device message fields, topic definitions, and error codes, always use the latest Device Protocol as the source of truth.

{
"messageType": "up/state",
"deviceId": "SN123456",
"tenantCode": "tenant_a",
"username": "owner_user",
"data": {}
}

Field descriptions:

  • messageType: topic business type
  • deviceId: device SN
  • tenantCode: tenant code
  • username: device owner username (the userName in the topic)
  • data: device protocol message body (see the Device Protocol)
TopicmessageTypeDirectionMain Purposedata Content Source
devices/{tenantCode}/{userName}/{sn}/up/state/up/stateDevice -> Cloud PlatformReport device status such as battery, paper, network, and firmwareDevice status report body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/up/print/ack/up/print/ackDevice -> Cloud PlatformReport print job confirmation, progress, and success/failure acknowledgementsPrint acknowledgement body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/up/upgrade/ack/up/upgrade/ackDevice -> Cloud PlatformReport upgrade task confirmation, download/upgrade progress, and success/failure acknowledgementsUpgrade acknowledgement body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/up/control/ack/up/control/ackDevice -> Cloud PlatformReport control command execution resultsControl acknowledgement body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/up/event/up/eventDevice -> Cloud PlatformReport device events such as stop-printDevice event body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/up/pull/up/pullDevice -> Cloud PlatformPull print resources, text-to-image resources, or feature lists proactivelyPull request body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/down/print/down/printCloud Platform -> DeviceDeliver print jobs and resource listsPrint delivery body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/down/upgrade/down/upgradeCloud Platform -> DeviceDeliver firmware upgrade tasksUpgrade delivery body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/down/control/down/controlCloud Platform -> DeviceDeliver device control commands such as reboot, shutdown, or cache clearingControl delivery body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/down/pull/ack/down/pull/ackCloud Platform -> DeviceReply to pull requests with results such as “no task available”Pull acknowledgement body (see device-protocol.md)
devices/{tenantCode}/{userName}/{sn}/down/resource/down/resourceCloud Platform -> DeviceReturn feature lists or resource request failure detailsResource response body (see device-protocol.md)
{
"messageType": "client_connected",
"deviceId": "SN123456",
"tenantCode": "tenant_a",
"userName": "owner_user",
"sourceUsername": "tenant_a|owner_user|SN123456",
"data": {
"event": "client_connected",
"clientid": "SN123456|0.1",
"username": "tenant_a|owner_user|SN123456",
"peername": "10.0.0.10:53721",
"sockname": "10.0.0.1:1883",
"connected_at": 1740000000,
"timestamp": 1740000000
}
}
{
"messageType": "client_disconnected",
"deviceId": "SN123456",
"tenantCode": "tenant_a",
"userName": "owner_user",
"sourceUsername": "tenant_a|owner_user|SN123456",
"data": {
"event": "client_disconnected",
"clientid": "SN123456|0.1",
"username": "tenant_a|owner_user|SN123456",
"reason": "normal",
"peername": "10.0.0.10:53721",
"connected_at": 1740000000,
"disconnected_at": 1740000300,
"timestamp": 1740000300
}
}

The examples below are aligned with the latest Device Protocol. If fields, constraints, enums, or error codes change, always use that protocol document as the final reference.

{
"msgId": "a1b2c3d4e5f6789012345678901234ab",
"ts": 1724040060000,
"rssi": -58,
"battery": 90,
"paper": 1,
"paperType": "roll",
"errCode": [],
"temperature": 35.2,
"humidity": 45,
"ipAddress": "192.168.1.25",
"bluetoothMac": "00:1A:7D:DA:71:13",
"imei": "865123456789012",
"iccid": "89860123456789012345",
"signalStrength": -75,
"networkType": "4G",
"printCount": 12345,
"avgLatency": 150,
"packetLossRate": 2,
"charging": false,
"sleepTime": 10,
"firmware": [
{
"firmwareType": "cloud",
"firmwareVersion": "1.2.3",
"nn": "NN-001"
},
{
"firmwareType": "printer",
"firmwareVersion": "3.4.5",
"nn": "NN-002"
},
{
"firmwareType": "bluetooth",
"firmwareVersion": "0.9.8"
}
]
}
{
"msgId": "b2c3d4e5f67890a1b2c3d4e5f67890a1",
"jobId": "92ef08872ff906876071478274eec57b",
"ackOriginalMsgId": "a1b2c3d4e5f6789012345678901234ab",
"status": "confirm",
"seqs": [1, 2, 3, 4, 5],
"errCode": [],
"msg": "ok",
"ts": 1724040088000
}
{
"msgId": "d4e5f6789012a3b4c5d6e7f89012a3b4",
"deviceUpgradeId": "92ef08872ff906876071478274eec57b",
"ackOriginalMsgId": "msgId of the original delivery message",
"status": "upgrading",
"errCode": [],
"msg": "ok",
"ts": 1724041088000
}
{
"msgId": "g5h6i7j890k1l2m3n4o5p6q789r0s1t2",
"controlId": "a351eff1b614d0c1f64227d0c4b28c99",
"ackOriginalMsgId": "msgId of the original delivery message",
"status": "confirm",
"errCode": [],
"msg": "ok",
"ts": 1724042088000
}
{
"msgId": "h7i8j9k012l3m4n5o6p7q8r901s2t3u4",
"eventType": "stop_print",
"eventParams": {
"reason": "user_action"
},
"ts": 1724043088000
}
{
"msgId": "k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"type": "print",
"params": {
"jobId": "",
"seq": 0,
"firmware": [
{
"firmwareType": "cloud",
"firmwareVersion": "1.2.3",
"nn": "NN-001"
},
{
"firmwareType": "printer",
"firmwareVersion": "3.4.5",
"nn": "NN-002"
}
]
},
"ts": 1724044088000
}

Legacy-compatible /up/pull structure:

{
"msgId": "k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"jobId": "",
"seq": 0,
"firmware": [
{
"firmwareType": "cloud",
"firmwareVersion": "1.2.3",
"nn": "NN-001"
}
],
"ts": 1724044088000
}
{
"msgId": "e5f6789012a3b4c5d6e7f89012a3b4c5",
"jobId": "j-202408-0001",
"totalFileNumber": 100,
"resources": [
{
"seq": 1,
"url": "https://obj.example.com/prints/j-202408-0001-part1.data",
"hash": "sha256:ab12cd34ef56...",
"size": 102400,
"fileType": "prn",
"prnProtocol": "esc",
"compression": "gzip"
},
{
"seq": 2,
"url": "https://obj.example.com/prints/j-202408-0001-part2.data",
"hash": "sha256:cd34ef56ab78...",
"size": 102400,
"fileType": "prn",
"prnProtocol": "esc",
"compression": "none"
}
],
"dateTime": 1724846400000
}
{
"msgId": "f6789012a3b4c5d6e7f89012a3b4c5d6",
"deviceUpgradeId": "u-202408-0001",
"firmwareType": "cloud",
"firmwareVersion": "1.2.4",
"url": "https://obj.example.com/fw/p5802-1.2.4.bin",
"hash": "sha256:cd34ef56ab78...",
"size": 5242880,
"compression": "gzip",
"dateTime": 1724846400000
}
{
"msgId": "h6i7j890k1l2m3n4o5p6q789r0s1t2u3",
"controlId": "a351eff1b614d0c1f64227d0c4b28c99",
"command": "reboot",
"params": {},
"dateTime": 1724846400000
}
{
"msgId": "m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8",
"ackOriginalMsgId": "k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"code": 0,
"message": "no_task",
"dateTime": 1724044188000
}
{
"msgId": "r1s2t3u4v5w6x7y8z9a0b1c2d3e4f5g6",
"ackOriginalMsgId": "k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"type": "feature_list",
"errCode": [],
"msg": "",
"params": {
"features": [
{
"featureCode": "print_basic",
"featureName": "Basic Printing",
"featureType": "normal"
},
{
"featureCode": "ai_text_to_image",
"featureName": "Text-to-Image Printing",
"featureType": "ai",
"bizCode": "ai_doodle_swarmui_marker",
"bizName": "Text-to-Image"
}
]
},
"dateTime": 1724044288000
}

Failure example for /down/resource:

{
"msgId": "r1s2t3u4v5w6x7y8z9a0b1c2d3e4f5g7",
"ackOriginalMsgId": "k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z7",
"type": "text_to_image",
"errCode": [2002],
"msg": "Missing prompt for text_to_image",
"params": {},
"dateTime": 1724044289000
}
  • Integrate through imageEngineCode + runtimeParams.
  • The integration implementation should follow the tenant-provided text-to-image standard protocol, including request and response fields, authentication, timeout handling, and error codes.
  • Typically used for user-input cleanup, expansion, translation, moderation, and similar tasks.
  • An OpenAPI Chat Completions compatible interface is recommended, with a default path such as /v1/chat/completions.
  • Devices interact with the cloud print platform’s ASR service directly using the ASR protocol.
  • The cloud print platform can connect that ASR service to a tenant-provided ASR platform.
  1. Confirm the integration mode first: device-level first or tenant-level first.
  2. Build the smallest closed loop first: authentication -> create print job -> receive print acknowledgement.
  3. Then integrate message aggregation through MQTT or HTTP callbacks.
  4. Finally integrate replaceable AI capabilities and advanced workflows.