Docs / Strand / connectors/contact-message
Contact Entity
Direction: Read/Write | Type: contact.platform
Send messages and files to Contact entities and update entity state tables from your Strand workflows.
The contact.platform connector communicates with the Contact platform internally; no external access or public URLs are required.
Connector Setup
Create a Contact Entity Message connector from the Connectors page.
| Field | Required | Description |
|---|---|---|
| API Key | Yes | Entity API key (PASETO token). The entity's role must include the appropriate permissions for the operations you plan to use. |
The API key is encrypted at rest.
Tip: Store entity API keys in the Strand vault and reference them with {{ vault.contact_api_key }} in the connector configuration to keep credentials centralized.
Operations
The connector supports three operations, selected via the Operation dropdown on the node configuration panel.
send (default)
Send a message to a Contact entity. This is the default operation if none is specified.
Node Configuration
| Field | Required | Description |
|---|---|---|
| Operation | No | Set to send (or leave blank; it is the default) |
| Data | Yes | Message payload as a JSON object. Values support Jinja2 templates. |
Destination (key: dest) |
No | Target entity name or full resource path. Supports Jinja2 templates. |
| Tags | No | List of string tags for message routing and flow triggering. |
Data is the message payload:
{
"temperature": "{{ payload.temp }}",
"status": "processed",
"source": "{{ initial.meta.workflow_id }}"
}
Destination supports two formats:
- Entity name: for same-account delivery (e.g.,
my-sensor). The entity is looked up by name within the sending entity's account. - Full resource path: for cross-account delivery (e.g.,
12345:us-east-1:entity:my-sensor).
If omitted, the message is published without a specific destination.
Tags are used for routing and triggering Contact flows:
["alert", "high-priority", "sensor-data"]
send Example
{
"operation": "send",
"data": {
"temperature": "{{ payload.temp }}",
"humidity": "{{ payload.humidity }}",
"timestamp": "{{ payload.ts }}"
},
"dest": "sensor-gateway",
"tags": ["sensor-data", "building-a"]
}
send Permissions
The entity whose API key is used must have a role with the entity:WriteMessages action. If a destination is specified, the entity also needs entity:WriteMessages permission scoped to the destination's resource path.
---
send_file
Send a file into Contact (file transfer). The file bytes are supplied base64-encoded, typically chained from a Contact: Fetch File node or an HTTP download. The sending entity pays storage until the file is consumed.
Node Configuration
| Field | Required | Description |
|---|---|---|
| Operation | Yes | Set to send_file |
Content (key: content_base64) |
Yes | File bytes, base64-encoded. Defaults to {{ payload.content_base64 }} so it chains straight from a Fetch File node. |
File Name (key: file_name) |
No | File name including extension (drives Contact's file-type allowlist). |
Content Type (key: content_type) |
No | MIME type; inferred from the extension if omitted. |
Destination (key: dest) |
No | Recipient entity name or full resource path (direct / group / cross-account). |
| Tags | No | Comma-separated routing tags that route the file to subscribing Strand workflows/connectors. |
Kind (key: kind) |
No | Set to clip for the motion gallery (no recipient). |
Meta (key: meta) |
No | Optional sender metadata, ≤8 KB. Supports Jinja2 templates. |
Set exactly one delivery target: dest, tags, or kind: clip. See Delivery modes for how each routes.
send_file Example
Forward a fetched file to a specific device (direct delivery):
{
"operation": "send_file",
"content_base64": "{{ payload.content_base64 }}",
"file_name": "{{ payload.file_name }}",
"content_type": "{{ payload.content_type }}",
"dest": "gateway-01"
}
On success the node adds transfer_id, sha256, size, and mode to the output.
send_file Permissions
The entity whose API key is used must have a role with the entity:SendFiles action. For direct, group, and cross-account delivery the entity also needs entity:SendFiles scoped to the destination's resource path.
---
update_state
Update an entity's status table. The status table is a JSON key-value store attached to each Contact entity, useful for tracking device state, configuration, or metadata.
Node Configuration
| Field | Required | Description |
|---|---|---|
| Operation | Yes | Set to update_state |
| Entity | Yes | Entity name whose state table to update. Supports Jinja2 templates. |
| State | Yes | JSON object (or Jinja2 template that renders to JSON) containing the state data to apply. |
| Replace | No | false (default) to merge (PATCH): existing keys are preserved, provided keys are added or overwritten. true to replace (PUT): the entire state table is overwritten with the provided data. |
update_state Example
Merge new sensor readings into an entity's state table, preserving existing keys:
{
"operation": "update_state",
"entity": "{{ initial.meta.entity_name }}",
"state": {
"last_temperature": "{{ payload.temp }}",
"last_seen": "{{ payload.timestamp }}",
"firmware": "{{ payload.fw_version }}"
},
"replace": "false"
}
Replace the entire state table (all previous keys are removed):
{
"operation": "update_state",
"entity": "thermostat-01",
"state": {
"mode": "cooling",
"target_temp": 22,
"updated_by": "{{ initial.meta.workflow_id }}"
},
"replace": "true"
}
Important: Whenreplaceis"true", any keys not included instatewill be deleted from the entity's status table. Use"false"(the default) to safely merge updates.
update_state Permissions
The entity whose API key is used must have a role with the entity:UpdateEntityStatusTable action.
Errors
The connector translates Contact API responses into descriptive messages:
send Errors
| Status | Meaning |
|---|---|
| 401 | Invalid or expired entity API key, or the key does not belong to an entity |
| 403 | Entity is missing the entity:WriteMessages permission |
| 429 | Monthly data limit exceeded for this account |
| Connection error | Contact service is unreachable. Contact your administrator if this persists. |
send_file Errors
| Status | Meaning |
|---|---|
| 400 | No consumer for the tags, invalid destination, or the group has no same-account members |
| 401 | Invalid or expired entity API key |
| 402 | Surface monthly scan quota exhausted for this account |
| 403 | Entity is missing the entity:SendFiles permission, or file transfer is disabled |
| 413 | File exceeds the size limit or the account's monthly data limit |
| 415 | File type not allowed |
| 422 | File blocked by Surface (flagged malicious) |
| Connection error | Contact service is unreachable. Contact your administrator if this persists. |
update_state Errors
| Status | Meaning |
|---|---|
| 401 | Invalid or expired entity API key, or the key does not belong to an entity |
| 403 | Entity is missing the entity:UpdateEntityStatusTable permission |
| 404 | Entity not found |
| 429 | Monthly data limit exceeded for this account |
| 500 | Contact service encountered an internal error |
| Connection error | Contact service is unreachable. Contact your administrator if this persists. |
Tendrl