Skip to main content
Custom Endpoints let you define serverless-like HTTP endpoints that execute action pipelines — all configured through the REST API. Define a path, choose an HTTP method, configure actions, and your endpoint is live.

Overview

Custom endpoints are dispatched through a dedicated URL namespace:
POST /api/v1/x/{your-slug}/{optional-path}
When a request arrives, SnackBase matches it to an endpoint definition, evaluates authorization conditions, executes the action pipeline, and returns the configured response.

Key Features

  • No Code Required: Define endpoints via API or Admin UI
  • Path Parameters: Support for :param segments (e.g., /users/:user_id/orders)
  • Authorization Conditions: Gate access with rule expressions
  • Action Pipelines: Chain multiple actions with access to results from previous steps
  • Response Templates: Customize response status, body, and headers
  • Execution History: Track every invocation with timing and status

How It Works

┌───────────────┐     ┌──────────────────────────────┐     ┌──────────────┐
│  HTTP Request │     │   Custom Endpoint Dispatcher │     │   Response   │
│               │────>│                              │────>│              │
│  POST /api/v1 │     │  1. Match path + method      │     │  Status code │
│  /x/feedback  │     │  2. Extract path params      │     │  Body        │
│               │     │  3. Check auth (if required) │     │  Headers     │
│               │     │  4. Evaluate condition       │     │              │
│               │     │  5. Execute actions          │     │              │
│               │     │  6. Apply response template  │     │              │
└───────────────┘     └──────────────────────────────┘     └──────────────┘

Endpoint Definition

FieldTypeRequiredDescription
namestringYesHuman-readable name (max 200 chars)
pathstringYesURL path (max 500 chars), e.g., /submit-feedback or /users/:user_id
methodstringYesHTTP method: GET, POST, PUT, PATCH, DELETE
auth_requiredbooleanNoRequire authentication (default: true)
conditionstringNoRule expression — returns 403 if false
actionsarrayNoOrdered list of action configs (default: [])
response_templateobjectNoCustom response format
enabledbooleanNoActive status (default: true)

Path Parameters

Use :param syntax to capture path segments:
/users/:user_id/orders/:order_id
These values are available as {{request.params.user_id}} and {{request.params.order_id}} in action templates.

Uniqueness

Each endpoint is uniquely identified by the combination of (account_id, path, method). You cannot create two endpoints with the same path and method within one account.

Actions

Actions execute sequentially. Each action’s result is available to subsequent actions.

Supported Action Types

Action TypeDescription
send_webhookSend an HTTP request to an external URL
send_emailSend an email
create_recordCreate a record in a collection
update_recordUpdate an existing record
delete_recordDelete a record
enqueue_jobEnqueue a background job
query_recordsQuery records from a collection
aggregate_recordsRun an aggregation (count, sum, avg, min, max)
transformTransform data using a template

Query Records

{
  "type": "query_records",
  "config": {
    "collection": "orders",
    "filter": "customer_id = '{{request.params.customer_id}}'",
    "sort": "-created_at",
    "limit": 10,
    "offset": 0
  }
}

Aggregate Records

{
  "type": "aggregate_records",
  "config": {
    "collection": "orders",
    "function": "sum",
    "field": "total",
    "filter": "status = 'completed'",
    "group_by": "category"
  }
}
Supported functions: count, sum, avg, min, max.

Transform

Reshape data from previous action results:
{
  "type": "transform",
  "config": {
    "output": {
      "total_orders": "{{actions[0].result}}",
      "customer": "{{request.params.customer_id}}"
    }
  }
}

Template Variables

All string values in action configs and response templates support these variables:
VariableDescription
{{request.body.field}}Value from the request body
{{request.query.field}}URL query parameter
{{request.params.field}}Path parameter (from :param segments)
{{auth.user_id}}Authenticated user’s ID
{{auth.email}}Authenticated user’s email
{{auth.account_id}}Account ID
{{actions[N].result}}Result of the Nth action (0-indexed)
{{now}}Current UTC timestamp (ISO 8601)

Response Templates

Customize what your endpoint returns:
{
  "response_template": {
    "status": 200,
    "body": {
      "message": "Feedback received",
      "order_count": "{{actions[0].result}}"
    },
    "headers": {
      "X-Custom-Header": "value"
    }
  }
}
If no response template is configured, the endpoint returns HTTP 200 with the last action’s result as the body.

Authorization

Authentication

Set auth_required: true (the default) to require a valid authentication token. Set to false for public endpoints.

Condition Expressions

Add a condition to control who can access the endpoint:
{
  "condition": "@has_role('admin') or @owns_record()"
}
If the condition evaluates to false, the endpoint returns 403 Forbidden.

Example: Customer Order Summary Endpoint

{
  "name": "Customer Order Summary",
  "path": "/customers/:customer_id/summary",
  "method": "GET",
  "auth_required": true,
  "actions": [
    {
      "type": "query_records",
      "config": {
        "collection": "orders",
        "filter": "customer_id = '{{request.params.customer_id}}'",
        "sort": "-created_at",
        "limit": 5
      }
    },
    {
      "type": "aggregate_records",
      "config": {
        "collection": "orders",
        "function": "sum",
        "field": "total",
        "filter": "customer_id = '{{request.params.customer_id}}'"
      }
    },
    {
      "type": "transform",
      "config": {
        "output": {
          "recent_orders": "{{actions[0].result}}",
          "lifetime_total": "{{actions[1].result}}"
        }
      }
    }
  ],
  "response_template": {
    "status": 200,
    "body": "{{actions[2].result}}"
  }
}
Call it:
curl https://api.snackbase.dev/api/v1/x/customers/cust-123/summary \
  -H "Authorization: Bearer {token}"

Limits

LimitDefault
Max endpoints per account20 (configurable)
Execution timeout30 seconds
Max action execution depth5
Path max length500 characters