portablemind
All guides
API / Developer3 min read

Automate with Dynamic Functions

Run your own sandboxed JavaScript inside PortableMind — on a schedule, on a record change, or as a tool your agents can call.

apiautomationserverless

Run your own logic inside PortableMind — small JavaScript functions that read and write your data, call external APIs, run on a schedule, or fire when a record changes. No service to deploy.

What you'll use

Dynamic Functions: sandboxed JavaScript stored in the platform, executed as a background job. Trigger them manually, on a cron schedule, from an MCP tool, or as a model lifecycle callback.

Steps

  1. Go to AI Studio → Build → Dynamic Functions and create one. Write JavaScript in the editor; you get a context with params, tenant_id, the current user, and helpers like execute_action(model, action, params) to read/write tenant data and shareRecord(model, id, partyId, level) to share what you create (viewer/commenter/editor/full_access — never owner, and only what the function's user could share anyway).
  2. Pick a trigger:
    • Manual / API — call it on demand:
      POST /api/v1/dynamic_functions/:id/execute   { params, async: true }
      
      By default the function runs with the caller's permissions. Turn on "API executes as run-as user" to run it with the function's run_as_user instead (the caller is still recorded for audit) — that's how a least-privilege user can trigger a function that needs service-level access. The execute permission can also be granted per function, not just tenant-wide.
    • Schedule — give it a cron like 0 9 * * 1 (9am Mondays).
    • Callback — run it when a record changes, e.g. callback_model: 'Project', callback_event: 'create'. Supported models include Party, User (e.g. offboarding cleanup on destroy), Project, Task, BizTxnEvent and more — and teams created through signup fire Party create callbacks too.
  3. Reach external services securely by attaching an OAuth/secret Configuration — sensitive values are encrypted at rest, never inlined in code.
  4. Audit every run. Each execution is logged (result, error, duration) under dynamic_function_executions so you can see exactly what happened.
  5. Trust your reads and writes. Sandbox writes honor your permission scopes per action (an editor share lets you update, never delete), and a list filter the platform can't apply raises an error instead of silently returning everything — so automation never acts on a lie.

Result

A lightweight automation layer that lives next to your data: a weekly rollup that posts to a conversation, a sync that fires whenever a project is created, an enrichment step an agent can call as a tool. It's serverless from your side — write the function, pick the trigger, done.

Your agents can run your function too — via the execute endpoint or the dynamic-function tools — so your custom logic becomes part of what they can do.