Skip to main content
A function is something Foundry can do, like “send a DocuSign envelope” or “look up a Salesforce contact.” You build it by describing what you want, and Foundry writes and tests the code for you. Functions live inside the Foundry app (in the workspace sidebar between Agents and Workflows). They use integrations created by your org admins in Settings → Integrations.

The workspace

Open Foundry from the sidebar. The left panel has two tabs:
  • Functions. Every function in your workspace, with their last test status (Passing, Failing, or Never run). Click New Function to start a new one.
  • Integrations. Every integration available to Foundry. The New Integration button takes you to Settings.
When you open a function, the right side becomes the function workspace with the generated code and a publish button. The panel on the left shifts into four tabs for that function:
  • Chat. The conversation Foundry uses to generate and refine code.
  • Test. Run the function with sample inputs.
  • Integrations. Connect or disconnect integrations for this function.
  • Configure. Edit the name, description, and AI tool prompt, or delete the function.

Build a function

1

Create the function

In Foundry’s Functions tab, click New Function. A blank function opens in the workspace.
2

Connect integrations

Open the function’s Integrations tab and connect the integration the function should call. You can add more than one, which is useful when a function needs to read from one tool and write to another. The first integration is the primary one and supplies the function’s default scope and OAuth connected account.If you don’t have the integration you need, an admin can create one in Settings → Integrations.
3

Describe what it should do

In the Chat tab, write what you want the function to do in plain language. Be specific:

List all active users and return their name, email, and role

Create a project with the given name, description, and team

Look up a contact by email and return their company and last activity date

Foundry generates code, type-checks it, and runs a dry-run against the API.
4

Test with real inputs

Open the Test tab, fill in the inputs, pick a runtime environment (development, staging, or production), and click Run Test. Foundry shows the result, every HTTP request the function made, and any log output.
5

Refine in chat

If something isn’t right, ask in plain language from the Chat tab:

Add pagination so it fetches every page.

If the API returns a 429, wait and retry up to 3 times.

Only return users where status is active.

6

Publish

Click Publish in the function workspace. Foundry validates the code one more time, generates an AI tool prompt (so agents know when to call it), and publishes the function. It’s now available as a workflow step and as a tool for your AI agents.
Foundry shows generation status (Idle, In progress, Success, or Error) in the function workspace, so if a generation stalls or fails, you can see why.
Want prompts you can copy? See Foundry examples for worked recipes, or Tips & troubleshooting for ways to get better code out of Foundry.

Advanced: the ActionContext SDK

This section is for users who want to read or hand-edit the generated TypeScript code. You don’t need any of this to build, test, or publish a function. Every function exports a run function that receives an ActionContext. The context gives you authenticated HTTP clients (one per integration), the Ravenna operations namespace, and runtime info.
import type { ActionContext } from '@ravenna/actions'

export async function run(ctx: ActionContext, input: RunInput): Promise<RunOutput> {
  // Each integration is available by its slug, with auth and default headers injected.
  const salesforce = ctx.integrations.salesforce
  const response = await salesforce.fetch(`${salesforce.baseUrl}/services/data/v59.0/query`)
  const { records } = await response.json()

  // Call Ravenna operations the same way you'd call any built-in action.
  await ctx.ravenna.createTicket({
    title: `New account: ${records[0].Name}`,
    queueId: input.queueId,
    statusId: input.statusId,
    requesterId: input.requesterId,
    authorId: input.authorId,
  })

  ctx.log(`Processed ${records.length} records in ${ctx.env}`)

  return { count: records.length }
}

Context properties

PropertyWhat it is
ctx.integrationsA map of integration clients keyed by slug. Each has .fetch (auth-injected) and .baseUrl.
ctx.ravennaThe Ravenna operations namespace. See the list below.
ctx.log()Writes to the function’s log output.
ctx.workspaceId / ctx.organizationIdIDs for the current execution context.
ctx.env'development', 'staging', or 'production'.
ctx.workflowExecutionIdSet when the function is running as a workflow step.
ctx.fetch, ctx.baseUrl, and ctx.auth still exist for backwards compatibility but are deprecated. They point at the primary integration. New code should use ctx.integrations.<slug> so it keeps working when more integrations are added to the function.

Ravenna operations

Available on ctx.ravenna: Tickets: createTicket, updateTicket, addTicketComment, setTicketStatus, setTicketPriority, setTicketAssignee, addTicketFollowers, addTicketTags, moveTicket Slack: sendSlackMessage, sendSlackDm, createSlackChannel Users: getUser

Advanced: how generation and testing work

Foundry validates generated code in two phases, automatically:
  1. TypeScript compilation catches syntax errors, type mismatches, and bad imports. Foundry auto-fixes failures up to 3 times.
  2. Dry-run execution runs the code in a sandbox without making real API calls, to catch issues like malformed URLs. Foundry auto-fixes failures up to 2 times.
When you run a real test from the Test tab, you pick the runtime environment (development, staging, or production) that the function sees via ctx.env. The function runs in an isolated sandbox with the credentials resolved for each of its integrations, limited to 30 seconds per execution. When you publish, Foundry runs a final validation, then generates an AI tool prompt that helps agents decide when to call the function. You can regenerate that prompt from the function’s Configure tab.
Learn how to use published functions in workflows and with AI agents.
Last modified on June 4, 2026