Skip to content

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": "&#123;&#123;secret:STRIPE_SECRET&#125;&#125;"
    }
  }
}

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
"&#123;&#123;steps.stepId.result&#125;&#125;"
"&#123;&#123;steps.stepId.result.field&#125;&#125;"

Input (Workflows)

json
"&#123;&#123;input.fieldName&#125;&#125;"

String Concatenation

Templates can be embedded in strings:

json
{
  "select": "*, users(name)",
  "filters": [{
    "column": "name",
    "operator": "ilike",
    "value": "%&#123;&#123;query.search&#125;&#125;%"
  }]
}

Default Values

Use JavaScript OR syntax:

json
"&#123;&#123;query.limit || 10&#125;&#125;"

Examples

Full Route Example

json
{
  "path": "/posts/:id",
  "method": "put",
  "requireAuth": true,
  "supabaseQueries": [{
    "table": "posts",
    "operation": "update",
    "data": {
      "title": "&#123;&#123;body.title&#125;&#125;",
      "content": "&#123;&#123;body.content&#125;&#125;",
      "updated_by": "&#123;&#123;auth.sub&#125;&#125;",
      "updated_at": "now()"
    },
    "filters": [
      { "column": "id", "operator": "eq", "value": "&#123;&#123;params.id&#125;&#125;" },
      { "column": "user_id", "operator": "eq", "value": "&#123;&#123;auth.sub&#125;&#125;" }
    ],
    "select": "*",
    "single": true
  }]
}

Integration Example

json
{
  "integrations": [{
    "type": "slack",
    "action": "sendMessage",
    "params": {
      "channel": "&#123;&#123;env.SLACK_CHANNEL&#125;&#125;",
      "text": "New order from &#123;&#123;body.customer_name&#125;&#125;"
    }
  }]
}

Template Reference

TemplateSourceExample
&#123;&#123;env.VAR&#125;&#125;Environment&#123;&#123;env.API_KEY&#125;&#125;
&#123;&#123;body.field&#125;&#125;Request body&#123;&#123;body.name&#125;&#125;
&#123;&#123;params.param&#125;&#125;URL param&#123;&#123;params.id&#125;&#125;
&#123;&#123;query.param&#125;&#125;Query string&#123;&#123;query.search&#125;&#125;
&#123;&#123;auth.claim&#125;&#125;JWT claim&#123;&#123;auth.sub&#125;&#125;
&#123;&#123;tenant.id&#125;&#125;Tenant ID&#123;&#123;tenant.id&#125;&#125;
&#123;&#123;secret.key&#125;&#125;Tenant secret&#123;&#123;secret.API_KEY&#125;&#125;
&#123;&#123;steps.id.result&#125;&#125;Workflow step&#123;&#123;steps.fetch.result&#125;&#125;
&#123;&#123;input.field&#125;&#125;Workflow input&#123;&#123;input.ticketId&#125;&#125;

Released under the ISC License.