Skip to content

Compute Functions Management API

This guide documents the HTTP API for creating, managing, and testing compute functions 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. Authentication
  3. API Endpoints
  4. Draft Workflow
  5. Examples
  6. Error Handling

Overview

Compute functions are JavaScript code blocks that execute in a secure sandbox. The Data Service provides HTTP endpoints to:

  • Create and manage function definitions
  • Update function code
  • Delete functions
  • Test function execution
  • Publish functions from drafts

Base URL

All endpoints are workspace-scoped:

https://your-centrali-instance.com/workspace/{workspace_slug}/api/v1/compute-functions

Replace {workspace_slug} with your workspace identifier.

Authentication

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

Authorization: Bearer <your-jwt-token>

You must have write permission on the compute-functions resource.

API Endpoints

Create Function

Create a new compute function.

Endpoint: POST /workspace/{workspace_slug}/api/v1/compute-functions

Request Body:

{
  "name": "string (required, unique within workspace)",
  "description": "string (optional)",
  "code": "string (required, JavaScript code)"
}

Example Request:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/compute-functions" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "order-processor",
    "description": "Processes new orders and updates inventory",
    "code": "async function run() {\n  const orderId = executionParams.orderId;\n  const order = await api.fetchRecord(orderId);\n  \n  await api.updateRecord(orderId, {\n    status: '\''processed'\'',\n    processedAt: new Date().toISOString()\n  });\n  \n  return { success: true, orderId };\n}"
  }'

Response (201 Created):

{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "order-processor",
  "description": "Processes new orders and updates inventory",
  "code": "async function run() { ... }",
  "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: Function with this name already exists - 401 Unauthorized: Invalid or missing JWT token - 403 Forbidden: Insufficient permissions


Get Function by ID

Retrieve a specific function by its ID.

Endpoint: GET /workspace/{workspace_slug}/api/v1/compute-functions/{function_id}

Example Request:

curl -X GET "https://your-centrali-instance.com/workspace/acme/api/v1/compute-functions/f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response (200 OK):

{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "order-processor",
  "description": "Processes new orders and updates inventory",
  "code": "async function run() { ... }",
  "workspaceSlug": "acme",
  "createdBy": "user-uuid",
  "updatedBy": "user-uuid",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T10:30:00.000Z"
}

Error Responses: - 404 Not Found: Function not found - 400 Bad Request: Invalid function ID format - 401 Unauthorized: Invalid or missing JWT token


List All Functions

Retrieve all functions in the workspace with optional filtering, searching, and pagination.

Endpoint: GET /workspace/{workspace_slug}/api/v1/compute-functions

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, max: 1000) - page (number): Page number, 1-based (default: 1) - sort (JSON array): Sort configuration, e.g., [{"field":"createdAt","direction":"desc"}]

Example Request:

curl -X GET "https://your-centrali-instance.com/workspace/acme/api/v1/compute-functions?limit=50&page=1&search=processor&sort=%5B%7B%22field%22%3A%22createdAt%22%2C%22direction%22%3A%22desc%22%7D%5D" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response (200 OK):

{
  "functions": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "name": "order-processor",
      "description": "Processes new orders and updates inventory",
      "workspaceSlug": "acme",
      "createdAt": "2025-01-15T10:30:00.000Z",
      "updatedAt": "2025-01-15T10:30:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 50
}

Note: The code field is not included in list responses to reduce payload size.


Update Function

Update an existing function's name, description, or code.

Endpoint: PUT /workspace/{workspace_slug}/api/v1/compute-functions/{function_id}

Request Body (all fields optional):

{
  "name": "string (optional)",
  "description": "string (optional)",
  "code": "string (optional)"
}

Example Request:

curl -X PUT "https://your-centrali-instance.com/workspace/acme/api/v1/compute-functions/f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Enhanced order processor with email notifications",
    "code": "async function run() {\n  const orderId = executionParams.orderId;\n  const order = await api.fetchRecord(orderId);\n  \n  await api.updateRecord(orderId, {\n    status: '\''processed'\'',\n    processedAt: new Date().toISOString()\n  });\n  \n  // Send notification\n  await api.httpPost(triggerParams.notificationUrl, {\n    orderId: orderId,\n    status: '\''processed'\''\n  });\n  \n  return { success: true, orderId };\n}"
  }'

Response (200 OK):

{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "order-processor",
  "description": "Enhanced order processor with email notifications",
  "code": "async function run() { ... }",
  "workspaceSlug": "acme",
  "createdBy": "user-uuid",
  "updatedBy": "user-uuid",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "updatedAt": "2025-01-15T11:00:00.000Z"
}

Important: - Updates create a new version automatically for audit trail - If changing the name, the new name must be unique - Active triggers will use the updated code on their next execution

Error Responses: - 404 Not Found: Function not found - 409 Conflict: New name conflicts with existing function - 400 Bad Request: Invalid input data - 401 Unauthorized: Invalid or missing JWT token


Delete Function

Delete a compute function.

Endpoint: DELETE /workspace/{workspace_slug}/api/v1/compute-functions/{function_id}

Example Request:

curl -X DELETE "https://your-centrali-instance.com/workspace/acme/api/v1/compute-functions/f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Response (200 OK):

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

Important: - Deleting a function will prevent associated triggers from executing - Consider deleting or updating triggers before deleting functions - This operation cannot be undone

Error Responses: - 404 Not Found: Function not found - 400 Bad Request: Invalid function ID - 401 Unauthorized: Invalid or missing JWT token


Test Function Execution

Test a function's code before publishing or attaching triggers.

Endpoint: POST /workspace/{workspace_slug}/api/v1/compute-functions/test

Request Body:

{
  "code": "string (required, JavaScript code to test)",
  "params": "object (required, test parameters)"
}

Example Request:

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/compute-functions/test" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "async function run() {\n  const { number } = executionParams;\n  \n  if (!number) {\n    return { success: false, error: '\''number required'\'' };\n  }\n  \n  const result = number * 2;\n  api.log({ message: '\''Calculated result'\'', number, result });\n  \n  return { success: true, result };\n}",
    "params": {
      "number": 21
    }
  }'

Response (200 OK):

{
  "jobId": "test-job-abc123",
  "status": "queued",
  "queuedAt": "2025-01-15T10:40:00.000Z"
}

Retrieving Test Results:

Use the job ID to fetch execution results from the function runs endpoint:

curl -X GET "https://your-centrali-instance.com/workspace/acme/api/v1/function-runs?jobId=test-job-abc123" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Important: - Test executions use the special "default-trigger" system trigger - Test runs are logged and visible in the debug console - The params object becomes executionParams in the function - Test functions have the same sandbox restrictions as production functions

Error Responses: - 400 Bad Request: Missing code or params - 401 Unauthorized: Invalid or missing JWT token


Publish Function from Draft

Publish a function from a draft.

Endpoint: POST /workspace/{workspace_slug}/api/v1/compute-functions/{draft_id}/publish

Example Request:

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

Response (201 Created):

{
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "order-processor",
  "description": "Processes new orders and updates inventory",
  "code": "async function run() { ... }",
  "workspaceSlug": "acme",
  "createdBy": "user-uuid",
  "createdAt": "2025-01-15T10:35:00.000Z",
  "updatedAt": "2025-01-15T10:35:00.000Z"
}

Important: - The draft is deleted after successful publication - Function name must be unique - See Draft Workflow section for details

Error Responses: - 404 Not Found: Draft not found - 409 Conflict: Function name already exists - 400 Bad Request: Invalid draft data - 401 Unauthorized: Invalid or missing JWT token

Draft Workflow

The draft system allows you to create, edit, and review functions before publishing them.

Step 1: Create a Draft

Endpoint: POST /workspace/{workspace_slug}/api/v1/drafts

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/drafts" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceType": "compute-functions",
    "data": {
      "name": "email-validator",
      "description": "Validates email addresses",
      "code": "async function run() {\n  const { email } = executionParams;\n  const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n  const isValid = emailRegex.test(email);\n  \n  return { success: true, valid: isValid };\n}"
    }
  }'

Response:

{
  "id": "draft-12345",
  "resourceType": "compute-functions",
  "data": {
    "name": "email-validator",
    "description": "Validates email addresses",
    "code": "async function run() { ... }"
  },
  "createdBy": "user-uuid",
  "createdAt": "2025-01-15T10:30:00.000Z"
}


Step 2: Update the Draft (Optional)

Endpoint: PUT /workspace/{workspace_slug}/api/v1/drafts/{draft_id}

curl -X PUT "https://your-centrali-instance.com/workspace/acme/api/v1/drafts/draft-12345" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "name": "email-validator",
      "description": "Enhanced email validator with domain check",
      "code": "async function run() {\n  const { email } = executionParams;\n  const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n  const isValid = emailRegex.test(email);\n  \n  if (!isValid) {\n    return { success: false, error: '\''Invalid email format'\'' };\n  }\n  \n  const domain = email.split('\''@'\'')[1];\n  return { success: true, valid: true, domain };\n}"
    }
  }'

Step 3: Test the Draft Code

curl -X POST "https://your-centrali-instance.com/workspace/acme/api/v1/compute-functions/test" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "async function run() { ... }",
    "params": {
      "email": "test@example.com"
    }
  }'

Step 4: Publish the Draft

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

After successful publication, the draft is deleted and the function is active.

Examples

Example 1: Create and Test a Data Validation Function

# 1. Create the function
curl -X POST "https://centrali.example.com/workspace/acme/api/v1/compute-functions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "validate-user-data",
    "description": "Validates user registration data",
    "code": "async function run() {\n  const { email, age, username } = executionParams;\n  const errors = [];\n  \n  const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n  if (!email || !emailRegex.test(email)) {\n    errors.push('\''Invalid email format'\'');\n  }\n  \n  if (!age || age < 18) {\n    errors.push('\''User must be 18 or older'\'');\n  }\n  \n  if (!username || username.length < 3) {\n    errors.push('\''Username must be at least 3 characters'\'');\n  }\n  \n  return {\n    valid: errors.length === 0,\n    errors: errors\n  };\n}"
  }'

# 2. Test the function
curl -X POST "https://centrali.example.com/workspace/acme/api/v1/compute-functions/test" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "async function run() { ... }",
    "params": {
      "email": "john@example.com",
      "age": 25,
      "username": "johndoe"
    }
  }'

Example 2: Update Function Code

# Update the function to add logging
curl -X PUT "https://centrali.example.com/workspace/acme/api/v1/compute-functions/f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "async function run() {\n  const { email, age, username } = executionParams;\n  \n  api.log({ message: '\''Validating user data'\'', email, age, username });\n  \n  const errors = [];\n  \n  const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n  if (!email || !emailRegex.test(email)) {\n    errors.push('\''Invalid email format'\'');\n  }\n  \n  if (!age || age < 18) {\n    errors.push('\''User must be 18 or older'\'');\n  }\n  \n  if (!username || username.length < 3) {\n    errors.push('\''Username must be at least 3 characters'\'');\n  }\n  \n  api.log({ message: '\''Validation complete'\'', errors: errors.length });\n  \n  return {\n    valid: errors.length === 0,\n    errors: errors\n  };\n}"
  }'

Example 3: Using Draft Workflow

# 1. Create draft
DRAFT=$(curl -X POST "https://centrali.example.com/workspace/acme/api/v1/drafts" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceType": "compute-functions",
    "data": {
      "name": "order-notification",
      "description": "Sends order notifications",
      "code": "async function run() {\n  const { orderId } = executionParams;\n  const order = await api.fetchRecord(orderId);\n  \n  await api.httpPost(triggerParams.webhookUrl, {\n    orderId: order.id,\n    status: order.data.status\n  });\n  \n  return { success: true };\n}"
    }
  }' | jq -r '.id')

# 2. Test the draft code
curl -X POST "https://centrali.example.com/workspace/acme/api/v1/compute-functions/test" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "async function run() { ... }",
    "params": {
      "orderId": "order-123"
    }
  }'

# 3. Publish the draft
curl -X POST "https://centrali.example.com/workspace/acme/api/v1/compute-functions/$DRAFT/publish" \
  -H "Authorization: Bearer $TOKEN"

Error Handling

Common Error Responses

400 Bad Request

{
  "error": "Function name 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 not found.",
  "statusCode": 404
}

409 Conflict

{
  "error": "Function with that name already exists.",
  "statusCode": 409
}

500 Internal Server Error

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

Error Handling Best Practices

  1. Check response status codes before processing responses
  2. Log error responses for debugging
  3. Implement retry logic for transient errors (500, 503)
  4. Validate inputs before making requests to avoid 400 errors
  5. Handle 409 conflicts by prompting for a different name

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