Skip to main content

informer.yaml Reference

The informer.yaml file is the central configuration file for your Magic App. It declares which APIs the app can access and defines custom roles for role-based UIs.

Place it in your project root. It's uploaded to the app's library on deploy and enforced at runtime by the Informer server.

Basic Structure

# informer.yaml

access:
datasets:
- admin:sales-data
queries:
- admin:monthly-summary
integrations:
- salesforce

roles:
- id: viewer
name: Viewer
description: Read-only access

Access Section

The access section controls which Informer APIs your app can call. Without this section, all API access is blocked when the app runs in Informer (secure by default).

note

In dev mode, the Vite proxy uses your admin credentials directly, so access restrictions are not enforced locally. They only apply when the app is deployed and viewed by users.

Datasets

Grants access to dataset search and field metadata.

access:
datasets:
- admin:sales-data
- admin:customers

Each entry grants:

  • POST /api/datasets/{id}/_search — Elasticsearch queries
  • GET /api/datasets/{id}/fields — Field metadata

Row-Level Security

Restrict data based on the viewing user's profile:

access:
datasets:
- id: admin:orders
filter:
region: $user.custom.region # User only sees their region
sales_rep: $user.username # User only sees their own records

Filters are injected server-side into every search request. The app code doesn't need to handle filtering — it's automatic and tamper-proof.

Queries

Grants access to execute saved queries:

access:
queries:
- admin:daily-summary
- admin:monthly-report

Each entry grants:

  • POST /api/queries/{id}/_execute

Integrations

Grants access to make requests through integrations (Salesforce, REST APIs, etc.):

access:
integrations:
- salesforce
- quickbooks

Each entry grants:

  • POST /api/integrations/{id}/request

Credential Injection

Pass user-specific credentials to external APIs:

access:
integrations:
- id: partner-api
headers:
Authorization: Bearer $user.custom.partnerToken
X-Client-ID: $tenant.id
params:
user_id: $user.custom.externalId

Headers and params are expanded server-side — sensitive values are never exposed to client JavaScript.

Path Restrictions

Limit which endpoints the app can call on an integration:

access:
integrations:
- id: salesforce
paths:
- /data/*/query
- /data/*/sobjects/*

Datasources

Grants access to run SQL queries against datasources:

access:
datasources:
- postgres-main
- mysql-analytics

Each entry grants:

  • POST /api/datasources/{id}/_query

Libraries

Grants access to read files from other libraries:

access:
libraries:
- admin:shared-assets
- admin:common-templates

Each entry grants:

  • GET /api/libraries/{id}/contents/*

Raw API Paths

For edge cases not covered by resource types:

access:
apis:
- POST /api/custom/endpoint
- GET /api/special/resource
- POST /api/models/go_everyday/_chat
- POST /api/models/go_everyday/_completion
- POST /api/models/go_everyday/_object
- /api/read-only/resource # METHOD defaults to GET if omitted

Each entry is a string in the format METHOD /api/path. If the HTTP method is omitted, it defaults to GET.

Roles Section

Define custom roles that publishers assign when sharing the app:

roles:
- id: viewer
name: Viewer
description: Can view reports but not take actions
- id: approver
name: Approver
description: Can approve or reject requests
- id: manager
name: Manager
description: Full management access
FieldRequiredDescription
idYesString identifier used in code
nameYesDisplay name shown in share dialogs
descriptionNoHelp text shown in share dialogs

Reading Roles

Client-side:

const roles = window.__INFORMER__?.roles || [];

if (roles.includes('approver')) {
showApprovalPanel();
}

Server-side (route handlers):

// Automatic enforcement via config
export const config = {
roles: ['admin', 'manager'] // 403 if user lacks these roles
};

// Manual checking
export async function GET({ request }) {
if (request.roles.includes('manager')) {
// show admin data
}
}

How Roles Are Assigned

  • Internal shares — Publisher selects roles in the share dialog
  • External links — Publisher selects roles when creating the link; roles are baked into the token
  • Publisher+ on owning team — Automatically receives all defined roles
  • No roles definedwindow.__INFORMER__.roles is []

Variable Reference

Variables are expanded server-side, keeping sensitive values secure.

VariableDescription
$user.usernameLogin name
$user.emailEmail address
$user.displayNameFull name
$user.custom.xxxCustom user field value
$tenant.idTenant identifier
$tenant.<setting>Tenant setting value (from system settings)
$report.idApp UUID
$report.nameApp display name
Missing Variables

If a variable references a custom user field that doesn't exist (e.g., $user.custom.region when the user has no region field), it resolves to an empty string. For dataset filters, this means the filter matches records where that field is empty — not all records. Ensure all referenced custom fields exist for your users.

Agents Section

Define AI agents that execute autonomously in response to events, cron schedules, or manual triggers. See the Agents API docs for full details.

agents:
order-processor:
description: Processes new orders and sends confirmations
instructions: |
You are an order processing agent. When triggered by an order_created event,
verify the order details, update inventory, and send a confirmation email.
tools:
- send-email
- update-inventory
on: order_created
model: go_everyday

daily-report:
description: Generates a daily summary email
instructions: Summarize today's orders and email the report to the team.
tools:
- send-email
cron: "0 17 * * 1-5"

crm-agent:
description: Customer support with CRM tools
instructions: Help customers using CRM data and web search.
toolkits:
- admin:crm-toolkit
assistants:
- admin:support-persona
on: support_request
webSearch: true

Agent Fields

FieldTypeDescription
descriptionstringHuman-readable description
instructionsstringSystem prompt for the AI model
toolsstring[]App tool names (from tools/ directory)
toolkitsstring[]Toolkit natural IDs to attach
assistantsstring[]Assistant natural IDs — instructions merge into the agent's system prompt
onstring | string[]Event name(s) that trigger this agent
cronstringCron schedule (5-field: min hour dom mon dow)
webSearchbooleanEnable web search tool
modelstringAI model slug (default: go_everyday)

Toolkits

Agents can reference external toolkits that provide additional tools. Toolkit references are resolved at deploy — if a referenced toolkit doesn't exist, deploy fails with a clear error.

agents:
my-agent:
instructions: Use CRM tools to look up customer data.
toolkits:
- admin:crm-toolkit # Resolved by naturalId at deploy
on: customer_inquiry

At execution time, the agent receives all tools from its referenced toolkits alongside its app tools. Toolkit system instructions are appended to the agent's prompt.

Assistants

Agents can reference Informer assistants to inherit their instructions. Each assistant's system prompt is merged into the agent's own instructions at execution time.

agents:
support-bot:
instructions: Handle customer inquiries.
assistants:
- admin:support-persona # Assistant instructions merged into prompt
on: support_request

Assistant references are validated at deploy time — if a referenced assistant doesn't exist, deploy fails with a clear error. At runtime, assistant instructions are prepended to the system prompt before toolkit instructions.

Cron Schedules

Standard 5-field cron format: minute hour day-of-month month day-of-week

agents:
nightly-sync:
instructions: Sync data from external system.
cron: "0 3 * * *" # 3:00 AM daily
weekly-report:
instructions: Generate weekly report.
cron: "0 9 * * 1" # 9:00 AM every Monday
frequent-check:
instructions: Check for new items.
cron: "*/15 * * * *" # Every 15 minutes

Events Section

Declare event types that agents can listen for. Events are emitted from server route handlers via the emit() callback.

events:
order_created:
description: Fired when a new order is submitted
order_shipped:
description: Fired when an order ships
support_request:
description: Fired when a customer opens a support ticket

agents:
order-processor:
on: order_created
instructions: Process the new order.
support-bot:
on: support_request
instructions: Respond to the support ticket.

Event types are stored in app.defn.events on deploy. To emit an event from a server route:

export async function POST({ query, emit, request }) {
const [order] = await query(
'INSERT INTO orders (customer, total) VALUES ($1, $2) RETURNING *',
[request.body.customer, request.body.total]
);
await emit('order_created', { orderId: order.id });
return { status: 201, body: order };
}

Widgets Section

Declare dashboard widgets that render inside Informer's widget gallery. Widgets are static HTML files served in iframes at fixed grid sizes.

widgets:
cash-balance:
entry: widgets/cash-balance.html
label: Cash Balance
size: { w: 2, h: 1 }
refresh: 300

sales-trend:
entry: widgets/sales-trend.html
label: Sales Trend
size: { w: 2, h: 2 }
refresh: 300

Widget Fields

FieldTypeDescription
entrystringPath to HTML file relative to public/
labelstringDisplay name in the widget gallery
sizeobjectGrid dimensions: w (width) and h (height) in grid units
refreshnumberAuto-refresh interval in seconds

Widget HTML files go in public/widgets/ and are self-contained (inline CSS/JS, no external dependencies). They use the same API access as the main app.

Complete Example

# informer.yaml

access:
datasets:
- admin:sales-data
- id: admin:orders
filter:
region: $user.custom.region
queries:
- admin:monthly-summary
integrations:
- salesforce
- sendgrid
datasources:
- postgres-analytics

roles:
- id: viewer
name: Viewer
description: Read-only access
- id: manager
name: Manager
description: Full management access

events:
order_created:
description: New order submitted
order_shipped:
description: Order has shipped

agents:
order-processor:
description: Processes new orders
instructions: Verify order details and update inventory.
tools:
- update-inventory
- send-email
on: order_created

daily-digest:
description: Daily order summary
instructions: Summarize today's orders and email to managers.
tools:
- send-email
cron: "0 17 * * 1-5"

widgets:
order-count:
entry: widgets/order-count.html
label: Today's Orders
size: { w: 2, h: 1 }
refresh: 60