Unit 3: Build Challenge
Hands-On Challenge (25 minutes)
The Goal
Design and build a new orchestrator recipe, deploy it, and invoke it from chat. You’ve seen how the existing tools work end-to-end — now build one yourself.
Choose Your Challenge
| Challenge | Difficulty | Systems | Choose If… |
|---|---|---|---|
| Option A: Extended Stay | Standard | Salesforce only | You don’t have Stripe connected |
| Option B: Room Upgrade | Advanced | Salesforce + Stripe | You have Stripe connected and want a cross-system challenge |
Choose How to Build
You have two paths to build your recipe:
Path 1: Build with a Coding Agent
If you have access to a coding agent (Claude Code, Cursor, GitHub Copilot, etc.), you can install additional tools that give your agent the knowledge to write Workato recipes:
- Install Recipe Skills — an agent-consumable knowledge base covering connector configuration, datapill syntax, control flow, and error handling:
git clone https://github.com/workato-devs/recipe-skills.git -
Install the Recipe Linter — catches datapill syntax errors, schema mismatches, and structural issues:
macOS/Linux:
brew install workato-devs/tap/recipe-lint wk plugins install recipe-lintWindows:
scoop install recipe-lint wk plugins install recipe-lint - (Optional) Install the Recipe Visualizer — VS Code/Cursor/Windsurf extension that renders recipe JSON as interactive workflow graphs. Download the
.vsixfrom the Workato Labs page and install via your IDE.
Your workflow: Agent writes recipe JSON → Linter validates → make push deploys → Test from chat
For full setup details and documentation, see workato-devs.github.io/labs
Path 2: Build in the Workato UI
- Navigate to Projects → orchestrator-recipes in Workato
- Click Create Recipe
- Use the visual recipe editor to build your orchestrator step by step
- Start the recipe when you’re ready to test
Both paths end the same way: invoke your new tool from the hotel app chat and trace the execution in Workato.
Challenge Rules
| Rule | Details |
|---|---|
| Time | 20 minutes to build + test |
| Teams | Individual or pairs |
| Goal | Working orchestrator, invocable from chat |
| Stretch | Trace your tool call end-to-end in Workato logs |
Option A: Extended Stay
The Scenario
A guest currently checked in wants to extend their stay by a few more nights. The front desk needs to verify availability and update the reservation.
Build an extend_stay orchestrator.
Available Atomic Skills
| Atomic Skill | Purpose | Returns |
|---|---|---|
search_contact_by_email | Find guest contact | id, found |
search_booking_by_contact_and_date | Find current booking | booking_id, room_id, check_out_date |
search_bookings_by_room_and_dates | Check availability for new dates | bookings[] or empty |
upsert_booking | Update reservation | booking_id |
update_opportunity_stage | Update revenue tracking | opportunity_id |
Requirements
Input Parameters
| Parameter | Required | Description |
|---|---|---|
guest_email | Yes | Guest’s email address |
new_checkout_date | Yes | New departure date (ISO format) |
idempotency_token | Yes | UUID for retry safety |
Success Criteria
Your solution must:
- Find the guest’s current active booking
- Check room availability for the extended dates
- Update the booking with the new checkout date
- Handle “room unavailable for extension” gracefully
- Be idempotent (safe to retry)
Response Codes
| HTTP Status | Condition | error_code |
|---|---|---|
| 200 | Success | (none) |
| 404 | Guest not found | GUEST_NOT_FOUND |
| 404 | No active booking | NO_ACTIVE_BOOKING |
| 409 | Room not available for extended dates | EXTENSION_NOT_AVAILABLE |
Option B: Room Upgrade
The Scenario
A guest wants to upgrade to a better room and is willing to pay the price difference. This requires checking availability, processing an additional payment, and updating the reservation.
Build an upgrade_room orchestrator that coordinates Salesforce and Stripe.
Available Atomic Skills
Salesforce:
| Atomic Skill | Purpose | Returns |
|---|---|---|
search_contact_by_email | Find guest contact | id, found |
search_booking_by_contact_and_date | Find current booking | booking_id, room_id, room_number, opportunity_id |
search_room_by_number | Find target room | id, status, nightly_rate |
update_room_status | Update room availability | room_id, updated |
upsert_booking | Update reservation | booking_id |
Stripe:
| Atomic Skill | Purpose | Returns |
|---|---|---|
create_stripe_payment_intent | Charge price difference | payment_intent_id |
confirm_stripe_payment | Confirm the charge | status, confirmed |
Requirements
Input Parameters
| Parameter | Required | Description |
|---|---|---|
guest_email | Yes | Guest’s email address |
new_room_number | Yes | Target room for upgrade |
payment_method_id | Yes | Stripe payment method token |
idempotency_token | Yes | UUID for retry safety |
Success Criteria
Your solution must:
- Find the guest’s current active booking
- Validate the target room is available
- Calculate the price difference (remaining nights x rate difference)
- Process the additional payment via Stripe
- Update room statuses (old room → Dirty, new room → Occupied)
- Update the booking with the new room
- Handle payment failures gracefully
- Be idempotent (safe to retry)
Response Codes
| HTTP Status | Condition | error_code |
|---|---|---|
| 200 | Success | (none) |
| 404 | Guest not found | GUEST_NOT_FOUND |
| 404 | No active booking | NO_ACTIVE_BOOKING |
| 404 | Target room not found | ROOM_NOT_FOUND |
| 409 | Target room not available | ROOM_NOT_AVAILABLE |
| 402 | Payment failed | PAYMENT_FAILED |
Deploy and Test
Once your recipe is built:
- Deploy:
- Coding agent path:
wk lintto validate, thenmake pushto deploy - Workato UI path: Save and start the recipe
- Coding agent path:
- Add to an API Collection:
- In Workato, go to Platform → API Platform → API Collections
- Open the
dewy-resort-managercollection - Add your new recipe as an endpoint (Method: POST)
- Write a description that tells the LLM when and how to use your tool
- Enable the endpoint
- Test from chat:
- Open the hotel app as Manager
- Ask the agent to perform the action your tool handles
- Watch the debug panel for your tool invocation
- Check Workato logs to trace the execution
Hints
Hint 1: Order of Operations
Think about dependencies: - What must you validate before making any changes? - For Option B: What happens if payment fails after you've already updated the room? - Validate first, mutate lastHint 2: Checking Extended Dates (Option A)
You need to check availability between: - Current checkout date (from existing booking) - New checkout date (from input) The current booking already covers up to the original checkout date.Hint 3: Calculating Price Difference (Option B)
Price difference = (new_room_rate - old_room_rate) x remaining_nights You'll need: - Current room's nightly rate (from booking or room lookup) - New room's nightly rate (from room lookup) - Remaining nights (checkout_date - today)Hint 4: Idempotency Pattern
Use the `idempotency_token` in multiple places: - As `external_id` in upsert_booking - As `Idempotency-Key` header in Stripe calls (Option B)Facilitator Notes
Pacing: 20 minutes for building, 5 minutes for demo/discussion. If teams finish early, encourage them to trace their tool call in Workato logs or test edge cases (invalid email, unavailable room).
Coding agent path: Attendees using coding agents may finish significantly faster. Encourage them to tackle Option B or refine their error handling and tool description.
If attendees get stuck on recipe-skills setup: The repo README has step-by-step instructions for each agent platform. Prioritize getting the skills loaded — the linter and visualizer are nice-to-haves.
If time is running short: Have attendees focus on designing the steps (which atomics, in what order, what error handling) even if they don’t finish building. The design exercise is still valuable.
Judging Criteria
| Criterion | Weight | What We’re Looking For |
|---|---|---|
| Working End-to-End | 40% | Can it be invoked from chat and produce the right result? |
| Composition | 25% | Proper use of atomic skills? Logical ordering? |
| Error Handling | 20% | What happens when things go wrong? Structured error codes? |
| Tool Description | 15% | Would the LLM know when and how to use this tool? |
Solution Walkthrough
Option A: Extended Stay
extend_stay
|
+-- search_contact_by_email
| +-- Error if not found: 404 GUEST_NOT_FOUND
|
+-- search_booking_by_contact_and_date
| +-- Error if not found: 404 NO_ACTIVE_BOOKING
| +-- Save: current checkout_date, room_id
|
+-- search_bookings_by_room_and_dates
| +-- Check: current_checkout_date to new_checkout_date
| +-- IF conflicts exist: 409 EXTENSION_NOT_AVAILABLE
|
+-- upsert_booking
| +-- Update: check_out_date = new_checkout_date
| +-- Uses: idempotency_token as external_id
|
+-- Return: booking_id, new_checkout_date, total_nights
Option B: Room Upgrade
upgrade_room
|
+-- search_contact_by_email
| +-- Error if not found: 404 GUEST_NOT_FOUND
|
+-- search_booking_by_contact_and_date
| +-- Error if not found: 404 NO_ACTIVE_BOOKING
| +-- Save: room_id (old), opportunity_id, checkout_date
|
+-- search_room_by_number (target room)
| +-- Error if not found: 404 ROOM_NOT_FOUND
| +-- Error if not Vacant: 409 ROOM_NOT_AVAILABLE
| +-- Save: new room_id, nightly_rate
|
+-- Calculate price difference
| +-- (new_rate - old_rate) x remaining_nights
|
+-- create_stripe_payment_intent + confirm_stripe_payment
| +-- Error if fails: 402 PAYMENT_FAILED
| +-- Use idempotency_token as Idempotency-Key
|
+-- update_room_status (old room -> Dirty)
|
+-- update_room_status (new room -> Occupied)
|
+-- upsert_booking (update room reference)
|
+-- Return: booking_id, previous_room, new_room, amount_charged
Key Teaching Points
| Point | Why It Matters |
|---|---|
| Validate everything before mutating | Prevents partial updates on failure |
| Check availability for the RIGHT date range | Common mistake: checking wrong dates |
| Payment before room updates (Option B) | Don’t change rooms if payment fails |
| Idempotency at every external call | Safe retries across systems |
Common Mistakes
| Mistake | Better Approach |
|---|---|
| Checking wrong date range for availability | Extension: check from current checkout TO new checkout |
| Updating rooms before payment confirmed | Process payment first, then update state |
| Forgetting to calculate price difference | Need both room rates and remaining nights |
| No rollback plan for partial failures | Design for all-or-nothing where possible |
| Vague tool description | Be specific about required params and error codes — the LLM needs this |