Tutorials/Copilot Studio/Building a Multi-Input Lookup Agent with Copilot Studio
Copilot Studiointermediate

Building a Multi-Input Lookup Agent with Copilot Studio

Handle diverse user inputs gracefully by letting your Copilot Studio agent accept names, emails, or custom codes in a single prompt. Here's how to set it up and route the query logic intelligently.

NA
Narmer Abader
@narmer · Published June 3, 2026

When building a conversational agent that looks up records, you can't always enforce a single input method. A helpdesk agent might need an employee ID, an email, or a full name. An event concierge might need a ticket number, email, or full name.

Forcing users into a rigid menu ("Type 1 for name, 2 for email...") breaks the natural flow of conversation. A much better approach is to ask a single, open-ended question and let the AI detect exactly what type of identifier the user provided.

In this guide, I'll show you how to build an Event Registration Concierge Agent that can accept a full name, email address, or an 8-character confirmation code. The agent will figure out which one it received and look up the right record.

Creating the Registration Topic

Let's start by creating a new custom topic in Copilot Studio. Name it Find My Registration.

Set the trigger phrases to cover how a user might ask for their details:

  • "Look up my registration"
  • "Find my ticket"
  • "Check in for the conference"
  • "What is my seat assignment?"

1. Setting Up the Backend Data

To search for attendees, we need a data source. I built a Dataverse table called cr8a5_Attendee. You can use a SharePoint list with identical columns; the logic translates perfectly.

Here's the schema I used:

Column NameData TypePurpose
Full NameTextAttendee's full name
Email AddressTextAttendee's email
Confirmation CodeTextUnique 8-char code
Ticket TypeChoice (Option Set)VIP, Standard, or Workshop
Checked InYes/NoOnsite check-in status

Populate this with a handful of test records so Copilot Studio has data to query later.

2. Configuring the Question Node

Add a Question node to the topic. The prompt text should be flexible:

"Please tell me your full name, the email you registered with, or your 8-digit confirmation code."

Under Identify, select One of multiple entities. This tells the model to attempt matching the user's response against several different entity types.

Check the built-in entities Person name and Email.

Custom Entity with Regex

For the confirmation code, we need a custom entity. Click New EntityCreate an entity and choose Regular expression (Regex).

  • Name: Confirmation Code
  • Description: Matches the standard 8-character code
  • Pattern: [A-Z0-9]{8}

Make sure your regex is precise enough to avoid false matches but flexible enough to catch the actual codes in your system. If your codes are case-insensitive, adjust to [A-Za-z0-9]{8}.

Your question node should now be looking for Person Name, Email, and Confirmation Code.

3. Understanding the Output Object

A common point of confusion here is the data shape of the question node's output. The node creates a record variable (let's call it detectedInfo). This record has a property for every entity type you selected.

When a user responds, only the property matching the detected entity receives a value. The rest are blank strings.

For example, if the user says "Code: A1B2C3D4", the variable looks like this:

jsonExample output of the detected entity object
{
"Person name": "",
"Email": "",
"Confirmation Code": "A1B2C3D4"
}

This behavior is key to the branching logic we'll set up next.

4. Branching the Logic

Beneath the Question node, add three Condition nodes:

  1. detectedInfo.Person name is not blank
  2. detectedInfo.Email is not blank
  3. detectedInfo.Confirmation Code is not blank

Each branch will hold a different database query tailored to the entity type detected.

5. Querying the Data

Inside each condition branch, add a List Rows action (if using Dataverse) or Get Items (if using SharePoint). Give the action a descriptive name like List Attendees by Name.

Person Name Branch (Power Fx):

powerfxFilter by Full Name
Filter(cr8a5_attendees, cr8a5_fullname = detectedInfo.'Person name')

Email Branch (Power Fx):

powerfxFilter by Email
Filter(cr8a5_attendees, cr8a5_emailaddress = detectedInfo.Email)

Confirmation Code Branch (Power Fx):

powerfxFilter by Code
Filter(cr8a5_attendees, cr8a5_confirmationcode = detectedInfo.'Confirmation Code')
Filter Delegation

These Filter expressions are delegable for both Dataverse and SharePoint text columns, meaning they run server-side no matter the list size. Still, always test your topic with realistic volumes to ensure performance meets your expectations.

6. Extracting and Displaying the Result

The List Rows action outputs a table variable (for example, colAttendees). Since we only want the single matching record, we need to pull it out of the array.

After the three condition branches converge, add a Set Variable Value node. Create a new variable called attendeeRecord and set it using the First function:

powerfxExtract the single matching row
First(colAttendees.Value)

Now we can display the data. Add a Message node with the following text. Notice how I use Power Fx expressions inside curly braces to reference the record values:

textAttendee details message
I found your record, {attendeeRecord.cr8a5_fullname}!

Here are your registration details:

- **Ticket Type:** {attendeeRecord.cr8a5_tickettype}
- **Checked In:** {attendeeRecord.cr8a5_checkedin}
- **Confirmation Code:** {attendeeRecord.cr8a5_confirmationcode}

Is there anything else I can help you with?

7. Testing the Agent

Open the Test pane in Copilot Studio and try a few diverse inputs:

The agent should correctly follow the name, email, or code branch and return the matching attendee record.

Testing Tips

If a branch doesn't fire, check the entity names in your condition nodes. A simple typo or missing space in your Power Fx can silently break the logic. The Test pane's Trace view is your best friend for debugging.

Common Pitfalls and Troubleshooting

1. The Question Node returns an object, not a string This is the most common misunderstanding of the "One of multiple entities" feature. You cannot directly compare the entire output to a value. You must check the individual property that matches your entity type.

2. Regex is too strict If your regex pattern is too narrow (e.g., [A-Z]{8} when codes include numbers), the AI won't match it. Always test your pattern on the exact data your users will enter.

3. Spaces in entity names Power Fx requires single quotes around identifiers with spaces. For example, detectedInfo.'Confirmation Code' works, while detectedInfo.Confirmation Code will cause a parsing error.

4. Forgetting the fallback branch If the user's input doesn't match any entity, the flow falls into the All other conditions branch. Always add a message there, such as: "I'm sorry, I couldn't find a registration with that information. Please try your full name, email, or confirmation code." Then add an End current topic action to the branch.

5. Overexposing data Be mindful of what your agent displays. If someone enters a name and the agent returns a record, make sure the user is authorized to see that information. For internal HR agents, consider adding an authentication step or limiting the result set to the currently authenticated user.

Final Recommendation

The "one of multiple entities" pattern is a cornerstone of natural, flexible conversational AI. By accepting multiple identifiers in a single prompt and branching intelligently, you remove friction from the user experience.

This pattern isn't limited to simple lookups. You could extend it to update records, trigger workflows, or route the conversation to different system topics based on the entity detected.

Start with a simple lookup like the one in this guide. Once you understand how the output object and conditions work, you can apply the same logic to even more complex scenarios.

References