Skills
The Caoliao A2A service exposes three skills, all read-only.
| Skill | Question it answers | Artifact name |
|---|---|---|
get_entity | What is this code? | entity |
get_records | What has happened to this thing? | records |
list_actions | What can be done right now? | actions |
Note: examples on this page come from a public demo code; they are abridged and personal names have been replaced. The live service returns field values in Chinese — the examples here are translated for illustration. The full structure is defined by schema.json.
Selecting a skill
Include a DataPart in the message parts:
{
"kind": "data",
"data": {
"skill": "get_records",
"url": "https://qr71.cn/okDISU/qssTnoy",
"size": 10,
"pageToken": ""
}
}| Field | Required | Description |
|---|---|---|
url | Yes | Caoliao code link |
skill | No | Skill id. Defaults to get_entity |
size | No | get_records only — page size, default 20, maximum 50 |
pageToken | No | get_records only — paging cursor |
You can also send plain text; the service extracts the first code link and defaults to get_entity. Text is the fallback path. When you know which skill you want, use a DataPart — Caoliao does not perform natural-language intent recognition, that is the calling agent's job.
get_entity
Returns the whole entity in one call: name, type, owning organization, properties, current states, plus a preview of available actions and recent records.
Start here once you have a code.
Example questions (declared in the Agent Card to help callers choose):
- What equipment does this QR code refer to?
- Show me this code's name, current status and properties
Structured payload — an ObjectCard v2, the same structure returned by Public MCP's entity_get. Its main blocks:
| Block | Content |
|---|---|
thing / code / binding | Identity triple: the thing, the code, the binding between them |
properties | Property fields |
relations | Relation slots: located in, belongs to, responsible by, part of |
states | Business states |
records | Record ledger preview: total count plus the most recent entries |
media | Images and attachments |
actions | Available actions with their contract annotations |
plans | Recurring plans |
endpoints | Where this entity is reachable over Public MCP and A2A |
contract | The boundaries this response honors |
Top-level blocks are always present: when untracked they hold null, {} or [], all of which read as "not tracked". "Absence" semantics apply to optional sub-fields inside blocks; see "Three things consumers must know" below. Field details in Public MCP · Tools.
get_records
Returns the full ledger — inspections, repairs, maintenance — newest first, cursor-paginated. Every entry carries a snapshot of the code and thing at the time the record was created.
get_entity only previews the latest few; use this for full history.
Example questions:
- What inspections has this code had recently?
- Show me this machine's operation history
Structured payload:
{
"url": "https://qr71.cn/okDISU/qssTnoy",
"records": [
{
"id": "rec_460807516",
"type": "inspection",
"label": "Inspection form",
"at": "2026-06-23T02:26:36.000Z",
"result": "pass",
"resultLabel": "Normal",
"summary": "Inspection result: normal",
"by": { "name": "Zhang" },
"snapshot": { "codeId": "qssTnoy", "thingId": "thg_qssTnoy" }
}
],
"hasMore": false,
"total": 1
}When hasMore is true, the response also carries a top-level nextPageToken field; pass it as pageToken on the next call.
list_actions
Lists the actions available right now — which forms can be filled in, which state changes exist. Listing only, never execution.
Example questions:
- Which forms can be filled in on this code right now?
- What actions are available on this code?
Structured payload:
{
"url": "https://qr71.cn/okDISU/qssTnoy",
"actions": [
{
"action": "record:1556557",
"label": "Inspection form",
"requiresAuth": true,
"annotations": {
"readonly": false,
"destructive": false,
"idempotent": "by_request_key",
"confirm": "none"
},
"precondition": null,
"formSchemaVia": "entity_action_get",
"humanUrl": "https://qr71.cn/okDISU/qssTnoy"
},
{
"action": "record:1556556",
"label": "Maintenance record",
"requiresAuth": true,
"annotations": {
"readonly": false,
"destructive": false,
"idempotent": "by_request_key",
"confirm": "none"
},
"precondition": null,
"formSchemaVia": "entity_action_get",
"humanUrl": "https://qr71.cn/okDISU/qssTnoy"
}
]
}Important:
requiresAuth: truemeans "executing this action requires authorization". But this service never executes an action, authorized or not. The correct path is to handhumanUrlto a person, who completes the form on the scan page.The
entity_action_getnamed informSchemaViais a tool of Public MCP. A2A exposes three skills and fetching field schemas is not among them — use Public MCP when you need form fields.
annotationsdescribe how the action will behave when it is eventually executed. They are not a description of current behavior.
Three things consumers must know
These come from the read-only contract extension and directly affect how you handle responses:
- Neither absence nor emptiness is negation. A missing sub-field, or a block holding
null/{}/[], means the platform does not track that value or cannot resolve it into a structured reference. It does not meanfalseor "does not exist". Caoliao would rather give nothing than pass text off as a structured reference. thing.idis a transitional identifier (idScheme: "code-derived"). Do not persist a dependency on it. The stable identifier to store iscode.uri.- Ledger entries can currently be edited by the owning organization. An immutable ledger is the target state; this contract does not promise immutability today.
Full contract at https://a2a.objqr.com/ext/caoliao-entity/v2; machine-readable schema at schema.json under the same path.
Next
- Task and Response — the full envelope you get back