# Getting Started with Custom Actions

Stand up your first Custom Action in a few minutes.

---

> **Note:** Custom Actions require a Builder plan or higher.
> [Upgrade to Builder](https://app.avcodex.com/plans)

## Create your first action

### 1. Open Custom Actions

Go to [app.avcodex.com](https://app.avcodex.com), pick your agent, then **Build** > **Capabilities** > **Add Custom Action**.

### 2. Basic configuration

Fill in the basics. Example: a tech-facing action that searches your project database for a room.

  - **Title**: `Search rooms`
  - **Description**: `Search for a room in the project database by site name, room name, or asset tag`
  - **Method**: `GET`
  - **URL**: `https://api.example.com/rooms`

### 3. Add parameters

Open the **Parameters** tab and add a query parameter.

- **Source**: Let the AI generate it.
- **Key**: `query`
- **Type**: String.
- **Example**: `1200-market boardroom-4`
- **AI instructions**: `Search term taken from the user's request, usually a site code, room name, or asset tag.`
- **Required**: yes.

### 4. Test the action

Use the built-in tester to confirm the call works.

### 5. Save and use

Click **Add Action**. Your agent can now search rooms whenever a tech asks.

## Import from cURL

If you already have a cURL command, paste it in. The importer will configure most of the action for you.

### 1. Paste the cURL

For example, posting a status note to a Slack channel:

```bash
curl -X POST https://api.example.com/messages \
  -H "Authorization: Bearer {{var.API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "{{channel}}",
    "subject": "{{subject}}",
    "body": "{{message}}"
  }'
```

### 2. Parse and configure

Click **Parse cURL** to auto-populate:

- Method: POST.
- Headers: Authorization, Content-Type.
- Body parameters with AI placeholders.

### 3. Configure placeholders

For each `{{placeholder}}`:

- Add an example value (a real Slack channel, a sample subject like "Boardroom 4 commissioning passed").
- Write AI instructions ("Use the channel the tech mentions, default to #av-ops").
- Mark required or optional.

## Using variables

### Application variables

Define reusable values in the **Variables** tab.

**Define once:**
- `API_KEY` = `sk-abc123...`
- `BASE_URL` = `https://api.example.com`

**Use anywhere:**
- URL: `{{var.BASE_URL}}/rooms`
- Header: `Authorization: Bearer {{var.API_KEY}}`

### System variables

System variables give the action runtime context about the current user and conversation. They are available in every action.

**`{{system.message_history}}`**
- The full conversation as an array.
- Format: OpenAI Chat Completions API format.
- Use case: send conversation context to an analysis or escalation API.
- Example: `[{"role": "user", "content": "Q-SYS Core offline"}, {"role": "assistant", "content": "Which room?"}]`

**`{{system.user_id}}`**
- The unique ID of the current user.
- Format: string identifier.
- Use case: track which tech ran an action, attribute work in your PM tool.
- Example: `"user_abc123"`

**`{{system.timestamp}}`**
- Current Unix timestamp, in seconds.
- Format: string number.
- Use case: log when actions occur, time-stamped commissioning notes.
- Example: `"1713552052"`

**Example use in the cURL importer:**
```bash
curl -X POST https://api.example.com/escalations \
  -H "Content-Type: application/json" \
  -H "X-User-ID: {{system.user_id}}" \
  -d '{
    "timestamp": "{{system.timestamp}}",
    "messages": {{system.message_history}}
  }'
```

Note: `message_history` does not need quotes in the body. It is already a JSON array.

## Action dependencies

Action dependencies let you build multi-step workflows where one action's output becomes the next action's input. The agent runs the actions in the right order automatically.

**How it works**

1. A tech asks: "What was the last commissioning result for Boardroom 4 at 1200 Market?"
2. The agent recognizes it needs to:
   - First, call **Find room** to resolve the room ID.
   - Then, call **Get latest commissioning report** with that ID.
3. Actions run in sequence.
4. The agent responds with the final answer.

### Example: two-step room lookup

**Step 1, find the room:**
- Name: `Find room`.
- URL: `https://api.example.com/rooms?query={{query}}`.
- Returns: `{"data": {"id": "room_4421", "name": "Boardroom 4"}}`.

**Step 2, get the commissioning report:**
- Name: `Get latest commissioning report`.
- URL: `https://api.example.com/rooms/{{roomId}}/commissioning/latest`.
- Parameter configuration:
  - Source: `Output from another Action`.
  - Action: `Find room`.
  - JSONPath: `$.data.id` (extracts `room_4421` from Step 1).

**Result:** when the tech asks about Boardroom 4 commissioning, the agent:

1. Calls **Find room**, gets `room_4421`.
2. Calls **Get latest commissioning report** with `room_4421`.
3. Responds: "Boardroom 4 was commissioned on April 14. All checks passed except the ceiling-mic gate threshold, flagged for review."

**JSONPath examples:**
- `$.id` - top-level field.
- `$.data.room.id` - nested field.
- `$.items[0].name` - first array item.
- `$.rooms[*].id` - all room IDs.

## Verb customization

Improve the in-chat experience with status messages:

- **Present tense**: "Searching project database."
- **Past tense**: "Searched project database."

These show while the action runs.

## Best practices

### 1. Clear descriptions

Write descriptions that help the agent understand when to call the action. "Use when the tech asks about a room's commissioning status" beats "Get commissioning."

### 2. Realistic examples

Provide example values that match real AV data. A real site code like `1200-market` is better than `foo`.

### 3. Test thoroughly

Run the tester with several inputs before saving. Try a known-good room, a missing room, an ambiguous query.

### 4. Use variables

Never hardcode sensitive values. Use application variables.

### 5. Handle errors

Make sure your API returns clear error messages. The agent will surface them to the tech.

## Next steps

- [Configure parameters](/docs/custom-actions/parameter-configuration)
- [Manage variables](/docs/custom-actions/variables-and-secrets)
- [Test your actions](/docs/custom-actions/testing-and-debugging)
- [View examples](/docs/custom-actions/examples)

*AVCodex · Your AV expertise. Amplified by AI.*
