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

Using SDK Client in APP Functions

APP mode functions receive an sdk_client parameter that provides direct access to the Taruvi SDK, allowing you to interact with the platform's APIs without manual authentication.

Function Signature with SDK Client

def main(params, user_data, sdk_client):
"""
Main entry point with SDK client access.

Args:
params (dict): Input parameters from API request
user_data (dict): User information (username, email, etc.)
sdk_client: Authenticated Taruvi SDK client instance

Returns:
Any JSON-serializable value
"""
# Use sdk_client to interact with platform APIs
pass

Available SDK Modules

The sdk_client provides access to all Taruvi platform modules:

def main(params, user_data, sdk_client):
# Database operations
users = sdk_client.database.query('users').limit(10).execute()

# Call other functions
result = sdk_client.functions.execute('helper-function', {'key': 'value'})

# Authentication operations
# sdk_client.auth.signInWithToken(token, token_type)

# Storage operations
# sdk_client.storage.upload(bucket, file_path, content)

# Secrets management
# secret = sdk_client.secrets.get('API_KEY')

# Policy operations
# sdk_client.policy.check(resource, action)

# App settings
# settings = sdk_client.app.getSettings()

return {'modules_available': True}

Authentication Modes

The sdk_client is automatically authenticated based on how the function was invoked:

JWT Bearer Token (User Sessions):

# Function automatically receives authenticated client
def main(params, user_data, sdk_client):
# sdk_client is authenticated with JWT token from request
# Can access user-specific resources
current_user = user_data.get('username')
user_records = sdk_client.database.query('user_data').filter(
'owner', current_user
).execute()
return {'user': current_user, 'records': user_records}

API Key (Long-lived Tokens):

# Function receives client authenticated with API key
def main(params, user_data, sdk_client):
# sdk_client authenticated with USER or SYSTEM API key
# Useful for scheduled functions or service-to-service calls
data = sdk_client.database.query('scheduled_reports').execute()
return {'report_count': len(data.get('data', []))}

Unauthenticated Access:

# Function receives unauthenticated client
def main(params, user_data, sdk_client):
# Can only access public endpoints
# Attempting protected operations will raise authentication errors
public_data = sdk_client.database.query('public_content').execute()
return {'public_items': len(public_data.get('data', []))}

Database Operations via SDK

Query Data:

def main(params, user_data, sdk_client):
"""Query database table via SDK client."""
table_name = params.get('table', 'users')

# Query with filters
result = sdk_client.database.query(table_name)\
.filter('status', 'active')\
.limit(10)\
.execute()

return {
'table': table_name,
'count': len(result.get('data', [])),
'data': result
}

Insert Data:

def main(params, user_data, sdk_client):
"""Insert data via SDK client."""
table = params['table']
data = params['data']

result = sdk_client.database.insert(table, data).execute()

return {
'inserted': True,
'result': result
}

Update Data:

def main(params, user_data, sdk_client):
"""Update data via SDK client."""
table = params['table']
record_id = params['id']
updates = params['data']

result = sdk_client.database.update(table, record_id, updates).execute()

return {
'updated': True,
'result': result
}

Function Invocation via SDK

Functions can invoke other functions using the SDK client:

def main(params, user_data, sdk_client):
"""Call another function via SDK client."""
target_function = params.get('target_function')
target_params = params.get('target_params', {})

# Invoke the target function
result = sdk_client.functions.execute(target_function, target_params)

return {
'called': target_function,
'result': result
}

Example: Function Chain

# Function A calls Function B calls Function C
def function_a(params, user_data, sdk_client):
"""Entry point that orchestrates workflow."""
# Call Function B
result_b = sdk_client.functions.execute('function-b', {
'step': 1,
'data': params.get('data')
})

# Process result and call Function C
result_c = sdk_client.functions.execute('function-c', {
'step': 2,
'processed_data': result_b.get('result')
})

return {
'workflow': 'complete',
'step_b': result_b,
'step_c': result_c
}

External Approach: Initialize SDK in Function

While the platform automatically provides an authenticated sdk_client, you can also initialize the SDK manually within your function code:

from taruvi import Client

def main(params, user_data, sdk_client_ignored):
"""Initialize SDK client manually (external approach)."""
# Initialize client
client = Client(
api_url=params['api_url'],
app_slug=params['app_slug'],
mode='sync'
)

# Authenticate if credentials provided
if params.get('jwt_token'):
client = client.auth.signInWithToken(
token=params['jwt_token'],
token_type='jwt'
)
elif params.get('api_key'):
client = client.auth.signInWithToken(
token=params['api_key'],
token_type='api_key'
)

# Use the manually initialized client
data = client.database.query('users').execute()

return {
'initialized': 'external',
'count': len(data.get('data', []))
}
Recommended Approach

Use the automatically provided sdk_client parameter (internal approach) instead of initializing the SDK manually. The platform handles authentication automatically and ensures proper tenant context.

Complete Example: Data Processing Function

def main(params, user_data, sdk_client):
"""
Complete example: Process orders and update inventory.

This function:
1. Queries orders from database
2. Processes each order
3. Updates inventory
4. Calls notification function
"""
# Get parameters
order_status = params.get('status', 'pending')
current_user = user_data.get('username')

print(f"Processing orders for {current_user}")

# Query orders
orders = sdk_client.database.query('orders')\
.filter('status', order_status)\
.filter('assigned_to', current_user)\
.limit(50)\
.execute()

order_data = orders.get('data', [])
processed = []

# Process each order
for order in order_data:
order_id = order.get('id')
items = order.get('items', [])

# Update inventory for each item
for item in items:
inventory_result = sdk_client.database.update(
'inventory',
item['product_id'],
{'quantity': item['quantity'] - item['ordered']}
).execute()

# Update order status
sdk_client.database.update(
'orders',
order_id,
{'status': 'processed', 'processed_by': current_user}
).execute()

# Send notification
sdk_client.functions.execute('send-notification', {
'type': 'email',
'recipient': order.get('customer_email'),
'template': 'order_processed',
'data': {'order_id': order_id}
})

processed.append(order_id)
print(f"Processed order {order_id}")

return {
'success': True,
'processed_count': len(processed),
'processed_orders': processed,
'user': current_user
}

Error Handling with SDK Client

def main(params, user_data, sdk_client):
"""Handle errors gracefully when using SDK client."""
try:
# Attempt database operation
result = sdk_client.database.query('sensitive_data').execute()
return {'success': True, 'data': result}

except Exception as e:
# Handle authentication errors
if 'authentication' in str(e).lower() or 'unauthorized' in str(e).lower():
return {
'success': False,
'error': 'Authentication required',
'message': 'Please provide valid credentials'
}

# Handle other errors
return {
'success': False,
'error': 'Operation failed',
'message': str(e)
}

Best Practices

  1. Use the Provided SDK Client: Always use the sdk_client parameter instead of initializing manually
  2. Check Authentication: Verify user_data if you need specific permissions
  3. Handle Errors: Wrap SDK operations in try-except blocks
  4. Log Progress: Use print() to log important steps (captured in stdout)
  5. Return JSON-Serializable Data: Always return dictionaries, lists, or primitive types
  6. Validate Parameters: Check params before using values

Common Patterns

Read-Process-Write Pattern:

def main(params, user_data, sdk_client):
# Read
data = sdk_client.database.query('input_data').execute()

# Process
processed = [transform(item) for item in data.get('data', [])]

# Write
for item in processed:
sdk_client.database.insert('output_data', item).execute()

return {'processed': len(processed)}

Orchestration Pattern:

def main(params, user_data, sdk_client):
# Step 1: Data validation function
validation = sdk_client.functions.execute('validate-data', params)
if not validation.get('valid'):
return {'error': 'Invalid data'}

# Step 2: Processing function
result = sdk_client.functions.execute('process-data', params)

# Step 3: Notification function
sdk_client.functions.execute('send-notification', {
'message': f"Processed {result.get('count')} items"
})

return result

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