Skip to main content

Functions API

The Functions API enables you to create, manage, and execute serverless functions on the Taruvi Cloud platform. Functions can forward requests to external webhooks, execute custom Python code in a secure sandbox, or call predefined system functions.

Overview

The Functions module provides a flexible serverless execution environment with three execution modes:

  • PROXY Mode: Forward requests to external webhook services (Zapier, n8n, Make, etc.)
  • APP Mode: Execute custom Python code in a secure, sandboxed environment
  • SYSTEM Mode: Call predefined internal functions for common operations

Key Features

  • 🚀 Multiple Execution Modes: Choose the right execution model for your use case
  • 🔒 Secure Sandboxing: APP mode uses RestrictedPython for safe code execution
  • Scheduled Execution: Run functions on cron schedules
  • 📊 Execution History: Track all function invocations with detailed results
  • 🔄 Version Control: Manage multiple code versions with easy activation
  • 🔐 Authentication: Flexible auth configuration for webhook integrations
  • 🏢 Multi-tenant: Complete data isolation per tenant

Architecture

graph TD
A[Function] -->|has mode| B[PROXY/APP/SYSTEM]
A -->|has many| C[Code Versions]
A -->|creates| D[Invocation Records]
D -->|tracks| E[Celery Task]
E -->|stores| F[Task Result]
A -->|can have| G[Schedule]
G -->|triggers| H[Periodic Task]

Base URL Structure

All Functions endpoints follow this pattern:

/api/functions/                                    # Function management
/api/functions/{slug}/ # Function details
/api/functions/{slug}/execute/ # Execute function
/api/functions/{slug}/executions/ # Execution history
/api/functions/{slug}/code/ # Code management
/api/functions/code/ # Code version CRUD
/api/functions/invocations/ # Invocation records

Quick Start

1. Create a PROXY Function

Forward requests to an external webhook (e.g., Zapier):

POST /api/apps/{app_slug}/functions/
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN

{
"name": "Send Slack Notification",
"execution_mode": "proxy",
"category": "communication",
"webhook_url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"is_active": true
}

Response:

{
"id": 1,
"name": "Send Slack Notification",
"slug": "send-slack-notification",
"execution_mode": "proxy",
"category": "communication",
"webhook_url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"is_active": true,
"created_at": "2024-01-22T09:15:00Z"
}

2. Create an APP Function with Code

Create a function that executes custom Python code:

# Step 1: Create the function
POST /api/apps/{app_slug}/functions/
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN

{
"name": "Calculate Tax",
"execution_mode": "app",
"category": "data_processing",
"environment": "python",
"is_active": true
}

# Step 2: Upload code
POST /api/functions/calculate-tax/code/
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN

{
"version": "1.0.0",
"code": "def main(params, user_data):\n amount = params.get('amount', 0)\n rate = params.get('rate', 0.1)\n tax = amount * rate\n return {'amount': amount, 'tax': tax, 'total': amount + tax}",
"is_active": true
}

3. Execute the Function

POST /api/functions/calculate-tax/execute/
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN

{
"params": {
"amount": 1000,
"rate": 0.15
}
}

Response:

{
"task_id": "abc123-def456-ghi789",
"status": "SUCCESS",
"result": {
"result": {
"amount": 1000,
"tax": 150.0,
"total": 1150.0
},
"stdout": "",
"stderr": "",
"success": true
},
"invocation": {
"id": 1,
"function_name": "Calculate Tax",
"celery_task_id": "abc123-def456-ghi789",
"trigger_type": "api",
"created_at": "2024-01-22T11:30:00Z"
}
}

Execution Modes

PROXY Mode

Forward requests to external webhook services like Zapier, n8n, or Make.

Configuration:

{
"execution_mode": "proxy",
"webhook_url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"auth_config": {
"type": "bearer",
"token": "your-secret-token"
},
"headers": {
"X-Custom-Header": "value"
},
"config": {
"timeout": 30
}
}

Authentication Types:

  • bearer: Bearer token authentication
  • api_key: API key in custom header
  • basic: Basic authentication (username:password)
  • custom: Custom headers

Payload Sent to Webhook:

{
"params": {
"user_provided": "parameters"
},
"context": {
"function": {
"name": "Function Name",
"slug": "function-slug",
"category": "integration"
},
"user": {
"id": 3,
"username": "john.doe",
"email": "[email protected]"
}
}
}

APP Mode

Execute custom Python code in a secure sandbox.

Code Structure:

def main(params, user_data):
"""
Main entry point for your function.

Args:
params (dict): Input parameters from API request
context (dict): Execution context with function and user metadata

Returns:
Any JSON-serializable value
"""
# Your code here
name = params.get('name', 'World')
user = context['user']['username']

print(f"Executed by {user}") # Captured in stdout

return {
'message': f'Hello, {name}!',
'processed_by': user
}

Available Built-ins:

  • Basic types: int, float, str, bool, list, dict, tuple, set
  • Functions: len, range, enumerate, zip, map, filter, sorted
  • Math: abs, min, max, sum, round
  • Type checking: isinstance, type
  • I/O: print (captured to stdout)

Security Restrictions:

  • No file system access
  • No network operations
  • No dangerous imports (os, sys, subprocess)
  • No arbitrary attribute access
  • Execution timeout enforced

SYSTEM Mode

Call predefined internal functions managed by platform administrators.

Available System Functions:

  • send_notification: Send email/SMS/push notifications
  • data_processing_job: Trigger data processing pipelines
  • example: Demo function for testing

System functions are registered by administrators and cannot be created via API.

API Endpoints

Function Management

List Functions

Get a paginated list of all functions.

Endpoint: GET /api/apps/{app_slug}/functions/

Query Parameters:

  • execution_mode (optional): Filter by mode (proxy, app, system)
  • category (optional): Filter by category
  • is_active (optional): Filter by active status (true, false)
  • schedule_enabled (optional): Filter by scheduling status
  • search (optional): Search by name, description, or slug
  • ordering (optional): Sort results (name, -created_at, execution_mode)

Example Request:

curl -X GET "https://tenant.taruvi.cloud/api/apps/test-app/functions/?execution_mode=app&is_active=true" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Example Response:

{
"count": 25,
"next": "https://tenant.taruvi.cloud/api/apps/test-app/functions/?page=2",
"previous": null,
"results": [
{
"id": 1,
"name": "Process Invoice",
"slug": "process-invoice",
"environment": "python",
"execution_mode": "app",
"category": "document_processing",
"is_active": true,
"schedule_enabled": false,
"app": 5,
"app_name": "Finance App",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-20T14:22:00Z"
}
]
}

Get Function Details

Retrieve detailed information about a specific function.

Endpoint: GET /api/functions/{slug}/

Example Request:

curl -X GET "https://tenant.taruvi.cloud/api/functions/process-invoice/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Example Response:

{
"id": 1,
"name": "Process Invoice",
"slug": "process-invoice",
"environment": "python",
"execution_mode": "app",
"category": "document_processing",
"description": "Extracts data from invoice PDFs and stores in database",
"app": 5,
"app_name": "Finance App",
"is_active": true,
"webhook_url": "",
"auth_config": {},
"headers": {},
"config": {
"timeout": 300,
"max_retries": 3
},
"schedule_enabled": false,
"cron_expression": "",
"schedule_params": {},
"active_code": {
"id": 10,
"version": "1.2.0",
"code": "def main(params, user_data):\n # Function code here\n pass",
"is_active": true,
"created_at": "2024-01-20T14:22:00Z",
"created_by": 3,
"created_by_username": "john.doe"
},
"code_versions": [
{
"id": 10,
"version": "1.2.0",
"is_active": true,
"created_at": "2024-01-20T14:22:00Z"
}
],
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-20T14:22:00Z"
}

Create Function

Create a new function.

Endpoint: POST /api/apps/{app_slug}/functions/

Request Body:

{
"name": "Send Welcome Email",
"environment": "python",
"execution_mode": "proxy",
"category": "communication",
"description": "Sends welcome email to new users via Zapier",
"webhook_url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"auth_config": {
"type": "bearer",
"token": "your-secret-token"
},
"headers": {
"X-Custom-Header": "value"
},
"config": {
"timeout": 30
},
"is_active": true
}

Example Request:

curl -X POST "https://tenant.taruvi.cloud/api/apps/test-app/functions/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Send Welcome Email",
"execution_mode": "proxy",
"webhook_url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/"
}'

Update Function

Update an existing function.

Endpoint: PATCH /api/functions/{slug}/

Request Body (partial update):

{
"description": "Updated description",
"is_active": false,
"config": {
"timeout": 60,
"max_retries": 5
}
}

Example Request:

curl -X PATCH "https://tenant.taruvi.cloud/api/functions/send-welcome-email/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"is_active": false}'

Delete Function

Delete a function and all associated data.

Endpoint: DELETE /api/functions/{slug}/

Example Request:

curl -X DELETE "https://tenant.taruvi.cloud/api/functions/send-welcome-email/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response: 204 No Content

Get Function History

Retrieve the change history for a function.

Endpoint: GET /api/functions/{slug}/history/

Example Response:

[
{
"history_id": 45,
"history_date": "2024-01-20T14:22:00Z",
"history_type": "Changed",
"history_user": "john.doe",
"name": "Process Invoice",
"slug": "process-invoice",
"execution_mode": "app",
"is_active": true,
"schedule_enabled": false
}
]

Aggregate Functions

Get functions from all sources (database + system registry).

Endpoint: GET /api/functions/aggregate/

Example Response:

{
"database_functions": [
{
"id": 1,
"name": "Process Invoice",
"slug": "process-invoice",
"execution_mode": "app"
}
],
"system_functions": [
{
"id": null,
"name": "send_notification",
"slug": "send_notification",
"execution_mode": "system",
"is_active": true
}
],
"total": 2
}

Code Management (APP Mode)

Create Code Version

Upload a new code version for an APP mode function.

Endpoint: POST /api/functions/{slug}/code/

Request Body:

{
"version": "1.3.0",
"code": "def main(params, user_data):\n name = params.get('name', 'World')\n return {'message': f'Hello, {name}!'}",
"is_active": true
}

Example Request:

curl -X POST "https://tenant.taruvi.cloud/api/functions/process-invoice/code/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"version": "1.3.0",
"code": "def main(params, user_data):\n return {\"status\": \"success\"}",
"is_active": true
}'

Example Response:

{
"id": 11,
"function": 1,
"version": "1.3.0",
"code": "def main(params, user_data):\n return {\"status\": \"success\"}",
"is_active": true,
"created_at": "2024-01-22T10:00:00Z",
"created_by": 3,
"created_by_username": "john.doe"
}
Code Requirements

Your code must define a main function that accepts two parameters:

  • params: Dictionary of input parameters
  • context: Dictionary with function and user metadata

The function should return a dictionary or any JSON-serializable value.

Update Active Code

Update the currently active code version.

Endpoint: PATCH /api/functions/{slug}/code/

Request Body:

{
"code": "def main(params, user_data):\n # Updated code\n return {'updated': True}"
}

List Code Versions

Get all code versions for a function.

Endpoint: GET /api/functions/code/?function__slug={slug}

Example Response:

{
"count": 3,
"results": [
{
"id": 11,
"function": 1,
"version": "1.3.0",
"is_active": true,
"created_at": "2024-01-22T10:00:00Z",
"created_by_username": "john.doe"
}
]
}

Activate Code Version

Set a specific code version as active.

Endpoint: POST /api/functions/code/{id}/activate/

Example Request:

curl -X POST "https://tenant.taruvi.cloud/api/functions/code/10/activate/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Function Execution

Execute Function

Execute a function and wait for the result (synchronous).

Endpoint: POST /api/functions/{slug}/execute/

Request Body:

{
"params": {
"name": "John Doe",
"email": "[email protected]",
"amount": 150.00
}
}

Example Request:

curl -X POST "https://tenant.taruvi.cloud/api/functions/process-invoice/execute/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"params": {
"invoice_id": "INV-2024-001",
"amount": 1500.00
}
}'

Example Response (Success):

{
"task_id": "abc123-def456-ghi789",
"status": "SUCCESS",
"result": {
"result": {
"invoice_processed": true,
"total_amount": 1500.00,
"line_items": 5
},
"stdout": "Processing invoice INV-2024-001\n",
"stderr": "",
"success": true
},
"invocation": {
"id": 42,
"function_name": "Process Invoice",
"celery_task_id": "abc123-def456-ghi789",
"trigger_type": "api",
"created_at": "2024-01-22T11:30:00Z"
}
}

Example Response (Error):

{
"error": "Function execution failed: SandboxError: Code must define a 'main' function"
}
Timeout

The execute endpoint waits up to 5 minutes for the function to complete. For long-running functions, consider using async execution and polling for results.

Get Execution History

Retrieve execution history for a function.

Endpoint: GET /api/functions/{slug}/executions/

Query Parameters:

  • limit (optional): Number of results (default: 100)
  • offset (optional): Pagination offset (default: 0)

Example Request:

curl -X GET "https://tenant.taruvi.cloud/api/functions/process-invoice/executions/?limit=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Example Response:

{
"count": 150,
"limit": 10,
"offset": 0,
"results": [
{
"id": 42,
"function_name": "Process Invoice",
"celery_task_id": "abc123-def456-ghi789",
"task_status": "SUCCESS",
"user_username": "john.doe",
"trigger_type": "api",
"created_at": "2024-01-22T11:30:00Z"
}
]
}

Get Execution Result

Retrieve the result of a specific execution by task ID.

Endpoint: GET /api/functions/result/{task_id}/

Example Request:

curl -X GET "https://tenant.taruvi.cloud/api/functions/result/abc123-def456-ghi789/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Example Response:

{
"task_id": "abc123-def456-ghi789",
"status": "SUCCESS",
"result": {
"result": {
"invoice_processed": true,
"total_amount": 1500.00
},
"stdout": "Processing complete\n",
"stderr": "",
"success": true
},
"traceback": null,
"date_created": "2024-01-22T11:30:00Z",
"date_done": "2024-01-22T11:30:15Z"
}

Task Statuses:

  • PENDING: Task is waiting to be executed
  • STARTED: Task has started execution
  • SUCCESS: Task completed successfully
  • FAILURE: Task failed with an error
  • RETRY: Task is being retried after failure

Invocation Records

List Invocations

Get all function invocations with optional filters.

Endpoint: GET /api/functions/invocations/

Query Parameters:

  • function_id (optional): Filter by function ID
  • function_slug (optional): Filter by function slug
  • trigger_type (optional): Filter by trigger type (api, schedule)
  • user_id (optional): Filter by user ID

Example Request:

curl -X GET "https://tenant.taruvi.cloud/api/functions/invocations/?function_slug=process-invoice&trigger_type=api" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Get Invocation Details

Retrieve details of a specific invocation.

Endpoint: GET /api/functions/invocations/{id}/

Example Response:

{
"id": 42,
"function_name": "Process Invoice",
"celery_task_id": "abc123-def456-ghi789",
"task_status": "SUCCESS",
"user_username": "john.doe",
"trigger_type": "api",
"created_at": "2024-01-22T11:30:00Z"
}

Get Invocation Result

Get the execution result for a specific invocation.

Endpoint: GET /api/functions/invocations/{id}/result/

Example Response:

{
"invocation": {
"id": 42,
"function_name": "Process Invoice",
"celery_task_id": "abc123-def456-ghi789",
"trigger_type": "api"
},
"task_result": {
"task_id": "abc123-def456-ghi789",
"status": "SUCCESS",
"result": {
"invoice_processed": true
},
"date_done": "2024-01-22T11:30:15Z"
}
}

Get Invocation by Task ID

Retrieve invocation and result by Celery task ID.

Endpoint: GET /api/functions/invocations/by-task-id/{task_id}/

Example Request:

curl -X GET "https://tenant.taruvi.cloud/api/functions/invocations/by-task-id/abc123-def456-ghi789/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Scheduling

Enable scheduled execution using cron expressions.

Configuration:

{
"schedule_enabled": true,
"cron_expression": "0 * * * *",
"schedule_params": {
"report_type": "daily",
"recipients": ["[email protected]"]
}
}

Cron Expression Format:

* * * * *
│ │ │ │ │
│ │ │ │ └─ Day of week (0-6, Sunday=0)
│ │ │ └─── Month (1-12)
│ │ └───── Day of month (1-31)
│ └─────── Hour (0-23)
└───────── Minute (0-59)

Examples:

  • 0 * * * * - Every hour
  • 0 0 * * * - Daily at midnight
  • 0 9 * * 1 - Every Monday at 9 AM
  • */15 * * * * - Every 15 minutes
  • 0 0 1 * * - First day of every month

Enable Scheduling:

curl -X PATCH "https://tenant.taruvi.cloud/api/functions/calculate-tax/" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule_enabled": true,
"cron_expression": "0 0 * * *",
"schedule_params": {
"amount": 5000,
"rate": 0.15
}
}'

Use Cases

Webhook Integration

Forward API requests to external automation platforms:

# Create PROXY function
POST /api/apps/{app_slug}/functions/
{
"name": "Zapier Integration",
"execution_mode": "proxy",
"webhook_url": "https://hooks.zapier.com/...",
"auth_config": {"type": "bearer", "token": "secret"}
}

# Execute
POST /api/functions/zapier-integration/execute/
{
"params": {"event": "user_signup", "user_id": 123}
}

Custom Business Logic

Execute custom Python code for data processing:

# Create APP function with code
POST /api/apps/{app_slug}/functions/
{"name": "Data Transformer", "execution_mode": "app"}

POST /api/functions/data-transformer/code/
{
"version": "1.0.0",
"code": "def main(params, user_data):\n data = params['data']\n return {'transformed': [x * 2 for x in data]}",
"is_active": true
}

# Execute
POST /api/functions/data-transformer/execute/
{"params": {"data": [1, 2, 3, 4, 5]}}

Scheduled Reports

Generate and send reports on a schedule:

# Create function
POST /api/apps/{app_slug}/functions/
{"name": "Daily Report", "execution_mode": "app"}

# Add code
POST /api/functions/daily-report/code/
{
"version": "1.0.0",
"code": "def main(params, user_data):\n # Generate report logic\n return {'report': 'generated'}",
"is_active": true
}

# Enable scheduling
PATCH /api/functions/daily-report/
{
"schedule_enabled": true,
"cron_expression": "0 9 * * *",
"schedule_params": {"format": "pdf"}
}

Error Handling

Common Error Responses

400 Bad Request:

{
"error": "webhook_url is required for PROXY mode"
}

404 Not Found:

{
"error": "Function with slug 'invalid-slug' not found or not active"
}

500 Internal Server Error:

{
"error": "Function execution failed: SandboxError: Execution failed"
}

Execution Errors

When a function execution fails, the response includes:

  • status: FAILURE
  • traceback: Detailed error information
  • result: Error message

Best Practices

Security

  • Never expose sensitive credentials in function code
  • Use auth_config for webhook authentication
  • Validate all input parameters in your code
  • Set appropriate timeouts to prevent runaway executions

Performance

  • Keep functions focused on single tasks
  • Use appropriate execution modes (PROXY for external services, APP for custom logic)
  • Set reasonable timeout values in config
  • Monitor execution history for performance issues

Code Management

  • Use semantic versioning for code versions (1.0.0, 1.1.0, 2.0.0)
  • Test code thoroughly before activating
  • Keep previous versions for easy rollback
  • Document your code with comments

Scheduling

  • Use specific cron expressions to avoid unnecessary executions
  • Test scheduled functions manually before enabling
  • Monitor scheduled execution results regularly
  • Disable scheduling when functions are not needed

Rate Limiting

API endpoints are rate-limited to ensure platform stability:

  • Authentication endpoints: 10 requests per minute
  • Execution endpoints: 100 requests per minute
  • Other endpoints: 1000 requests per minute

Rate limit headers are included in responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642857600

Tenant Isolation

All Functions operations are tenant-scoped:

  • Functions are completely isolated per tenant
  • No cross-tenant function access
  • Automatic tenant detection from domain/subdomain

Next Steps