# Functions

## List all device functions

> Retrieves all functions configured for a device. Functions execute in sequence: Decoder → Transform → Rules (parallel) → Storage (parallel). Schedule functions run independently on cron timers.\
> \
> \*\*Function Types:\*\*\
> \
> \| Type | Purpose | Execution |\
> \|------|---------|-----------|\
> \| \`decoder\` | Parse raw bytes to JSON | First (one per device) |\
> \| \`transformfn\` | Modify/enrich data with JSONata | Second (one per device) |\
> \| \`rule\` | Trigger actions on conditions | Third (multiple, parallel) |\
> \| \`storagefn\` | Forward to external storage | Fourth (multiple, parallel) |\
> \| \`schedule\` | Poll external APIs on cron | Independent (multiple) |\
> \
> \*\*Function Status:\*\*\
> \- \`Active\`: Function running successfully\
> \- \`Failed\`: Last execution failed (auto-disabled, email sent)\
> \- \`Disabled\`: Manually disabled by user\
> \
> \*\*Response includes:\*\* function\_type, status, enabled, last\_triggered, debounce\_period, template\_id

```json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"function.getFunctionsResponseBody":{"type":"object","properties":{"functions":{"type":"array","items":{"$ref":"#/components/schemas/function.function"}},"total_count":{"type":"integer"}}},"function.function":{"type":"object","properties":{"avatar":{"type":"string"},"brand":{"type":"string"},"conditionType":{"type":"string"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/function.Condition"}},"created":{"type":"string"},"cron_properties":{"$ref":"#/components/schemas/function.cronData"},"debounce_period":{"type":"integer"},"description":{"type":"string"},"device_id":{"type":"string"},"enabled":{"type":"boolean"},"from_template":{"type":"boolean"},"function_type":{"type":"string"},"id":{"type":"string"},"interpreter":{"type":"string"},"jsonata":{"type":"string"},"last_triggered":{"type":"string"},"metadata":{"type":"object","additionalProperties":{}},"model":{"type":"string"},"name":{"type":"string"},"project_id":{"type":"string"},"reason":{"type":"string"},"rule_type":{"type":"string"},"scheduled_type":{"type":"string"},"script":{"type":"string"},"source_type":{"type":"string"},"status":{"type":"string"},"storage_type":{"type":"string"},"template_update":{"type":"boolean"},"transformation_id":{"type":"string"}}},"function.Condition":{"type":"object","properties":{"key":{"description":"Data field name to evaluate","type":"string"},"operator":{"description":"Comparison operator: >, <, ==, !=, >=, <=","type":"string"},"value":{"description":"Value to compare against","type":"string"}}},"function.cronData":{"type":"object","properties":{"cron_expression":{"type":"string"},"timezone":{"type":"string"}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/projects/{project_id}/devices/{device_id}/functions":{"get":{"description":"Retrieves all functions configured for a device. Functions execute in sequence: Decoder → Transform → Rules (parallel) → Storage (parallel). Schedule functions run independently on cron timers.\n\n**Function Types:**\n\n| Type | Purpose | Execution |\n|------|---------|-----------|\n| `decoder` | Parse raw bytes to JSON | First (one per device) |\n| `transformfn` | Modify/enrich data with JSONata | Second (one per device) |\n| `rule` | Trigger actions on conditions | Third (multiple, parallel) |\n| `storagefn` | Forward to external storage | Fourth (multiple, parallel) |\n| `schedule` | Poll external APIs on cron | Independent (multiple) |\n\n**Function Status:**\n- `Active`: Function running successfully\n- `Failed`: Last execution failed (auto-disabled, email sent)\n- `Disabled`: Manually disabled by user\n\n**Response includes:** function_type, status, enabled, last_triggered, debounce_period, template_id","tags":["Functions"],"summary":"List all device functions","parameters":[{"description":"Project ID (UUID format)","name":"project_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Device ID","name":"device_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Functions retrieved successfully - Returns array of all function types for the device","content":{"application/json":{"schema":{"$ref":"#/components/schemas/function.getFunctionsResponseBody"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"404":{"description":"Device not found or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
```

## Get function details

> Retrieves complete configuration for a specific function including script/expression, conditions, metadata, credentials, and execution status.\
> \
> \*\*Required Query Parameter:\*\*\
> \- \`type\`: Function type - "decoder", "rule", "storage", "transformation", "scheduled"\
> \
> \*\*Response Includes:\*\*\
> \
> \*\*Decoder:\*\* script, enabled, status, reason (if failed)\
> \
> \*\*Transform:\*\* expression, interpreter (JSONata), enabled\
> \
> \*\*Rule:\*\* rule\_type, conditions, metadata (webhook URI, headers, body), debounce\_period, last\_triggered, status\
> \
> \*\*Storage:\*\* storagefn\_type, metadata (database, collection), cred\_meta (encrypted credentials), transform\_id, last\_triggered\
> \
> \*\*Schedule:\*\* schedule\_type, cron\_data (timezone, cron\_spec), metadata (URI, method, headers), last\_triggered\
> \
> \*\*Use Cases:\*\*\
> \- View current function configuration\
> \- Debug function failures (check reason field)\
> \- Clone function to another device\
> \- Audit function settings

```json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"function.function":{"type":"object","properties":{"avatar":{"type":"string"},"brand":{"type":"string"},"conditionType":{"type":"string"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/function.Condition"}},"created":{"type":"string"},"cron_properties":{"$ref":"#/components/schemas/function.cronData"},"debounce_period":{"type":"integer"},"description":{"type":"string"},"device_id":{"type":"string"},"enabled":{"type":"boolean"},"from_template":{"type":"boolean"},"function_type":{"type":"string"},"id":{"type":"string"},"interpreter":{"type":"string"},"jsonata":{"type":"string"},"last_triggered":{"type":"string"},"metadata":{"type":"object","additionalProperties":{}},"model":{"type":"string"},"name":{"type":"string"},"project_id":{"type":"string"},"reason":{"type":"string"},"rule_type":{"type":"string"},"scheduled_type":{"type":"string"},"script":{"type":"string"},"source_type":{"type":"string"},"status":{"type":"string"},"storage_type":{"type":"string"},"template_update":{"type":"boolean"},"transformation_id":{"type":"string"}}},"function.Condition":{"type":"object","properties":{"key":{"description":"Data field name to evaluate","type":"string"},"operator":{"description":"Comparison operator: >, <, ==, !=, >=, <=","type":"string"},"value":{"description":"Value to compare against","type":"string"}}},"function.cronData":{"type":"object","properties":{"cron_expression":{"type":"string"},"timezone":{"type":"string"}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/projects/{project_id}/devices/{device_id}/functions/{function_id}":{"get":{"description":"Retrieves complete configuration for a specific function including script/expression, conditions, metadata, credentials, and execution status.\n\n**Required Query Parameter:**\n- `type`: Function type - \"decoder\", \"rule\", \"storage\", \"transformation\", \"scheduled\"\n\n**Response Includes:**\n\n**Decoder:** script, enabled, status, reason (if failed)\n\n**Transform:** expression, interpreter (JSONata), enabled\n\n**Rule:** rule_type, conditions, metadata (webhook URI, headers, body), debounce_period, last_triggered, status\n\n**Storage:** storagefn_type, metadata (database, collection), cred_meta (encrypted credentials), transform_id, last_triggered\n\n**Schedule:** schedule_type, cron_data (timezone, cron_spec), metadata (URI, method, headers), last_triggered\n\n**Use Cases:**\n- View current function configuration\n- Debug function failures (check reason field)\n- Clone function to another device\n- Audit function settings","tags":["Functions"],"summary":"Get function details","parameters":[{"description":"Project ID (UUID format)","name":"project_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Device ID","name":"device_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function ID","name":"function_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function type","name":"type","in":"query","required":true,"schema":{"type":"string","enum":["decoder","rule","storage","transformation","scheduled"]}}],"responses":{"200":{"description":"Function retrieved successfully - Includes complete configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/function.function"}}}},"400":{"description":"Invalid function type parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"404":{"description":"Function not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
```

## Update entire function configuration

> \*\*FULL REPLACEMENT:\*\* Updates the complete function configuration including script, conditions, metadata, and all settings. Use UpdateConfig for partial updates.\
> \
> \*\*Update Scenarios:\*\*\
> \- \*\*Decoder:\*\* Update JavaScript decoder script, change parsing logic\
> \- \*\*Transform:\*\* Update JSONata expression, change field transformations\
> \- \*\*Rule:\*\* Update conditions, webhook URL, email templates, debounce period\
> \- \*\*Storage:\*\* Update connection strings, database/collection names, credentials\
> \- \*\*Schedule:\*\* Update cron schedule, API endpoint, timezone\
> \
> \*\*Required Query Parameter:\*\*\
> \- \`type\`: Function type - "decoder", "rule", "storage", "transformation", "scheduled"\
> \
> \*\*Request Body Examples:\*\*\
> \
> Decoder: \`{"name": "Decoder", "script": "function decoder(input) {...}", "enabled": true}\`\
> \
> Rule: \`{"name": "Alert", "rule\_type": "webhook", "conditions": \[...], "metadata": {...}, "debounce\_period": 5}\`\
> \
> Transform: \`{"name": "Transform", "expression": "$merge(\[...])", "interpreter": "JSONata"}\`

```json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"main.SuccessResponse":{"type":"object","properties":{"action":{"description":"Action that was performed","type":"string"},"message":{"description":"Human-readable success message","type":"string"},"success":{"description":"Operation completed successfully","type":"boolean"}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/projects/{project_id}/devices/{device_id}/functions/{function_id}":{"put":{"description":"**FULL REPLACEMENT:** Updates the complete function configuration including script, conditions, metadata, and all settings. Use UpdateConfig for partial updates.\n\n**Update Scenarios:**\n- **Decoder:** Update JavaScript decoder script, change parsing logic\n- **Transform:** Update JSONata expression, change field transformations\n- **Rule:** Update conditions, webhook URL, email templates, debounce period\n- **Storage:** Update connection strings, database/collection names, credentials\n- **Schedule:** Update cron schedule, API endpoint, timezone\n\n**Required Query Parameter:**\n- `type`: Function type - \"decoder\", \"rule\", \"storage\", \"transformation\", \"scheduled\"\n\n**Request Body Examples:**\n\nDecoder: `{\"name\": \"Decoder\", \"script\": \"function decoder(input) {...}\", \"enabled\": true}`\n\nRule: `{\"name\": \"Alert\", \"rule_type\": \"webhook\", \"conditions\": [...], \"metadata\": {...}, \"debounce_period\": 5}`\n\nTransform: `{\"name\": \"Transform\", \"expression\": \"$merge([...])\", \"interpreter\": \"JSONata\"}`","tags":["Functions"],"summary":"Update entire function configuration","parameters":[{"description":"Project ID (UUID format)","name":"project_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Device ID","name":"device_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function ID","name":"function_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function type","name":"type","in":"query","required":true,"schema":{"type":"string","enum":["decoder","rule","storage","transformation","scheduled"]}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Complete function configuration","required":true},"responses":{"200":{"description":"Function updated successfully - Full configuration replaced","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.SuccessResponse"}}}},"400":{"description":"Invalid request body - Check required fields for function type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"404":{"description":"Function not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
```

## Update specific function configuration fields

> \*\*PARTIAL UPDATE:\*\* Updates only specific configuration fields without touching the script or core settings. Use this for quick changes like updating a webhook URL or debounce period.\
> \
> \*\*Supported Function Types:\*\*\
> \- \*\*Rule:\*\* Update webhook URI, headers, body template, debounce\_period\
> \- \*\*Storage:\*\* Update database name, collection, connection details\
> \- \*\*Schedule:\*\* Update cron schedule, API endpoint, timezone\
> \
> \*\*Not Supported:\*\* Decoder and Transform (use Update endpoint instead)\
> \
> \*\*Required Query Parameter:\*\*\
> \- \`type\`: Function type - "rule", "storage", "scheduled"\
> \
> \*\*Use Cases:\*\*\
> \- Change webhook URL without modifying conditions\
> \- Update debounce period without touching rule logic\
> \- Rotate database credentials\
> \- Modify cron schedule\
> \
> \*\*Example: Update Rule Webhook URL\*\*\
> \`\`\`json\
> {"metadata": {"uri": "<https://new-webhook.example.com"\\}}\\>
> \`\`\`

````json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"main.SuccessResponse":{"type":"object","properties":{"action":{"description":"Action that was performed","type":"string"},"message":{"description":"Human-readable success message","type":"string"},"success":{"description":"Operation completed successfully","type":"boolean"}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/projects/{project_id}/devices/{device_id}/functions/{function_id}/config":{"put":{"description":"**PARTIAL UPDATE:** Updates only specific configuration fields without touching the script or core settings. Use this for quick changes like updating a webhook URL or debounce period.\n\n**Supported Function Types:**\n- **Rule:** Update webhook URI, headers, body template, debounce_period\n- **Storage:** Update database name, collection, connection details\n- **Schedule:** Update cron schedule, API endpoint, timezone\n\n**Not Supported:** Decoder and Transform (use Update endpoint instead)\n\n**Required Query Parameter:**\n- `type`: Function type - \"rule\", \"storage\", \"scheduled\"\n\n**Use Cases:**\n- Change webhook URL without modifying conditions\n- Update debounce period without touching rule logic\n- Rotate database credentials\n- Modify cron schedule\n\n**Example: Update Rule Webhook URL**\n```json\n{\"metadata\": {\"uri\": \"https://new-webhook.example.com\"}}\n```","tags":["Functions"],"summary":"Update specific function configuration fields","parameters":[{"description":"Project ID (UUID format)","name":"project_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Device ID","name":"device_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function ID","name":"function_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function type","name":"type","in":"query","required":true,"schema":{"type":"string","enum":["rule","storage","scheduled"]}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"Partial configuration update","required":true},"responses":{"200":{"description":"Function configuration updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.SuccessResponse"}}}},"400":{"description":"Invalid request body or unsupported function type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"404":{"description":"Function not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
````

## Enable/disable a function

> \*\*QUICK TOGGLE:\*\* Enables or disables a function without changing its configuration. Useful for temporary disabling during maintenance or debugging.\
> \
> \*\*Required Query Parameters:\*\*\
> \- \`type\`: Function type - "decoder", "rule", "storage", "transformation", "scheduled"\
> \- \`enabled\`: Boolean - true to enable, false to disable\
> \
> \*\*Behavior:\*\*\
> \- \*\*Disable:\*\* Function stops executing, data flow continues without it\
> \- \*\*Enable:\*\* Function resumes execution, applies to new data\
> \- Status transitions: Active ↔ Disabled\
> \
> \*\*Use Cases:\*\*\
> \- Temporarily disable rule during maintenance\
> \- Test data pipeline without decoder\
> \- Pause storage function to external system\
> \- Quick troubleshooting without losing configuration\
> \
> \*\*Note:\*\* Failed functions must be fixed and enabled via this endpoint to resume

```json
{"openapi":"3.0.0","info":{"title":"Qubitro Public API","version":"2.0"},"servers":[{"url":"https://api.qubitro.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Enter your API key with the Bearer prefix, e.g. \"Bearer QB_your_api_key_here\"","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"main.SuccessResponse":{"type":"object","properties":{"action":{"description":"Action that was performed","type":"string"},"message":{"description":"Human-readable success message","type":"string"},"success":{"description":"Operation completed successfully","type":"boolean"}}},"main.ErrorResponse":{"type":"object","properties":{"action":{"description":"Action that was attempted","type":"string"},"code":{"description":"Optional error code","type":"string"},"details":{"description":"Optional additional details","type":"string"},"message":{"description":"Human-readable error message","type":"string"},"success":{"description":"Operation failed","type":"boolean"}}}}},"paths":{"/v2/projects/{project_id}/devices/{device_id}/functions/{function_id}/enabled":{"put":{"description":"**QUICK TOGGLE:** Enables or disables a function without changing its configuration. Useful for temporary disabling during maintenance or debugging.\n\n**Required Query Parameters:**\n- `type`: Function type - \"decoder\", \"rule\", \"storage\", \"transformation\", \"scheduled\"\n- `enabled`: Boolean - true to enable, false to disable\n\n**Behavior:**\n- **Disable:** Function stops executing, data flow continues without it\n- **Enable:** Function resumes execution, applies to new data\n- Status transitions: Active ↔ Disabled\n\n**Use Cases:**\n- Temporarily disable rule during maintenance\n- Test data pipeline without decoder\n- Pause storage function to external system\n- Quick troubleshooting without losing configuration\n\n**Note:** Failed functions must be fixed and enabled via this endpoint to resume","tags":["Functions"],"summary":"Enable/disable a function","parameters":[{"description":"Project ID (UUID format)","name":"project_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Device ID","name":"device_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function ID","name":"function_id","in":"path","required":true,"schema":{"type":"string"}},{"description":"Function type","name":"type","in":"query","required":true,"schema":{"type":"string","enum":["decoder","rule","storage","transformation","scheduled"]}},{"description":"Enable (true) or disable (false)","name":"enabled","in":"query","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Function status updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.SuccessResponse"}}}},"400":{"description":"Invalid parameters - Check enabled boolean and type values","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}},"404":{"description":"Function not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/main.ErrorResponse"}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.qubitro.com/developers/functions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
