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

# Utilities

> General-purpose operations an automation can run as App Action steps, such as email and HTTP requests.

General-purpose operations an [automation](/automations/overview) can run as App Action steps. Unlike [commerce primitives' actions](/apps/colossal-app/actions), these aren't tied to a Colossal object.

## Email

<AccordionGroup>
  <Accordion title="send_email">
    Sends an email to a recipient.

    **Input**

    <ResponseField name="to" type="string" required />

    <ResponseField name="subject" type="string" required>
      *minLen: 1, maxLen: 998.*
    </ResponseField>

    <ResponseField name="html" type="string">
      *Default: `""`.*
    </ResponseField>

    <ResponseField name="content" type="string">
      *Default: `""`.*
    </ResponseField>

    <ResponseField name="from" type="string | null" />

    **Output**

    <ResponseField name="to" type="string" />

    <ResponseField name="subject" type="string" />
  </Accordion>
</AccordionGroup>

## Notifications

<AccordionGroup>
  <Accordion title="post_notification">
    Send a notification about this automation. It reaches whoever the automation belongs to - the person who created it, whoever set that run going, plus anyone added to an agent that uses it. A builder who has never touched it is not notified, and there is no way to name a recipient. The default channel when the merchant asks to be notified without naming one.

    **Input**

    <ResponseField name="title" type="string" required>
      Short headline shown in the notification row.
    </ResponseField>

    <ResponseField name="body" type="string" required>
      A sentence or two of detail below the title.
    </ResponseField>

    <ResponseField name="severity" type="string">
      One of: info, suggestion, warning, action\_required, celebration. *Default: `"info"`.*
    </ResponseField>

    <ResponseField name="idempotency_key" type="string | null">
      Optional dedupe key; matching non-deleted rows are returned instead of creating a new one.
    </ResponseField>

    **Output**

    <ResponseField name="notification_uid" type="string | null" />
  </Accordion>
</AccordionGroup>

## HTTP request

<AccordionGroup>
  <Accordion title="http_request">
    Sends an HTTP request to any URL.

    **Input**

    <ResponseField name="url" type="string" required>
      *minLen: 1, maxLen: 2083.*
    </ResponseField>

    <ResponseField name="method" type="enum (`GET`, `POST`, `PUT`, `PATCH`, `DELETE`)" required />

    <ResponseField name="headers" type="object" />

    <ResponseField name="body" type="object" />

    <ResponseField name="timeout" type="integer">
      *min: 1, max: 300. Default: `30`.*
    </ResponseField>

    **Output**

    <ResponseField name="status_code" type="integer">
      *min: 0.*
    </ResponseField>

    <ResponseField name="response" type="object | string | null" />

    <ResponseField name="headers" type="object" />
  </Accordion>
</AccordionGroup>

### Security

The `http_request` action supports custom headers, so you can include a secret key to verify that incoming requests are from Colossal. When configuring a webhook request in your automation, add an authorization header with a secret value:

```json theme={null}
{
  "headers": {
    "X-Webhook-Secret": "your-secret-key"
  }
}
```

Then verify it on your server:

```typescript theme={null}
app.post('/webhooks/colossal', (req, res) => {
  const secret = req.headers['x-webhook-secret'];

  if (secret !== process.env.WEBHOOK_SECRET) {
    return res.status(401).send('Unauthorized');
  }

  // Process webhook
  res.status(200).send('OK');
});
```

### Best practices

1. **Use a secret header** - Add a shared secret to your webhook headers to verify requests
2. **Handle duplicate events** - Use `correlation_id` for idempotency
3. **Return 200 quickly** - Process events asynchronously
4. **Handle retries** - We retry failed webhooks up to 3 times
5. **Monitor webhook endpoints** - Ensure high availability
