Documentation Index
Fetch the complete documentation index at: https://docs.snackbase.dev/llms.txt
Use this file to discover all available pages before exploring further.
This guide walks you through creating custom HTTP endpoints that execute action pipelines — without writing backend code.
Prerequisites
Building Your First Endpoint
Design Your Endpoint
Plan what the endpoint does:GET /api/v1/x/customers/:customer_id/summary
1. Query recent orders for this customer
2. Calculate total spend
3. Return combined summary
Create the Endpoint
const endpoint = await client.endpoints.create({
name: "Customer 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_spend: "{{actions[1].result}}",
},
},
},
],
response_template: {
status: 200,
body: "{{actions[2].result}}",
},
});
curl -X POST https://api.snackbase.dev/api/v1/endpoints \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer 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
}
}
]
}'
Test the Endpoint
Call your new endpoint:curl https://api.snackbase.dev/api/v1/x/customers/cust-123/summary \
-H "Authorization: Bearer {token}"
Expected response:{
"recent_orders": [...],
"lifetime_spend": { "value": 2450.00 }
}
Add Authorization
Use a condition expression to restrict access:const endpoint = await client.endpoints.update(endpoint.id, {
condition: "@has_role('admin') or auth.user_id = request.params.customer_id",
});
If the condition evaluates to false, the endpoint returns 403 Forbidden. Monitor Execution History
Track how your endpoint is being used:const executions = await client.endpoints.listExecutions(endpoint.id);
for (const exec of executions.items) {
console.log(`${exec.status} - ${exec.duration_ms}ms`);
}
More Examples
Accept form data and create a record:
await client.endpoints.create({
name: "Submit Feedback",
path: "/submit-feedback",
method: "POST",
auth_required: false, // Public endpoint
actions: [
{
type: "create_record",
config: {
collection: "feedback",
data: {
message: "{{request.body.message}}",
email: "{{request.body.email}}",
submitted_at: "{{now}}",
},
},
},
],
response_template: {
status: 201,
body: { message: "Thank you for your feedback!" },
},
});
Dashboard Data Endpoint
Aggregate data for a dashboard:
await client.endpoints.create({
name: "Sales Dashboard",
path: "/dashboard/sales",
method: "GET",
auth_required: true,
condition: "@has_role('admin')",
actions: [
{
type: "aggregate_records",
config: {
collection: "orders",
function: "count",
filter: "status = 'completed'",
},
},
{
type: "aggregate_records",
config: {
collection: "orders",
function: "sum",
field: "total",
filter: "status = 'completed'",
},
},
{
type: "aggregate_records",
config: {
collection: "orders",
function: "sum",
field: "total",
filter: "status = 'completed'",
group_by: "category",
},
},
{
type: "transform",
config: {
output: {
total_orders: "{{actions[0].result}}",
total_revenue: "{{actions[1].result}}",
revenue_by_category: "{{actions[2].result}}",
},
},
},
],
response_template: {
status: 200,
body: "{{actions[3].result}}",
},
});
Troubleshooting
404 when calling the endpoint
- Verify the endpoint is
enabled
- Check the URL format:
/api/v1/x/{path} (note the /x/ prefix)
- Confirm the HTTP method matches (GET, POST, etc.)
- Check path parameter syntax uses
:param format
- The
condition expression evaluated to false
- If
auth_required is true, ensure you’re sending a valid auth token
- Another endpoint with the same
path and method already exists
- Each (path, method) combination must be unique per account
Endpoints have a 30-second execution timeout. If your action pipeline is complex, consider:
- Reducing query
limit values
- Simplifying filter expressions
- Breaking complex logic into separate endpoints
Next Steps