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

# Team

> Look up a member of the agent's organization and the contact handles they share

`Team.findMember` searches the organization that owns the [agent](/concepts/agents) for members whose name, email address, or user id matches, and returns the WhatsApp, SMS, and email handles each of them chose to share. Pair it with [`Channels.send`](/reference/sdk/channels) to message a colleague without hard-coding a number. Available in tools, jobs, webhooks, triggers, processors, and workflow code steps.

*Verified against lua-cli 3.33.0.*

```ts theme={null}
import { Team } from 'lua-cli';
```

## Quick example

A search returns a list; disambiguate when more than one member matches.

```ts theme={null}
import { Team } from 'lua-cli';

const { matches } = await Team.findMember('Stefan');
const whatsapp = matches[0]?.targets.find((t) => t.channel === 'whatsapp');
```

## Methods

### findMember(name)

Returns the organization members matching a name, email address, or user id, with their shared handles.

```ts theme={null}
Team.findMember(name: string): Promise<DirectoryResolveResult>
```

<ParamField path="name" type="string" required>
  The text to match: a case-insensitive substring of a member's full name or of any of their email addresses, or an exact user id. Whitespace only returns no matches.
</ParamField>

A member is a person with an active membership in the agent's organization, as managed in the admin dashboard; deactivated members are never returned. A handle appears in `targets` only when the member marked it shareable in their profile, so `targets` can be empty. The organization is derived from the agent; you can't resolve members of another organization.

**Returns**

<ResponseField name="result" type="DirectoryResolveResult">
  <Expandable title="properties">
    <ResponseField name="query" type="string">The trimmed text that was matched.</ResponseField>

    <ResponseField name="matches" type="DirectoryMatch[]">
      One entry per matching member: `userId`, `fullName?`, `primaryEmail?`, and `targets`, an array of `DirectoryTarget`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="DirectoryTarget" type="interface">
  <Expandable title="properties">
    <ResponseField name="channel" type="'whatsapp' | 'sms' | 'email'">The channel the handle is for.</ResponseField>
    <ResponseField name="value" type="string">An E.164 number for `whatsapp` and `sms`; an address for `email`.</ResponseField>
    <ResponseField name="label" type="string">The member's own label for the handle, such as `work`.</ResponseField>
    <ResponseField name="validated" type="boolean">Whether the member verified the handle.</ResponseField>
  </Expandable>
</ResponseField>

**Example**

```ts theme={null}
import { LuaTool, Team, Channels } from 'lua-cli';
import { z } from 'zod';

export default class NotifyColleagueTool implements LuaTool {
  name = 'notify_colleague';
  description = 'Send a WhatsApp message to a named teammate';
  inputSchema = z.object({
    name: z.string().describe('Teammate name or email'),
    message: z.string(),
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const { matches } = await Team.findMember(input.name);
    if (matches.length !== 1) {
      return { sent: false, candidates: matches.map((m) => m.fullName ?? m.userId) };
    }
    const target = matches[0].targets.find((t) => t.channel === 'whatsapp');
    if (!target) return { sent: false, reason: 'no shared WhatsApp number' };

    const result = await Channels.send({
      channel: 'whatsapp',
      to: { phoneNumber: target.value },
      text: input.message,
    });
    return { sent: true, deliveryId: result.deliveryId };
  }
}
```

**Errors** — the call throws. In a deployed agent the error is a `DirectoryResolveError` with `code` and `statusCode`; in `lua test` it is a plain `Error` carrying the server's message, or `Directory resolve failed`.

* `name is required` when `name` is empty.
* `Agent is not linked to an organization`.
* A 403 when the agent isn't yours.

## Types

`DirectoryResolveResult`, `DirectoryMatch`, and `DirectoryTarget` are exported from `lua-cli` with the shapes listed under `findMember(name)`.

## See also

* [`Channels`](/reference/sdk/channels) — send to the handle you resolved
* [`User`](/reference/sdk/user) — the end user's own profile, as opposed to organization members
* [Send proactive messages](/build/send-proactive-messages) — cold-start rules per channel
