Skip to content

Creating Actions

This guide walks you through creating actions on Universal API.

Web UI

Navigate to universalapi.co/actions and click "Create Action".

Required Fields

FieldDescription
Action NameDisplay name for your action
DescriptionWhat the action does
CategoryClassification (Utilities, Communication, etc.)
Runtimepython3.12
Source CodeYour Python handler function

Optional Fields

FieldDefaultDescription
Visibilityprivatepublic, private, or team
Statusdevelopmentdevelopment, active, deprecated
Memory128 MB128, 256, 512, or 1024 MB
Timeout30 sec1-300 seconds
Tags-Keywords for discovery
Keys Needed-Required API keys/OAuth tokens

Code Structure

Every action must have a handler function:

python
def handler(event, context):
    """
    Args:
        event: Contains request data, parameters, and injected keys
        context: Lambda execution context

    Returns:
        dict: Response with statusCode and body
    """
    # Your code here
    return {
        "statusCode": 200,
        "body": {"result": "success"}
    }

The Event Object

The event parameter contains:

python
{
    # Query parameters from URL
    "queryStringParameters": {
        "param1": "value1",
        "param2": "value2"
    },

    # Request body (for POST)
    "body": "...",

    # Your stored API keys (injected by Universal API)
    "keys": {
        "google_oauth": {
            "keyName": "google_oauth",
            "keyValue": "ya29.xxx...",  # Access token
            "secretKeyName": "refresh_token",
            "secretKeyValue": "1//0xxx..."
        },
        "openai": {
            "keyName": "openai",
            "keyValue": "sk-xxx..."
        }
    },

    # Request metadata
    "userId": "user-id",
    "actionId": "act-xxx",
    "headers": {...}
}

Reading Parameters

python
def handler(event, context):
    # From query string (?name=John&count=5)
    params = event.get("queryStringParameters", {}) or {}
    name = params.get("name", "World")
    count = int(params.get("count", 1))

    # From POST body
    import json
    body = event.get("body", "{}")
    if isinstance(body, str):
        body = json.loads(body)

    return {
        "statusCode": 200,
        "body": {"name": name, "count": count}
    }

Using API Keys

python
def handler(event, context):
    # Check if key exists
    if "keys" not in event or "openai" not in event["keys"]:
        return {
            "statusCode": 400,
            "body": {"error": "OpenAI API key not configured"}
        }

    # Get the key
    api_key = event["keys"]["openai"]["keyValue"]

    # Use it
    import requests
    response = requests.post(
        "https://api.openai.com/v1/chat/completions",
        headers={"Authorization": f"Bearer {api_key}"},
        json={"model": "gpt-4", "messages": [{"role": "user", "content": "Hi"}]}
    )

    return {
        "statusCode": 200,
        "body": response.json()
    }

Using OAuth Tokens

python
def handler(event, context):
    # Check for Google OAuth
    if "keys" not in event or "google_oauth" not in event["keys"]:
        return {
            "statusCode": 400,
            "body": {"error": "Please connect your Google account"}
        }

    # Get tokens
    google_oauth = event["keys"]["google_oauth"]
    access_token = google_oauth["keyValue"]

    # Call Google API
    import requests
    response = requests.get(
        "https://www.googleapis.com/drive/v3/files",
        headers={"Authorization": f"Bearer {access_token}"},
        params={"pageSize": 10}
    )

    return {
        "statusCode": 200,
        "body": response.json()
    }

Creating via API

bash
curl -X POST "https://api.universalapi.co/action/create" \
  -H "Content-Type: application/json" \
  -H "X-Uni-UserId: your-user-id" \
  -H "X-Uni-SecretUniversalKey: your-secret-key" \
  -d '{
    "actionName": "My Action",
    "description": "Does something useful",
    "category": "Utilities",
    "runtime": "python3.12",
    "visibility": "private",
    "sourceCode": "def handler(event, context):\n    return {\"statusCode\": 200, \"body\": {\"message\": \"Hello!\"}}"
  }'

Available Python Packages

Actions have access to:

  • requests - HTTP library
  • boto3 - AWS SDK
  • json, datetime, re - Standard library
  • And more common packages

Error Handling

python
def handler(event, context):
    try:
        # Your code
        result = do_something()
        return {
            "statusCode": 200,
            "body": {"result": result}
        }
    except ValueError as e:
        return {
            "statusCode": 400,
            "body": {"error": f"Invalid input: {str(e)}"}
        }
    except Exception as e:
        return {
            "statusCode": 500,
            "body": {"error": f"Internal error: {str(e)}"}
        }

Best Practices

  1. Validate inputs - Check parameters before using them
  2. Handle missing keys - Always check if API keys exist
  3. Use timeouts - Set appropriate timeouts for external calls
  4. Return meaningful errors - Help users understand what went wrong
  5. Keep it focused - One action, one purpose

Next Steps

Universal API - The agentic entry point to the universe of APIs