Documentation
Behaviors API

Behaviors API

Create and manage behaviors programmatically.


Not a developer? You don't need this page! Create behaviors through the app or by talking to PAL. This page is for programmatic access via the API.

List Behaviors

Retrieve all behaviors for a project.

GET /api/behaviors?projectId={projectId}

const res = await fetch(
  `https://palpable.technology/api/behaviors?projectId=${projectId}`,
  { headers: { 'Authorization': 'Bearer pk_your_api_key' } }
)
const data = await res.json()
console.log(data.behaviors)

Response

{
  "behaviors": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Temperature Alert",
      "enabled": true,
      "project_id": "...",
      "triggers_v2": [
        {
          "type": "sensor_threshold",
          "moduleId": "modulino-thermo",
          "capability": "temperature",
          "operator": "above",
          "value": 30
        }
      ],
      "conditions_v2": null,
      "actions_v2": [
        {
          "type": "notification",
          "title": "High Temperature",
          "message": "Temperature is {{modulino_thermo.temperature}}°C",
          "channel": "push"
        }
      ],
      "cooldown_seconds": 300,
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ]
}

Create Behavior

POST /api/behaviors

const res = await fetch('https://palpable.technology/api/behaviors', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer pk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Evening Lights',
    project_id: '550e8400-...',
    triggers_v2: [{
      type: 'sensor_threshold',
      moduleId: 'veml7700',
      capability: 'lux',
      operator: 'below',
      value: 100
    }],
    actions_v2: [{
      type: 'i2c_write_raw',
      moduleId: 'modulino-pixels',
      address: 54,
      command: 'setAll',
      params: { r: 255, g: 180, b: 50 }
    }],
    cooldown_seconds: 300
  })
})

Trigger Types

sensor_threshold

Fires when a sensor value crosses a threshold.

{
  "type": "sensor_threshold",
  "moduleId": "modulino-thermo",
  "capability": "temperature",
  "operator": "above",
  "value": 25
}
OperatorDescription
aboveGreater than
belowLess than
equalsEqual to
changesValue changed (any direction)

schedule

Fires at specific times.

{
  "type": "schedule",
  "pattern": {
    "at": "08:00",
    "days": ["monday", "tuesday", "wednesday", "thursday", "friday"]
  }
}

Times are in 24-hour format. Days are full lowercase names. Schedule runs in the device's configured timezone.

variable_change

Fires when a variable changes.

{
  "type": "variable_change",
  "variable": "counter",
  "operator": "increased"
}
OperatorDescription
increasedValue went up
decreasedValue went down
changedValue changed (any direction)
equalsValue equals a specific amount

Condition Types

Conditions are evaluated after a trigger fires. Wrap in conditions_v2:

{
  "conditions_v2": {
    "type": "sensor_value",
    "moduleId": "veml7700",
    "capability": "lux",
    "operator": "below",
    "value": 100
  }
}

Conditions support negate: true to invert the check.

Action Types

notification

{
  "type": "notification",
  "title": "Alert",
  "message": "Temperature is {{modulino_thermo.temperature}}°C",
  "channel": "push"
}

i2c_write_raw

Send a command directly to a module.

{
  "type": "i2c_write_raw",
  "moduleId": "modulino-buzzer",
  "address": 30,
  "command": "beep",
  "params": { "frequency": 440, "duration": 200 }
}

set_variable

Store or compute a value. Must include either value, expression, or toggle.

{
  "type": "set_variable",
  "name": "angle",
  "expression": "map(modulino_knob.encoder, 0, 100, 0, 180)"
}

check_condition

Branch within a behavior (if/else logic).

{
  "type": "check_condition",
  "condition": {
    "type": "sensor_value",
    "moduleId": "qwiic-soil",
    "capability": "moisture",
    "operator": "below",
    "value": 30
  },
  "ifTrue": [ ... ],
  "ifFalse": [ ... ]
}

wait

Pause before the next action.

{ "type": "wait", "seconds": 5 }

Supports fractional values (e.g., 0.5 for half a second).

gpio_write

Control a GPIO pin directly (for relays, etc.).

{
  "type": "gpio_write",
  "pin": 18,
  "gpio_value": 1
}

Note: the field is gpio_value, not value.

log

Write a message to the cloud log.

{
  "type": "log",
  "message": "Soil moisture OK at {{qwiic_soil.moisture}}%"
}

run_behavior

Trigger another behavior.

{
  "type": "run_behavior",
  "behaviorId": "550e8400-..."
}

display_text / display_frame

Update content on a connected OLED display.

webhook

Call an external URL.

{
  "type": "webhook",
  "url": "https://example.com/hook",
  "method": "POST",
  "body": { "event": "triggered" }
}

Toggle Behavior

PATCH /api/behaviors/{behaviorId}

const res = await fetch(`https://palpable.technology/api/behaviors/${behaviorId}`, {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer pk_your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ enabled: false })
})

Delete Behavior

DELETE /api/behaviors/{behaviorId}

await fetch(`https://palpable.technology/api/behaviors/${behaviorId}`, {
  method: 'DELETE',
  headers: { 'Authorization': 'Bearer pk_your_api_key' }
})

Cooldown

The cooldown_seconds field prevents rapid re-triggering. After firing, the behavior won't fire again until the cooldown expires.

  • Default: 0.5 seconds (500ms)
  • Recommended for notifications: 300 seconds (5 minutes)
  • For responsive interactions (buttons): 0.5 seconds