> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prisme.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Building Custom Apps with Builder

> Learn how to create, deploy, and publish custom applications on Prisme.ai

This tutorial guides you through the process of creating, configuring, and publishing a custom application on Prisme.ai. You'll learn how to extend the platform's capabilities by building a reusable app that can be shared across workspaces and used by other team members.

## Understanding Apps on Prisme.ai

Before diving into development, it's important to understand what an "App" represents in the Prisme.ai ecosystem:

<CardGroup cols={2}>
  <Card title="Custom Components" icon="puzzle-piece">
    Components built with ReactJS to provide specialized UI or functionality
  </Card>

  <Card title="Imports" icon="plug">
    Connectors to external services like CRMs, APIs, or other software systems
  </Card>

  <Card title="Code to No-Code Interface" icon="code">
    Transform complex code into user-friendly no-code interfaces
  </Card>

  <Card title="Legacy to Modern API" icon="arrow-right-arrow-left">
    Convert legacy systems into modern APIs for better integration
  </Card>
</CardGroup>

## Benefits of Custom Apps

Creating custom apps on Prisme.ai offers several advantages:

* **Accelerated Roadmap Execution**: Deploy new features and integrations quickly
* **Enhanced Quality and Security**: Test and secure components in a controlled environment
* **Governance and Control**: Restrict app development to authorized users
* **Increased Productivity**: Automate routine tasks and integrate various data sources
* **Reusable Components**: Build once, use everywhere across your organization

## What You'll Build

In this tutorial, you'll create a Mailjet integration app that allows users to send emails directly from their automations. This practical example demonstrates the full app development lifecycle from creation to publication in the App Store.

<Note>
  While we're using Mailjet as an example, the principles and steps apply to building any type of custom app on Prisme.ai.
</Note>

## Prerequisites

Before starting this tutorial, make sure you have:

* An active Prisme.ai account with appropriate permissions
* Basic knowledge of YAML for configuration
* API credentials from the service you're integrating (Mailjet in this example)

## Step 1: Creating Your App Workspace

First, let's create a dedicated workspace for your app:

<Steps>
  <Step title="Access Builder">
    Log in to Prisme.ai and navigate to **Builder**.
  </Step>

  <Step title="Create a New Workspace">
    Click **+ Create new workspace**, then in step 1 choose **From Scratch**. In step 2, configure it as follows:

    * Name: "Mailjet" (or the name of your integration)
    * Description: Brief explanation of what the app does
    * Icon: Choose an appropriate icon that represents the service

    Click **Create Workspace** to finish.
  </Step>

  <Step title="Configure Basic Settings">
    Set up any additional workspace settings necessary for your app.
  </Step>
</Steps>

<img src="https://mintcdn.com/prismeai/K_v8yhAp7bkcmKW-/images/tutorials/builder-create-wizard-step2.png?fit=max&auto=format&n=K_v8yhAp7bkcmKW-&q=85&s=0f1200a9acbe99a419e71ae23e7d5c06" alt="Builder Create Workspace wizard step 2: name and description" width="1440" height="900" data-path="images/tutorials/builder-create-wizard-step2.png" />

*The wizard layout is the same regardless of name — for this tutorial, fill in "Mailjet".*

## Step 2: Building the Core Automation

Now, let's create the main functionality of your app:

<Steps>
  <Step title="Create an Automation">
    Navigate to the **Automations** section and click **Create Automation**.
  </Step>

  <Step title="Configure the Automation">
    * Name your automation (e.g., "SendEmail")
    * Set an appropriate slug (e.g., "send-email")
  </Step>

  <Step title="Define the Automation Logic">
    Switch to the **Code** view and paste the following YAML configuration:

    ```yaml theme={null}
    slug: send-email
    name: SendMail
    do:
      - fetch:
          emitErrors: true
          outputMode: body
          headers:
            Content-Type: application/json
            Authorization: Basic [Base64 Encoded Credentials]
          query: {}
          url: https://api.mailjet.com/v3.1/send
          method: post
          body:
            Messages:
              - From:
                  Email: '{{fromEmail}}'
                  Name: '{{fromName}}'
                To:
                  - Email: '{{toEmail}}'
                    Name: '{{toName}}'
                Subject: '{{subject}}'
                TextPart: '{{body}}'
          output: response
    arguments:
      fromEmail:
        type: string
        placeholder: john@example.com
        title: 
         fr: From Email
         en: From Email
        description: 
         en: From Email
         fr: From Email
      fromName:
        type: string
        placeholder: john
        title:
          en: From name
          fr: From Name
      toEmail:
        type: string
        placeholder: john@example.com
        title: 
         fr: To Email
         en: To Email
        description: 
         en: To Email
         fr: To Email
      toName:
        type: string
        placeholder: john
        title:
          en: To name
          fr: To Name
      subject:
        type: string
        placeholder: Your first Email
        title: 
         fr: Object
         en: Subject
        description: 
         en: Subject
         fr: Object
      body:
        type: string
        ui:widget: html
        title: 
         fr: Corps
         en: Body
        description:
          fr: Texte ou contenu enrichi au format HTML ou Markdown
          en: Text or rich text formated with HTML ou Markdown 
    ```
  </Step>

  <Step title="Keep the automation public">
    Do **not** set `private: true` on this automation. Public automations are the surface your app exposes to consumer workspaces — once the workspace is published as an app and installed, consumer automations call this one as `Mailjet.send-email`. Marking it private would hide it from the published app and break the integration.

    `private: true` is only appropriate for internal helpers that should never be reachable from outside the workspace.
  </Step>

  <Step title="Save the Automation">
    Click **Save** to create your automation.
  </Step>

  <Step title="Test the Automation">
    Run a test to ensure the automation works as expected with your API credentials.
  </Step>
</Steps>

### Understanding the Automation Configuration

The YAML configuration above defines a workflow that:

1. Makes an HTTP POST request to the Mailjet API
2. Uses basic authentication with encoded credentials
3. Formats the request body according to Mailjet's requirements
4. Defines input arguments with user-friendly labels and placeholders
5. Supports HTML content for the email body

<Note>
  The `arguments` section defines the inputs that will be exposed to users when they use your app in their own automations. Make sure these are clearly named and documented.
</Note>

## Step 3: Configuring Advanced Settings

Let's add configuration capabilities to make your app more flexible:

<Steps>
  <Step title="Create Configuration Schema">
    Navigate to the workspace **Settings** → **Configuration** tab.
  </Step>

  <Step title="Define Configuration Fields">
    Add the following YAML to create a configuration field for API credentials:

    ```yaml theme={null}
    config:
      schema:
        base64_encoded_credentials:
          title: Base64 encoded credentials
          description: Base64 encoded credentials
          type: string
    ```
  </Step>

  <Step title="Update Automation to Use Configuration">
    Modify your automation to use the configured credentials instead of hardcoded values.
  </Step>
</Steps>

## Step 4: Adding Documentation to the App

In v27, a Builder workspace exposes a single editable page called `index`, which is a React (Vite + Tailwind + Radix) single-page application. There is no separate `_doc` page and no block-based YAML. The `index` page is what app users see when they preview the workspace or open the published app's documentation, so that's where the documentation lives.

<Steps>
  <Step title="Open the index page">
    Navigate to **Pages** in the Builder sidebar and open the `index` page. If the workspace has no source yet, initialize the React template from **Code** mode.
  </Step>

  <Step title="Edit src/App.tsx">
    Switch to **Code** and replace the contents of `src/App.tsx` with a documentation component built from plain JSX and Tailwind. The example below renders a header and a simple Tabs UI for **Documentation** and **Changelog**, mirroring the legacy content:

    ```tsx theme={null}
    import { useState } from "react"
    import * as Tabs from "@radix-ui/react-tabs"

    export default function App() {
      return (
        <div className="min-h-screen bg-white p-8">
          <header className="mb-6">
            <h1 className="text-3xl font-semibold">Mailjet</h1>
            <p className="text-gray-600">
              The complete solution to power your email
            </p>
          </header>

          <Tabs.Root defaultValue="documentation">
            <Tabs.List className="flex gap-4 border-b border-gray-200">
              <Tabs.Trigger
                value="documentation"
                className="px-3 py-2 text-sm data-[state=active]:border-b-2 data-[state=active]:border-blue-600"
              >
                Documentation
              </Tabs.Trigger>
              <Tabs.Trigger
                value="changelog"
                className="px-3 py-2 text-sm data-[state=active]:border-b-2 data-[state=active]:border-blue-600"
              >
                Changelog
              </Tabs.Trigger>
            </Tabs.List>

            <Tabs.Content value="documentation" className="pt-6">
              <hr className="mb-4" />
              <p>Hello World</p>
            </Tabs.Content>

            <Tabs.Content value="changelog" className="pt-6">
              <hr className="mb-4" />
              <h2 className="text-xl font-semibold">3-8-2023.3</h2>
              <p>Latest stable release</p>
            </Tabs.Content>
          </Tabs.Root>
        </div>
      )
    }
    ```

    For longer docs, you can split the content into a dedicated `src/components/Documentation.tsx` and even add light routing (for example with `react-router-dom`) so `/` shows the documentation and `/changelog` shows release notes.
  </Step>

  <Step title="Render rich content (optional)">
    If you'd rather author the docs in Markdown or HTML, drop the converted HTML into a static container — `<div className="prose" dangerouslySetInnerHTML={{ __html: html }} />` works well with Tailwind Typography — or import any React Markdown library your project already uses (e.g. `react-markdown`, `marked`).
  </Step>

  <Step title="Preview and save">
    Switch back to **Preview** to verify the rendered documentation, then click **Save** to synchronize the source files to the workspace.
  </Step>

  <Step title="Allow consumers to view the page">
    The `index` page is part of the workspace, so its visibility follows the workspace's sharing settings. Open the workspace **Settings** and make sure the workspace's sharing settings allow consumers of the published app to view this page.
  </Step>
</Steps>

<img src="https://mintcdn.com/prismeai/K_v8yhAp7bkcmKW-/images/tutorials/builder-workspace-pages.png?fit=max&auto=format&n=K_v8yhAp7bkcmKW-&q=85&s=a4f4c20dda2654463fd8af35b2b26f2e" alt="Builder Pages editor for the index page with Preview / Code toggle, device viewport selectors, and Save button" width="1440" height="900" data-path="images/tutorials/builder-workspace-pages.png" />

*The Preview pane renders the compiled SPA. Once `src/App.tsx` is in place, the Mailjet documentation tabs appear on the right.*

## Step 5: Versioning and Publishing

Now that your app is built and documented, let's publish it to the App Store:

<Steps>
  <Step title="Push a Workspace Version">
    Click **Push** to create a new workspace version in the platform-wide repository. See [Versioning](/products/ai-builder/versioning) for details on how versions are managed.
  </Step>

  <Step title="Publish to App Store">
    Click **Publish** to make your workspace available as an installable app in the Prisme.ai App Store. See [Deployment](/products/ai-builder/deployment) for more on the publishing flow.
  </Step>

  <Step title="Configure Publication Settings">
    Set visibility, categorization, and other publication settings for your app.
  </Step>

  <Step title="Complete Publication">
    Finalize the publication process.
  </Step>
</Steps>

## Step 6: Installing and Using Your App

Now let's see how users can install and use your app:

<Steps>
  <Step title="Open the Apps Marketplace">
    In any workspace, navigate to the **Imports** section and click the **+** button to browse the Apps marketplace.
  </Step>

  <Step title="Find and Install Your App">
    Search for your app by name and click **Install**.
  </Step>

  <Step title="Configure App Settings">
    Enter any required configuration values (like the API credentials).
  </Step>

  <Step title="Use the App in Automations">
    Create or edit an automation, add a new instruction, and select your app's action (e.g., "SendEmail").
  </Step>

  <Step title="Configure Action Parameters">
    Fill in the required parameters defined in your app's arguments.
  </Step>
</Steps>

## Monitoring and Maintenance

After publishing your app, it's important to monitor its usage and make improvements:

<Steps>
  <Step title="Track Activity">
    Use the Activity tab to monitor usage patterns and detect any issues.
  </Step>

  <Step title="Gather Feedback">
    Collect feedback from users to identify enhancement opportunities.
  </Step>

  <Step title="Release Updates">
    Make improvements, push new versions, and publish updates to the App Store.
  </Step>
</Steps>

## Advanced App Development

As you become more familiar with app development on Prisme.ai, consider these advanced capabilities:

<CardGroup cols={2}>
  <Card title="Custom React Components" icon="react">
    Build rich interactive UI components using ReactJS
  </Card>

  <Card title="Multi-Service Integration" icon="network-wired">
    Connect multiple external services in a single app
  </Card>

  <Card title="Advanced Authentication" icon="shield-check">
    Implement OAuth and other complex authentication flows
  </Card>

  <Card title="AI-Enhanced Processing" icon="robot">
    Combine your app with Knowledges for intelligent data processing, or plug in Agent Creator agents to add reasoning on top of your integration.
  </Card>
</CardGroup>

## Best Practices for App Development

To ensure your apps are high-quality and maintainable:

* **Comprehensive Testing**: Test all aspects of your app thoroughly before publishing
* **Clear Documentation**: Provide detailed instructions and examples
* **Version Control**: Maintain consistent versioning practices
* **Security First**: Handle credentials and sensitive data securely
* **User Experience**: Focus on making your app intuitive and easy to use
* **Feedback Loop**: Establish a mechanism for collecting and acting on user feedback

## Next Steps

<CardGroup cols={2}>
  <Card title="Create a RAG Agent" icon="database" href="/resources/tutorials/no-code-rag-agent">
    Build an agent that uses AI to answer questions from your documents
  </Card>

  <Card title="Implement Webhook Integration" icon="webhook" href="/resources/tutorials/webhook-builder">
    Learn how to create advanced API and webhook integrations
  </Card>

  <Card title="Document Classification System" icon="file" href="/resources/tutorials/data-classification-agent">
    Build an AI system that automatically categorizes documents
  </Card>

  <Card title="Website to RAG Agent" icon="globe" href="/resources/tutorials/website-to-rag-agent">
    Convert a website into an interactive knowledge base
  </Card>
</CardGroup>
