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

# Email Templates

> Manage email template configurations for conversation reports and workflows

Use `email-templates` to manage per-user and per-genie email template configurations. Templates control the layout and content of outgoing emails such as conversation reports.

<Note>
  Standard users manage their own templates. Admin users can read or write templates for any user by passing `adminMode: true` and the target `userId`. Team members write to the team owner's templates by default; pass `personal: true` to write to your own account instead.
</Note>

***

## Get effective config

Returns the resolved template configuration for a given type. Looks up in priority order: genie-specific template → user-level template → system default. Returns `null` if no configuration exists at any level.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"getConfig"`
</ParamField>

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="type" type="string" required>
      Template type identifier (for example `"report"`).
    </ParamField>

    <ParamField body="agent_id" type="string">
      Genie UUID. When provided, a genie-specific template is checked first before falling back to the user-level template.
    </ParamField>

    <ParamField body="userId" type="string">
      Admin only. Resolve the config for this user ID instead of the authenticated user.
    </ParamField>

    <ParamField body="adminMode" type="boolean">
      Admin only. Must be `true` to use the `userId` parameter.
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="success" type="boolean">
  Whether the request succeeded.
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="config" type="object | null">
      The resolved template configuration object, or `null` if no template is configured at any level.
    </ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "getConfig", undefined, {
    type: "report",
    agent_id: "550e8400-e29b-41d4-a716-446655440000",
  });
  const config = response?.config;
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "getConfig",
      "data": {
        "type": "report",
        "agent_id": "550e8400-e29b-41d4-a716-446655440000"
      }
    }'
  ```

  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "config": {
        "subject": "Your conversation summary",
        "headerColor": "#4E9CFF",
        "logoUrl": "https://storage.example.com/logo.png"
      }
    }
  }
  ```
</CodeGroup>

***

## List templates

Returns a paginated list of email templates for the authenticated user, optionally filtered by type or genie.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"list"` or `"all"` (both return the same result).
</ParamField>

<ParamField body="data" type="object">
  <Expandable title="properties">
    <ParamField body="limit" type="number" default="50">
      Results per page. Maximum 500.
    </ParamField>

    <ParamField body="offset" type="number" default="0">
      Number of results to skip.
    </ParamField>

    <ParamField body="type" type="string">
      Filter by template type.
    </ParamField>

    <ParamField body="agent_id" type="string">
      Filter by genie UUID. Pass `null` to return only templates with no genie association.
    </ParamField>

    <ParamField body="userId" type="string">
      Admin only. List templates for this user ID. Also accepted as `impersonatedUserId`.
    </ParamField>

    <ParamField body="impersonatedUserId" type="string">
      Admin only. Alias for `userId`.
    </ParamField>

    <ParamField body="adminMode" type="boolean">
      Admin only. Must be `true` to use the `userId` / `impersonatedUserId` parameter.
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="items" type="array">
      <Expandable title="item properties">
        <ResponseField name="id" type="string">Template UUID.</ResponseField>
        <ResponseField name="user_id" type="string">Owner user ID.</ResponseField>
        <ResponseField name="agent_id" type="string | null">Genie UUID this template is scoped to, or `null` for a user-level template.</ResponseField>
        <ResponseField name="agent_name" type="string | null">Genie display name, if `agent_id` is set.</ResponseField>
        <ResponseField name="type" type="string">Template type identifier.</ResponseField>
        <ResponseField name="config" type="object">Template configuration object.</ResponseField>
        <ResponseField name="is_default" type="boolean">Whether this is a system-default template.</ResponseField>
        <ResponseField name="created_at" type="string">ISO 8601 creation timestamp.</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="count" type="number">Total matching templates.</ResponseField>
    <ResponseField name="limit" type="number">Applied limit.</ResponseField>
    <ResponseField name="offset" type="number">Applied offset.</ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "list", undefined, {
    limit: 50,
    offset: 0,
    type: "report",
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "list",
      "data": { "limit": 50, "offset": 0, "type": "report" }
    }'
  ```

  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "items": [
        {
          "id": "tpl-uuid-123",
          "user_id": "usr-uuid-456",
          "agent_id": null,
          "agent_name": null,
          "type": "report",
          "config": { "subject": "Your conversation summary" },
          "is_default": false,
          "created_at": "2024-01-15T10:30:00.000Z"
        }
      ],
      "count": 1,
      "limit": 50,
      "offset": 0
    }
  }
  ```
</CodeGroup>

***

## Get template

Retrieves a single email template by ID.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"get"`
</ParamField>

<ParamField body="id" type="string" required>
  The template UUID.
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="template" type="object">
      The full template object. Same shape as list items above, plus an embedded `agent` object when `agent_id` is set.
    </ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "get", "tpl-uuid-123");
  const template = response?.template;
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "get",
      "id": "tpl-uuid-123"
    }'
  ```
</CodeGroup>

***

## Create template

Creates a new email template record.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"create"`
</ParamField>

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="type" type="string" required>
      Template type identifier.
    </ParamField>

    <ParamField body="config" type="object" required>
      Template configuration object.
    </ParamField>

    <ParamField body="agent_id" type="string">
      Genie UUID. When provided, the template is scoped to that genie only.
    </ParamField>

    <ParamField body="is_default" type="boolean" default="false">
      Whether to mark this as a default template.
    </ParamField>

    <ParamField body="personal" type="boolean" default="false">
      Team members only. Pass `true` to create the template under your own account instead of the team owner's account.
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="template" type="object">
      The newly created template.
    </ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "create", undefined, {
    type: "report",
    config: { subject: "Custom report subject" },
    agent_id: "550e8400-e29b-41d4-a716-446655440000",
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "create",
      "data": {
        "type": "report",
        "config": { "subject": "Custom report subject" },
        "agent_id": "550e8400-e29b-41d4-a716-446655440000"
      }
    }'
  ```

  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "template": {
        "id": "tpl-new-uuid",
        "user_id": "usr-uuid-456",
        "agent_id": "550e8400-e29b-41d4-a716-446655440000",
        "type": "report",
        "config": { "subject": "Custom report subject" },
        "is_default": false,
        "created_at": "2024-01-15T11:00:00.000Z"
      }
    }
  }
  ```
</CodeGroup>

***

## Update template

Upserts a template identified by `type` and optionally `agent_id`. If a matching template already exists it is updated; otherwise a new one is created. Use `create` when you need the returned template object — `update` only returns the ID.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"update"`
</ParamField>

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="type" type="string" required>
      Template type identifier.
    </ParamField>

    <ParamField body="config" type="object" required>
      Replacement configuration. The entire config is replaced, not merged.
    </ParamField>

    <ParamField body="agent_id" type="string">
      Genie UUID. Scopes the upsert to a genie-specific template. Omit to target the user-level template for this type.
    </ParamField>

    <ParamField body="userId" type="string">
      Admin only. Write the template for this user ID. Also accepted as `impersonatedUserId`.
    </ParamField>

    <ParamField body="impersonatedUserId" type="string">
      Admin only. Alias for `userId`.
    </ParamField>

    <ParamField body="adminMode" type="boolean">
      Admin only. Must be `true` to use the `userId` / `impersonatedUserId` parameter.
    </ParamField>

    <ParamField body="personal" type="boolean" default="false">
      Team members only. Pass `true` to write to your own account instead of the team owner's account.
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="id" type="string | number">ID of the updated or created template.</ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "update", undefined, {
    type: "report",
    config: { subject: "Updated subject line" },
  });
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "update",
      "data": {
        "type": "report",
        "config": { "subject": "Updated subject line" }
      }
    }'
  ```

  ```json Response theme={null}
  {
    "success": true,
    "data": { "id": "tpl-uuid-123" }
  }
  ```
</CodeGroup>

***

## Delete template

Permanently deletes an email template by ID.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"delete"`
</ParamField>

<ParamField body="id" type="string" required>
  The template UUID to delete.
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="success" type="boolean" />
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "delete", "tpl-uuid-123");
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "delete",
      "id": "tpl-uuid-123"
    }'
  ```
</CodeGroup>

***

## Clone default template

Copies the system-default template of a given type into the user's account. If the user already has a template of that type, its config is replaced with the default. Returns the cloned config.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"cloneDefault"`
</ParamField>

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="type" type="string" required>
      Template type to clone the default for.
    </ParamField>

    <ParamField body="agent_id" type="string">
      Genie UUID. When provided, the clone is scoped to that genie.
    </ParamField>

    <ParamField body="personal" type="boolean" default="false">
      Team members only. Pass `true` to clone into your own account rather than the team owner's account.
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="config" type="object">The config copied from the system default.</ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "cloneDefault", undefined, {
    type: "report",
  });
  const config = response?.config;
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "cloneDefault",
      "data": { "type": "report" }
    }'
  ```
</CodeGroup>

***

## Copy logo

Copies a logo image from an external storage location into HelpGenie-managed storage and returns the new URL. If the image is already in internal storage or the copy fails, the original URL is returned unchanged.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"copyLogo"`
</ParamField>

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="logoUrl" type="string" required>
      Public URL of the logo to copy.
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="logoUrl" type="string">
      The new internal URL, or the original URL if the copy was skipped or failed.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## Sync signature visibility

Propagates a genie's signature enabled/disabled setting across its email template rows. For existing per-type rows the signature block is toggled in place (`"patched"`); rows that don't yet exist are left alone (`"no_template"`) — per-type rows are never force-created. The genie's shared brand template (the `type: null` fallback used when no per-type override exists) is also patched when it exists; if it is absent and the genie has branding configured, a new brand template row is created with the signature block set accordingly (`"forked"`). Templates for other genies are never touched.

<ParamField body="resource" type="string" required>
  Must be `"email-templates"`
</ParamField>

<ParamField body="action" type="string" required>
  Must be `"sync-signature-enabled"`
</ParamField>

<ParamField body="data" type="object" required>
  <Expandable title="properties">
    <ParamField body="agent_id" type="string" required>
      Genie UUID whose signature visibility should be synced across all template types.
    </ParamField>

    <ParamField body="enabled" type="boolean" required>
      `true` to enable the email signature block; `false` to disable it.
    </ParamField>

    <ParamField body="personal" type="boolean" default="false">
      Team members only. Pass `true` to write forked templates to your own account instead of the team owner's account.
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="success" type="boolean" />

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="results" type="object">
      A map of outcome strings keyed by template scope. Keys are `"brand"` (the genie's shared `type: null` brand template) and each per-type identifier: `"conversation_report"`, `"customer_report"`, `"meeting_recap"`, `"escalation_alert"`, `"conversation_digest"`, `"conversation_auto_digest"`, `"view_report"`. Each value is one of:

      | Value | Meaning |
      | - | - |
      | `"patched"` | An existing template row was updated in place. |
      | `"forked"` | No brand template row existed; one was created from the genie's branding. Only possible for the `"brand"` key — per-type rows are never created by this action. |
      | `"unchanged"` | The signature block was already in the requested state. |
      | `"no_template"` | No template row exists for this scope (per-type rows are left as-is). |
    </ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```typescript ApiService.invoke() theme={null}
  const response = await ApiService.invoke("email-templates", "sync-signature-enabled", undefined, {
    agent_id: "550e8400-e29b-41d4-a716-446655440000",
    enabled: true,
  });
  const { results } = response;
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.helpgenie.ai/v1 \
    -H "Authorization: Bearer hg_live_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "resource": "email-templates",
      "action": "sync-signature-enabled",
      "data": {
        "agent_id": "550e8400-e29b-41d4-a716-446655440000",
        "enabled": true
      }
    }'
  ```

  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "results": {
        "brand": "forked",
        "conversation_report": "patched",
        "customer_report": "unchanged",
        "meeting_recap": "patched",
        "escalation_alert": "no_template",
        "conversation_digest": "no_template",
        "conversation_auto_digest": "unchanged",
        "view_report": "patched"
      }
    }
  }
  ```
</CodeGroup>

***

## Error codes

| Code | Status | Description |
| - | - | - |
| `UNAUTHORIZED` | 401 | Missing or invalid authentication token |
| `FORBIDDEN` | 403 | User lacks permission for the operation |
| `NOT_FOUND` | 404 | Template not found |
| `VALIDATION_ERROR` | 400 | Missing required fields (`type`, `config`) |
| `INVALID_ACTION` | 400 | Unknown action |
| `INTERNAL_ERROR` | 500 | Server-side error |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.