Skip to content

Function Triggers Management API

This guide documents the HTTP API for creating, managing, and executing function triggers in Centrali. This API is provided by the Data Service.

Note: For information on writing function code, see FUNCTION_CODE_GUIDE.md in the Compute Service documentation.

Table of Contents

  1. Overview
  2. Trigger Types
  3. Authentication
  4. API Endpoints
  5. Event-Driven Triggers
  6. Examples
  7. Error Handling

Overview

Function triggers define when and how compute functions execute. Centrali supports four trigger types:

  • On-Demand: Manual execution via API
  • Event-Driven: Automatic execution when data events occur
  • Scheduled: Time-based execution at regular intervals
  • Webhook: HTTP endpoint triggers

Base URL

All endpoints are workspace-scoped:

https://your-centrali-instance.com/workspace/{workspace_slug}/api/v1/function-triggers

Replace {workspace_slug} with your workspace identifier.

Trigger Types

1. On-Demand Triggers

Executed manually via API call.

Trigger Metadata:

{
  "params": {
    "key": "value"
  }
}

Use Cases: - Admin operations - Manual data processing - Testing - User-initiated actions


2. Event-Driven Triggers

Executed automatically when specific record events occur.

Trigger Metadata:

{
  "event": "record_created",
  "recordSlug": "orders",
  "params": {
    "key": "value"
  }
}

Required Fields: - event: Event type (see Supported Events) - recordSlug: Record type to monitor

Use Cases: - Real-time data synchronization - Automated workflows - Cascading updates - Event-based notifications


3. Scheduled Triggers

Executed at regular time intervals.

Trigger Metadata:

{
  "interval": 3600,
  "params": {
    "key": "value"
  }
}

Required Fields: - interval: Time in seconds between executions

Use Cases: - Periodic backups - Daily/hourly reports - Cleanup operations - Batch processing

Common Intervals: - Every minute: 60 - Every 5 minutes: 300 - Every hour: 3600 - Every 6 hours: 21600 - Daily: 86400 - Weekly: 604800


4. Webhook Triggers

HTTP endpoints that execute functions when called externally.

Trigger Metadata:

{
  "path": "/payment-callback",
  "params": {
    "key": "value"
  }
}

Required Fields: - path: Webhook URL path

Webhook URL Format:

https://your-centrali-instance.com/workspace/{workspace_slug}/api/v1/webhook{path}

Use Cases: - Third-party integrations - Payment gateway callbacks - External API webhooks - Incoming notifications

Authentication

All requests require a valid JWT token in the Authorization header:

Authorization: Bearer <your-jwt-token>

You must have write permission on the function-triggers resource.

API Endpoints

Create Trigger

Create a new function trigger.

Endpoint: POST /workspace/{workspace_slug}/api/v1/function-triggers

Request Body:

{
  "name": "string (required, unique within workspace)",
  "description": "string (optional)",
  "functionId": "string (required, UUID of compute function)",
  "executionType": "on-demand | event-driven | scheduled | webhook",
  "triggerMetadata": {
    "params": {},
    // Additional fields based on executionType
  }
}

Example - On-Demand Trigger:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "manual-export",
    "description": "Manual data export trigger",
    "functionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "executionType": "on-demand",
    "triggerMetadata": {
      "params": {
        "format": "csv",
        "includeArchived": false
      }
    }
  }'

Response (201 Created):

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "manual-export",
  "description": "Manual data export trigger",
  "functionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "executionType": "on-demand",
  "triggerMetadata": {
    "params": {
      "format": "csv",
      "includeArchived": false
    }
  },
  "workspaceSlug": "acme",
  "createdBy": "user-uuid",
  "updatedBy": "user-uuid",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

Error Responses: - 400 Bad Request: Missing required fields or invalid data - 409 Conflict: Trigger with this name already exists - 401 Unauthorized: Invalid or missing JWT token - 403 Forbidden: Insufficient permissions


Get Trigger by ID

Retrieve a specific trigger by its ID.

Endpoint: GET /workspace/{workspace_slug}/api/v1/function-triggers/{trigger_id}

Example Request:

curl -X GET "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response (200 OK):

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "manual-export",
  "description": "Manual data export trigger",
  "functionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "executionType": "on-demand",
  "triggerMetadata": {
    "params": {
      "format": {
        "value": "...",
        "encrypted": true,
        "keyVersion": 1
      }
    }
  },
  "workspaceSlug": "acme",
  "createdBy": "user-uuid",
  "updatedBy": "user-uuid",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

Note: Encrypted parameters appear in encrypted format. The system automatically decrypts them before function execution.


List All Triggers

Retrieve all triggers in the workspace.

Endpoint: GET /workspace/{workspace_slug}/api/v1/function-triggers

Query Parameters: - search (string): Search term to filter by name - searchField (string): Field to search in (default: "name") - limit (number): Results per page (default: 500) - page (number): Page number, 1-based (default: 1) - sort (JSON array): Sort configuration

Example Request:

curl -X GET "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers?limit=50&page=1" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response (200 OK):

{
  "triggers": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "manual-export",
      "executionType": "on-demand",
      "functionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "createdAt": "2025-01-15T10:30:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 50
}


Update Trigger

Update an existing trigger.

Endpoint: PUT /workspace/{workspace_slug}/api/v1/function-triggers/{trigger_id}

Request Body (all fields optional):

{
  "name": "string (optional)",
  "description": "string (optional)",
  "triggerMetadata": {
    "params": {},
    // Other fields based on executionType
  }
}

Example Request:

curl -X PUT "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Updated export trigger with new format",
    "triggerMetadata": {
      "params": {
        "format": "json",
        "includeMetadata": true
      }
    }
  }'

Important: - For scheduled triggers: Updating interval automatically updates the scheduler - Updates create new versions for audit trail - Cannot update executionType (delete and recreate instead) - System default trigger cannot be updated


Delete Trigger

Delete a function trigger.

Endpoint: DELETE /workspace/{workspace_slug}/api/v1/function-triggers/{trigger_id}

Example Request:

curl -X DELETE "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response (200 OK):

{
  "success": true,
  "message": "Trigger deleted successfully"
}

Important: - Scheduled triggers are automatically removed from the scheduler - System default trigger cannot be deleted - This operation cannot be undone


Execute On-Demand Trigger

Manually execute an on-demand trigger.

Endpoint: POST /workspace/{workspace_slug}/api/v1/function-triggers/{trigger_id}/execute

Request Body (optional):

The request body is passed directly to the function as executionParams. This is not wrapped in a params key - the entire body becomes executionParams.

{
  "orderId": "4f20dbde-167d-4f18-8271-a4b94ab0be85",
  "packageType": "medium",
  "adminUserId": "user_123"
}

Example Request:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers/a1b2c3d4-e5f6-7890-abcd-ef1234567890/execute" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "4f20dbde-167d-4f18-8271-a4b94ab0be85",
    "packageType": "medium",
    "adminUserId": "user_123"
  }'

Response (200 OK):

"job-abc123-def456-7890"

The response is the job ID for tracking the execution.

How the Payload is Accessed in Your Function:

The request body is available as executionParams in your function code:

async function run() {
  // Request body from /execute endpoint is in executionParams
  const orderId = executionParams.orderId;         // "4f20dbde-..."
  const packageType = executionParams.packageType; // "medium"
  const adminUserId = executionParams.adminUserId; // "user_123"

  // triggerParams contains the static config from trigger creation
  const apiKey = triggerParams.apiKey;

  api.log({ message: 'Processing', orderId, packageType });

  return { success: true };
}

Important: - Only works for on-demand triggers - The request body becomes executionParams in the function - triggerParams contains the static configuration from trigger metadata - See Function Code Guide for detailed examples


Publish Trigger from Draft

Publish a trigger from a draft.

Endpoint: POST /workspace/{workspace_slug}/api/v1/function-triggers/{draft_id}/publish

Example Request:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers/draft-12345/publish" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response (201 Created):

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "nightly-cleanup",
  "executionType": "scheduled",
  "triggerMetadata": {
    "interval": 86400
  },
  "workspaceSlug": "acme",
  "createdAt": "2025-01-15T10:35:00.000Z"
}

Event-Driven Triggers

Event-driven triggers execute automatically when record events occur.

Supported Events

Centrali currently supports the following record events:

Event Description When Triggered
record_created New record created After successful record creation
record_updated Record updated After successful record update
record_deleted Record deleted After successful record deletion (soft or hard)
record_restored Deleted record restored After successful record restoration
record_reverted Record reverted to previous version After successful version rollback
record_create_failed Record creation failed When record creation fails
record_updated_failed Record update failed When record update fails
record_deleted_failed Record deletion failed When record deletion fails

Event Payload

Functions triggered by events receive the event data in executionParams:

async function run() {
  const event = executionParams;

  // Event structure:
  // {
  //   event: "record_created",
  //   workspaceSlug: "acme",
  //   recordSlug: "orders",
  //   recordId: "rec-123",
  //   data: { ... },  // The record data
  //   timestamp: "2025-01-15T10:30:00.000Z"
  // }

  api.log({
    message: `Processing ${event.event} for ${event.recordSlug}`,
    recordId: event.recordId
  });

  return { success: true };
}

Creating Event-Driven Trigger

Example - Trigger on New Orders:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "new-order-processor",
    "description": "Process new orders when created",
    "functionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "executionType": "event-driven",
    "triggerMetadata": {
      "event": "record_created",
      "recordSlug": "orders",
      "params": {
        "notifyWarehouse": true,
        "updateInventory": true
      }
    }
  }'

Example - Trigger on Record Updates:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "order-status-change",
    "description": "Handle order status changes",
    "functionId": "a2b3c4d5-e6f7-8901-bcde-f12345678901",
    "executionType": "event-driven",
    "triggerMetadata": {
      "event": "record_updated",
      "recordSlug": "orders",
      "params": {
        "sendNotification": true
      }
    }
  }'

Parameter Encryption

Sensitive parameters (API keys, secrets) can be encrypted at rest.

Encrypting Parameters

Add "encrypt": true to parameter values:

{
  "triggerMetadata": {
    "params": {
      "apiKey": {
        "value": "sk_live_abc123def456",
        "encrypt": true
      },
      "webhookSecret": {
        "value": "whsec_xyz789",
        "encrypt": true
      }
    }
  }
}

Example Request:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "payment-processor",
    "functionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "executionType": "webhook",
    "triggerMetadata": {
      "path": "/stripe-webhook",
      "params": {
        "provider": "stripe",
        "signingSecret": {
          "value": "whsec_abcdef123456",
          "encrypt": true
        }
      }
    }
  }'

How Encryption Works

  1. On Creation: System encrypts the value using AES-256-GCM
  2. On Storage: Encrypted format stored in database
  3. On Retrieval: Values remain encrypted in API responses
  4. On Execution: System automatically decrypts before passing to function

Security: Only the compute runtime can decrypt values. Users cannot retrieve plaintext secrets via API.

Examples

Example 1: Event-Driven Trigger for New Records

curl -X POST "https://centrali.example.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "new-customer-welcome",
    "description": "Send welcome email to new customers",
    "functionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "executionType": "event-driven",
    "triggerMetadata": {
      "event": "record_created",
      "recordSlug": "customers",
      "params": {
        "emailTemplate": "welcome",
        "sendImmediately": true,
        "emailServiceApiKey": {
          "value": "key_abc123",
          "encrypt": true
        }
      }
    }
  }'

Example 2: Scheduled Daily Report

curl -X POST "https://centrali.example.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "daily-sales-report",
    "description": "Generate daily sales report at midnight",
    "functionId": "a2b3c4d5-e6f7-8901-bcde-f12345678901",
    "executionType": "scheduled",
    "triggerMetadata": {
      "interval": 86400,
      "params": {
        "reportType": "sales_summary",
        "includeCharts": true,
        "recipients": [
          "sales@acme.com",
          "manager@acme.com"
        ]
      }
    }
  }'

Example 3: Webhook for Payment Gateway

curl -X POST "https://centrali.example.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "stripe-payment-webhook",
    "description": "Handle Stripe payment events",
    "functionId": "b3c4d5e6-f7g8-9012-cdef-123456789012",
    "executionType": "webhook",
    "triggerMetadata": {
      "path": "/webhooks/stripe",
      "params": {
        "provider": "stripe",
        "validateSignature": true,
        "signingSecret": {
          "value": "whsec_abcdef123456",
          "encrypt": true
        }
      }
    }
  }'

Webhook URL: https://centrali.example.com/workspace/acme/api/v1/webhook/webhooks/stripe


Example 4: Manual On-Demand Trigger

# Create trigger with static configuration (triggerParams)
curl -X POST "https://centrali.example.com/workspace/acme/api/v1/function-triggers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "manual-migration",
    "description": "Manually trigger data migration",
    "functionId": "c4d5e6f7-g8h9-0123-defg-234567890123",
    "executionType": "on-demand",
    "triggerMetadata": {
      "params": {
        "sourceSystem": "legacy_db",
        "targetSystem": "centrali",
        "batchSize": 1000
      }
    }
  }'

# Execute trigger with runtime data (executionParams)
# Note: The body is passed directly as executionParams, NOT wrapped in "params"
TRIGGER_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"

curl -X POST "https://centrali.example.com/workspace/acme/api/v1/function-triggers/$TRIGGER_ID/execute" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "recordType": "users",
    "startDate": "2025-01-01",
    "dryRun": false
  }'

In the function: - triggerParams.sourceSystem → "legacy_db" (from trigger config) - triggerParams.batchSize → 1000 (from trigger config) - executionParams.recordType → "users" (from execute request) - executionParams.startDate → "2025-01-01" (from execute request) - executionParams.dryRun → false (from execute request)


Example 5: Update Scheduled Trigger Interval

# Update from daily to hourly
curl -X PUT "https://centrali.example.com/workspace/acme/api/v1/function-triggers/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "triggerMetadata": {
      "interval": 3600,
      "params": {
        "reportType": "hourly_summary"
      }
    }
  }'

Note: The scheduler is automatically updated when you change the interval.

Error Handling

Common Error Responses

400 Bad Request

{
  "error": "Trigger execution type is required.",
  "statusCode": 400
}

401 Unauthorized

{
  "error": "Invalid or missing authorization token",
  "statusCode": 401
}

403 Forbidden

{
  "error": "Insufficient permissions for this operation",
  "statusCode": 403
}

404 Not Found

{
  "error": "Function trigger not found.",
  "statusCode": 404
}

409 Conflict

{
  "error": "A trigger named 'manual-export' already exists.",
  "statusCode": 409
}

500 Internal Server Error

{
  "error": "An unexpected error occurred",
  "statusCode": 500
}

Event-Driven Trigger Errors

Invalid Event Type:

{
  "error": "Invalid event type: record_invalid",
  "statusCode": 400
}

Supported events: record_created, record_updated, record_deleted, record_restored, record_reverted, record_create_failed, record_updated_failed, record_deleted_failed

Missing recordSlug:

{
  "error": "recordSlug is required for event-driven triggers",
  "statusCode": 400
}

Scheduled Trigger Errors

Invalid Interval:

{
  "error": "Interval must be a number.",
  "statusCode": 400
}

Missing Interval:

{
  "error": "Interval is required for scheduled triggers.",
  "statusCode": 400
}

Support

For additional help: - Check the Centrali debug console for execution logs - Review function run details for error messages - Contact your workspace administrator - Submit issues to the Centrali support team