Template Syntax
Inject dynamic values into configurations.
Template Format
Templates use double curly braces: {{source.field}}
Sources
Environment Variables
json
"{{env.VARIABLE_NAME}}"Example:
json
{
"jwt": {
"secret": "{{env.JWT_SECRET}}"
}
}Legacy syntax (also supported):
json
"${VARIABLE_NAME}"Request Body
json
"{{body.fieldName}}"Example:
json
{
"data": {
"title": "{{body.title}}",
"content": "{{body.content}}"
}
}Nested fields:
json
"{{body.user.name}}"
"{{body.items[0].id}}"URL Parameters
json
"{{params.paramName}}"For route /users/:id:
json
{
"filters": [{
"column": "id",
"operator": "eq",
"value": "{{params.id}}"
}]
}Query Parameters
json
"{{query.paramName}}"For /search?q=term&limit=10:
json
{
"filters": [{
"column": "name",
"operator": "ilike",
"value": "%{{query.q}}%"
}],
"limit": "{{query.limit}}"
}JWT Claims
json
"{{auth.claimName}}"Available claims:
{{auth.sub}}- Subject (user ID){{auth.role}}- User role{{auth.tenant_id}}- Tenant ID{{auth.email}}- Email (if included)
Example:
json
{
"data": {
"user_id": "{{auth.sub}}",
"created_by": "{{auth.sub}}"
}
}Tenant Context
json
"{{tenant.id}}"
"{{tenant.config.field}}"Secrets
Reference tenant-specific secrets stored securely in the database.
json
"{{secret:API_KEY}}"
"{{secret:STRIPE_SECRET}}"Legacy syntax (also supported):
json
"{{secret.SECRET_KEY}}"Setting Secrets
bash
POST /tenant/secrets
Authorization: Bearer <token>
{
"key": "STRIPE_SECRET",
"value": "sk_live_...",
"metadata": { "description": "Stripe API key" }
}Using in Config
json
{
"credentials": {
"stripe": {
"secretKey": "{{secret:STRIPE_SECRET}}"
}
}
}Secret Rotation
bash
POST /tenant/secrets/rotate
Authorization: Bearer <token>
{
"key": "API_KEY",
"newValue": "new-secret-value",
"gracePeriodDays": 30
}Old secret remains valid during grace period.
Secret Expiration
json
{
"key": "TEMP_TOKEN",
"value": "temporary-value",
"expiresAt": "2024-12-31T23:59:59Z"
}Expired secrets return null when accessed.
Step Results (Workflows)
json
"{{steps.stepId.result}}"
"{{steps.stepId.result.field}}"Input (Workflows)
json
"{{input.fieldName}}"String Concatenation
Templates can be embedded in strings:
json
{
"select": "*, users(name)",
"filters": [{
"column": "name",
"operator": "ilike",
"value": "%{{query.search}}%"
}]
}Default Values
Use JavaScript OR syntax:
json
"{{query.limit || 10}}"Examples
Full Route Example
json
{
"path": "/posts/:id",
"method": "put",
"requireAuth": true,
"supabaseQueries": [{
"table": "posts",
"operation": "update",
"data": {
"title": "{{body.title}}",
"content": "{{body.content}}",
"updated_by": "{{auth.sub}}",
"updated_at": "now()"
},
"filters": [
{ "column": "id", "operator": "eq", "value": "{{params.id}}" },
{ "column": "user_id", "operator": "eq", "value": "{{auth.sub}}" }
],
"select": "*",
"single": true
}]
}Integration Example
json
{
"integrations": [{
"type": "slack",
"action": "sendMessage",
"params": {
"channel": "{{env.SLACK_CHANNEL}}",
"text": "New order from {{body.customer_name}}"
}
}]
}Template Reference
| Template | Source | Example |
|---|---|---|
{{env.VAR}} | Environment | {{env.API_KEY}} |
{{body.field}} | Request body | {{body.name}} |
{{params.param}} | URL param | {{params.id}} |
{{query.param}} | Query string | {{query.search}} |
{{auth.claim}} | JWT claim | {{auth.sub}} |
{{tenant.id}} | Tenant ID | {{tenant.id}} |
{{secret.key}} | Tenant secret | {{secret.API_KEY}} |
{{steps.id.result}} | Workflow step | {{steps.fetch.result}} |
{{input.field}} | Workflow input | {{input.ticketId}} |