Skip to navigation
Plugin Building MasterclassEnd-to-End Course

Build Focused Actions

Create reusable HTTP actions with typed inputs, a single API operation, safe request mapping, and concise outputs.
View as Markdown

An action is one reusable executable operation. An HTTP action represents one HTTP request. Other action types cover code, model work, platform capabilities, and backend composition.

Choose the Action Type

Action typeUse it for
HTTP actionCall one REST or SOAP operation
Script actionApply focused Python logic or transformation
Built-in actionUse a capability provided by Moveworks
LLM actionExtract, classify, or generate unstructured content
Compound actionCoordinate several backend operations behind one contract

Do not model every action as an API call. Keep the name aligned with the operation it actually performs.

Step 1: Define Typed Input Arguments

Input arguments make an action reusable. Define the values the caller must provide without coupling the action to a specific conversation.

For a Get feature requests HTTP action:

ArgumentTypePurpose
statusstringOptional status filter
limitintegerMaximum records to return

For an Update feature request HTTP action:

ArgumentTypePurpose
feature_request_idstringStable downstream record ID
new_statusstringAllowed target state
Keep Conversation Out of the Action Contract

Name arguments for business data, not for where the data came from. A slot, webhook payload, schedule body, compound action, or another process can supply the same action input.

Step 2: Configure One HTTP Operation

An HTTP action defines:

Connector
HTTP connectorRequired

Supplies the base URL and authentication configuration.

Method
GET | POST | PUT | PATCH | DELETERequired

Matches the downstream API operation.

Endpoint
pathRequired

Begins with / and is appended to the connector base URL.

Headers
key-value map

Adds operation-specific headers such as content type, version, tenant, or instance.

Query Parameters
key-value map

Adds filtering, pagination, sorting, or operation flags.

Request Body
JSON, XML, form, or binary

Sends the payload required by write operations.

Response Schema
schema

Keeps only the fields the caller needs and establishes a stable output contract.

Build Along: Create the PurpleSuite Actions

Use the explorer to inspect the current Community API contract. It reads public catalog and OpenAPI metadata, then translates the selected operation into an Agent Studio action outline. It never requests credentials or executes the operation.

PurpleSuite API explorer

Choose a mock enterprise system and operation. The explorer reads public OpenAPI metadata and generates an Agent Studio action outline without requesting or storing credentials.

Catalog snapshot
Loading the public OpenAPI spec…
Security boundary: this explorer fetches only public catalog and OpenAPI metadata. It does not ask for, persist, or transmit a PurpleSuite PAT or instance ID, and it never runs write operations.
PurpleSuite end-to-end call trace

Follow one live feature request through the same three API calls and Agent Studio contracts in every chapter.

Shared connector
https://marketplace.moveworks.com
Every API action
Connector adds Bearer PAT. Action adds X-Instance-ID.
Create the three focused HTTP operations
Build and test the resolver read, update write, and verification read as independent actions.
List candidatesAPI callDynamic resolver + List action
GET /api/purple-suite/community/feature_requests
$filter: currentStatus ne 'Planned'
$select: id,name,currentStatus,productArea
$top: 10
Receives
Resolver invocation and optional search context
Returns
{ data: FeatureRequest[], nextCursor, total }
How it fits
This is the first real API call. The resolver uses the response list, so the assistant can select only records that PurpleSuite returned.
Successful run: actual API call ledger
1GET/api/purple-suite/community/feature_requestsDynamic resolver retrieves live candidates
2PATCH/api/purple-suite/community/feature_requests/{id}Compound action updates the selected record
3GET/api/purple-suite/community/feature_requests/{id}Compound action verifies the stored result
Use a record returned by your own PurpleSuite instance. Save its original status before the write and restore it after mutation testing when appropriate.

Create these three HTTP actions with the connector from the previous chapter:

ActionMethod and endpointInputsPurpose
List PurpleSuite feature requestsGET /api/purple-suite/community/feature_requests$filter, $select, and $top query parametersSupplies live resolver candidates
Get PurpleSuite feature requestGET /api/purple-suite/community/feature_requests/{{{feature_request_id}}}feature_request_idVerifies the final record state
Update PurpleSuite feature requestPATCH /api/purple-suite/community/feature_requests/{{{feature_request_id}}}feature_request_id, new_statusChanges one selected request

Add X-Instance-ID as an action header for all three operations. For the update action, map a JSON body with only the field being changed:

{
"currentStatus": "{{{new_status}}}"
}

Configure the list action with the query parameters used by the dynamic resolver:

Query parameterValue
$filtercurrentStatus ne 'Planned'
$selectid,name,currentStatus,productArea
$top10

Run the three actions in the same order the complete plugin uses:

  1. Run List PurpleSuite feature requests and save one returned record’s id, name, and original currentStatus.
  2. Run Get PurpleSuite feature request with that ID and verify the same record is returned.
  3. Run Update PurpleSuite feature request with the ID and new_status: Planned.
  4. Run the get action again and verify currentStatus is Planned.
  5. Restore the original status when appropriate for your development instance.

Your checkpoint is three independently tested actions with stable, minimal response schemas.

Step 3: Place Variables Safely

HTTP actions can reference inputs and supported runtime values in the endpoint, headers, query parameters, body, and JWT claims.

Use double braces when you need escaped string substitution:

{{query}}

Escaping can change characters such as @, /, quotes, or JSON punctuation.

Older Examples Use Mixed Mustache Styles

Some existing quickstarts use double braces for HTTP values. Follow the current HTTP action guidance: use triple braces for raw request substitution, and use Data Mapper when the value must remain a list, object, number, or boolean.

Step 4: Use Runtime User Data Deliberately

In user-triggered execution, an HTTP action can reference supported user attributes through meta_info.user.

{{{meta_info.user.email_addr}}}

Use the bare meta_info.user.email_addr path only in Data Mapper or DSL contexts. Do not assume that user context exists in webhook or scheduled execution. Pass identity as an explicit input when backend work needs it.

Use meta_info.action_instance_id when the downstream API supports an idempotency key.

Step 5: Shape the Response Early

Every field you keep becomes part of a downstream contract. Prefer:

{
"id": "FR-1042",
"name": "Bulk edit requests",
"current_status": "Planned",
"product_area": "Admin"
}

Avoid passing:

{
"raw_record": {
"internal_metadata": {},
"debug": {},
"audit_history": [],
"unused_fields": []
}
}

There are three useful pruning boundaries:

  1. The HTTP action Response Schema removes fields before returning to its caller.
  2. A compound action’s return.output_mapper controls its final return.
  3. A conversation action activity’s Output Mapping controls what enters the conversation process and reasoning context.

Step 6: Test the Action in Isolation

Provide example values for every input argument and test:

  • A successful response.
  • No matching data.
  • Invalid and boundary values.
  • Unauthorized and forbidden responses.
  • Rate limiting and timeouts.
  • Malformed downstream data.
  • A repeated write with the same idempotency key.

The action editor uses the currently logged-in builder for user runtime attributes. This does not prove that every end user has the same downstream access.

Action Quality Checklist

  • The name begins with a clear verb.
  • The action performs one focused operation.
  • Input arguments are typed and reusable.
  • The endpoint path begins with /.
  • The connector supplies secrets; descriptions and mappings do not.
  • Request variables use the correct substitution or mapping method.
  • The response schema includes only useful fields.
  • Errors preserve enough detail for deterministic handling without exposing secrets.
  • The action passes isolated tests before composition.

Deep Dives

Next, map data and context.