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

> ## Agent Instructions
> Use Stable documentation by default. Honor an explicit Beta request or a URL under /docs/beta/. If the requested version conflicts with the installed CLI package or API origin, clarify the target before writing integration code.
> Pages under /docs/beta/ document Beta; other product pages document Stable. Keep the CLI package, commands, API origin, and credentials within the selected version. State the documentation version in your answer.
> For MCP search, always pass version: Stable or version: Beta. Unfiltered search mixes both versions. For filesystem reads, keep Beta queries under /beta/ and exclude /beta/ from Stable queries; discover paths before reading them.
> The public docs base is https://photon.codes/docs. Convert MCP page paths to public URLs under that base, preserving /beta/ when present. Read https://photon.codes/docs/skill.md for version selection and https://photon.codes/docs/llms.txt for the version indexes.

# Space

> Published spectrum-ts type reference.

## Properties

**\_\_platform** `string` *required*

**id** `string` *required*

## Methods

### add()

```typescript theme={null}
add(users: MemberInput): Promise<void>
```

Add members to the current chat. Sugar for `send(addMember(users))`.
Accepts a single `User` or id string, or an array of either — batches
land in one provider call. Fire-and-forget.

Universal API; per-platform constraints (e.g. iMessage: remote + group
only — a DM cannot be converted, create a group via `space.create`)
surface as `UnsupportedError` from the provider's send action.

#### Parameters

**users** `MemberInput` *required*

#### Returns

`Promise<void>`

### avatar()

```typescript theme={null}
avatar(input: string | URL, options?: { mimeType: string }): Promise<void>
```

Set or clear the current chat's avatar (group icon). Sugar for
`send(avatar(input, options?))`.

* `space.avatar("clear")` — remove the current avatar.
* `space.avatar("./icon.png")` — set from a filesystem path; MIME type
  is inferred from the extension.
* `space.avatar(new URL("https://…/icon.png"))` — fetch the avatar
  lazily over the network. Bytes stay in memory (safe in read-only
  environments); MIME type is inferred from the URL pathname extension.
* `space.avatar(buffer, { mimeType })` — set from in-memory bytes;
  `mimeType` is required (enforced at the type level).

Universal API; per-platform constraints (e.g. iMessage: remote + group
only) surface as `UnsupportedError` from the provider's send action.

#### Parameters

**input** `string | URL` *required*

**options** `\{ mimeType: string \}`

#### Returns

`Promise<void>`

```typescript theme={null}
avatar(input: Buffer, options: { mimeType: string }): Promise<void>
```

#### Parameters

**input** `Buffer` *required*

**options** `\{ mimeType: string \}` *required*

#### Returns

`Promise<void>`

### edit()

```typescript theme={null}
edit(message: Message<string, User, Space<unknown>> | undefined, newContent: ContentInput): Promise<void>
```

Rewrite a previously-sent outbound message. Sugar for
`send(edit(newContent, message))`. Accepts `Message | undefined` so
`send` results chain without narrowing; an undefined target throws.

#### Parameters

**message** `Message\<string, User, Space\<unknown\>\> | undefined` *required*

**Type:** `Message<string, User, Space<unknown>> | undefined`

**newContent** `ContentInput` *required*

#### Returns

`Promise<void>`

### getAvatar()

```typescript theme={null}
getAvatar(): Promise<AvatarData | undefined>
```

Download the current chat avatar (group icon). Resolves `undefined` when
the chat has none. The result round-trips into the setter:
`space.avatar(res.data, { mimeType: res.mimeType })`.

Universal API; per-platform constraints (e.g. iMessage: remote + group
only — a DM throws) surface as `UnsupportedError`, as do platforms with
no implementation.

#### Returns

`Promise<AvatarData | undefined>`

### getDisplayName()

```typescript theme={null}
getDisplayName(): Promise<string | undefined>
```

Read the current chat's display name (group/chat title). Resolves
`undefined` when the chat has none — an unnamed group, or a 1:1 chat on a
platform that stores no title for DMs. Round-trips into `space.rename()`.

Universal API; unlike `rename` the read is not group-only. Per-platform
constraints (e.g. iMessage: remote only) surface as `UnsupportedError`, as
do platforms with no implementation.

#### Returns

`Promise<string | undefined>`

### getMembers()

```typescript theme={null}
getMembers(): Promise<User[]>
```

List the chat's current participants, excluding the agent's own account
where the platform can identify it. Each entry is a `User` tagged with
`__platform`; `id` is the user's canonical platform handle (the same
format `space.create` accepts), so results feed straight back into
`add()` / `remove()` / `space.create()`. Platform extras (e.g.
iMessage's `address`/`country`/`service`) ride along untyped — use the
platform instance's `getMembers(space)` for typed extras.

Universal API; per-platform constraints (e.g. iMessage: remote + group
only — a DM throws) surface as `UnsupportedError`, as do platforms with
no implementation.

#### Returns

`Promise<User[]>`

### getMessage()

```typescript theme={null}
getMessage(id: string): Promise<Message<string, User, Space<unknown>> | undefined>
```

Look up a message in this space by its id. Returns `undefined` if the
platform has no way to resolve the id (e.g. cache miss with no by-id
SDK fallback). Used to materialize a `Message` for APIs that require one,
such as `reaction()`.

#### Parameters

**id** `string` *required*

#### Returns

`Promise<Message<string, User, Space<unknown>> | undefined>`

### leave()

```typescript theme={null}
leave(): Promise<void>
```

Leave the current chat with the agent's own account. Sugar for
`send(leaveSpace())`. Fire-and-forget.

Universal API; per-platform constraints (e.g. iMessage: remote + group
only) surface as `UnsupportedError` from the provider's send action.

#### Returns

`Promise<void>`

### read()

```typescript theme={null}
read(message: Message): Promise<void>
```

Mark the conversation as read up to `message`, surfacing a read receipt
to the sender where the platform supports one. Sugar for
`send(read(message))`. Fire-and-forget; only inbound messages can be
marked read.

Granularity is per-platform: WhatsApp Business issues a receipt for
`message` and everything before it; iMessage (remote) marks the whole
chat read. Platforms with no read-receipt concept for bot conversations
(Telegram, Slack) silently no-op, so the signal is best-effort
everywhere — same contract as `startTyping()`.

#### Parameters

**message** `Message` *required*

#### Returns

`Promise<void>`

### remove()

```typescript theme={null}
remove(users: MemberInput): Promise<void>
```

Remove members from the current chat. Sugar for
`send(removeMember(users))`. Accepts the same input shapes as `add`.
Fire-and-forget.

Universal API; per-platform constraints (e.g. iMessage: remote + group
only) surface as `UnsupportedError` from the provider's send action.

#### Parameters

**users** `MemberInput` *required*

#### Returns

`Promise<void>`

### rename()

```typescript theme={null}
rename(displayName: string): Promise<void>
```

Rename the current chat. Sugar for `send(rename(displayName))`.

Universal API; per-platform constraints (e.g. iMessage: remote + group
only) surface as `UnsupportedError` from the provider's send action.

#### Parameters

**displayName** `string` *required*

#### Returns

`Promise<void>`

### responding()

```typescript theme={null}
responding(fn: () => T | Promise<T>): Promise<T>
```

#### Parameters

**fn** `() =\> T | Promise\<T\>` *required*

#### Returns

`Promise<T>`

### send()

```typescript theme={null}
send(content: ReactionBuilder): Promise<Message<string, AgentSender, Space<unknown>> & { content: { emoji: string; target: Message<string, User>; type: "reaction" } } | undefined>
```

A reaction send resolves to the reaction Message (`content` narrowed to
`Reaction`) — the handle to `unsend()` later. Listed before the general
overload so `send(reaction(...))` picks it; every other `ContentBuilder`
fails the `ReactionBuilder` shape and falls through.

#### Parameters

**content** `ReactionBuilder` *required*

#### Returns

`Promise<Message<string, AgentSender, Space<unknown>> & { content: { emoji: string; target: Message<string, User>; type: "reaction" } } | undefined>`

```typescript theme={null}
send(content: ContentInput): Promise<Message<string, AgentSender, Space<unknown>> | undefined>
```

#### Parameters

**content** `ContentInput` *required*

#### Returns

`Promise<Message<string, AgentSender, Space<unknown>> | undefined>`

```typescript theme={null}
send(content: [ContentInput, ContentInput, unknown]): Promise<Message<string, AgentSender, Space<unknown>>[]>
```

#### Parameters

**content** `[ContentInput, ContentInput, unknown]` *required*

**Type:** `[ContentInput, ContentInput, unknown]`

#### Returns

`Promise<Message<string, AgentSender, Space<unknown>>[]>`

### startTyping()

```typescript theme={null}
startTyping(): Promise<void>
```

#### Returns

`Promise<void>`

### stopTyping()

```typescript theme={null}
stopTyping(): Promise<void>
```

#### Returns

`Promise<void>`

### unsend()

```typescript theme={null}
unsend(message: Message<string, User, Space<unknown>> | undefined): Promise<void>
```

Retract a previously-sent outbound message. Sugar for
`send(unsend(message))`. Accepts `Message | undefined` so `send`
results chain without narrowing; an undefined target throws.

#### Parameters

**message** `Message\<string, User, Space\<unknown\>\> | undefined` *required*

**Type:** `Message<string, User, Space<unknown>> | undefined`

#### Returns

`Promise<void>`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.