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

# Users

> Fetch, update and delete user profiles, check usernames, and query follow and connection graphs

The `users` module provides server-side access to user profiles, social graph data (follows and connections), and username availability. All operations use your project API key and do not require a user access token.

***

### fetchUserById

Fetches a user profile by their internal Sublay user ID.

```typescript theme={null}
const user = await sublay.users.fetchUserById({ userId: "usr_abc123" });
```

<ParamField body="userId" type="string" required>
  The Sublay user ID.
</ParamField>

<ParamField body="include" type="string">
  Comma-separated list of associations to populate.
</ParamField>

**Returns** — `Promise<User>`

***

### fetchUserByForeignId

Fetches a user profile by your application's own user identifier. Optionally creates the user if not found.

```typescript theme={null}
const user = await sublay.users.fetchUserByForeignId({
  foreignId: "external-user-42",
  createIfNotFound: true,
  name: "Bob Smith",
  username: "bob",
});
```

<ParamField body="foreignId" type="string" required>
  Your application's user identifier.
</ParamField>

<ParamField body="createIfNotFound" type="boolean">
  When `true`, creates the user with the provided profile fields if no match is found. Defaults to `false`.
</ParamField>

<ParamField body="name" type="string">
  Display name — used only when creating a new user.
</ParamField>

<ParamField body="username" type="string">
  Username — used only when creating a new user.
</ParamField>

<ParamField body="avatar" type="string">
  Avatar URL — used only when creating a new user.
</ParamField>

<ParamField body="bio" type="string">
  Bio text — used only when creating a new user.
</ParamField>

<ParamField body="metadata" type="object">
  Public metadata — used only when creating a new user.
</ParamField>

<ParamField body="secureMetadata" type="object">
  Secure metadata (not exposed to the client) — used only when creating a new user.
</ParamField>

<ParamField body="include" type="string">
  Comma-separated list of associations to populate.
</ParamField>

**Returns** — `Promise<User>`

***

### fetchUserByUsername

Fetches a user profile by their username.

```typescript theme={null}
const user = await sublay.users.fetchUserByUsername({ username: "alice" });
```

<ParamField body="username" type="string" required>
  The user's unique username.
</ParamField>

<ParamField body="include" type="string">
  Comma-separated list of associations to populate.
</ParamField>

**Returns** — `Promise<User>`

***

### updateUser

Updates a user's profile fields.

```typescript theme={null}
const updatedUser = await sublay.users.updateUser({
  userId: "usr_abc123",
  name: "Alice Updated",
  bio: "New bio",
  avatar: "https://cdn.example.com/avatar.jpg",
  location: { latitude: 37.7749, longitude: -122.4194 },
});
```

<ParamField body="userId" type="string" required>
  The Sublay user ID to update.
</ParamField>

<ParamField body="name" type="string">
  New display name.
</ParamField>

<ParamField body="username" type="string">
  New username. Must be available.
</ParamField>

<ParamField body="bio" type="string">
  New bio text.
</ParamField>

<ParamField body="avatar" type="string">
  New avatar URL.
</ParamField>

<ParamField body="metadata" type="object">
  Updated public metadata. Merged with existing metadata.
</ParamField>

<ParamField body="secureMetadata" type="object">
  Updated secure metadata (not exposed in public responses). Merged with existing values.
</ParamField>

<ParamField body="birthdate" type="string">
  ISO 8601 date string for the user's birthdate.
</ParamField>

<ParamField body="location" type="object">
  Geographic location `{ latitude: number; longitude: number }`.
</ParamField>

**Returns** — `Promise<UserFull>`

***

### deleteUser

Permanently deletes a user and cascades cleanup across all of their related data — reactions, files, follows, connections, notifications, collections, reports, and mentions are removed, and their entities and comments are stripped of authored content. This mirrors the full-cascade delete performed from the dashboard.

<Warning>
  This is a hard, irreversible delete — the user and their related data cannot be recovered.
</Warning>

```typescript theme={null}
await sublay.users.deleteUser({ userId: "usr_abc123" });
```

<ParamField body="userId" type="string" required>
  The Sublay user ID to delete.
</ParamField>

**Returns** — `Promise<void>`

***

### fetchUserSuggestions

Returns users whose name or username matches a partial query string. Useful for mention autocomplete on the server.

```typescript theme={null}
const users = await sublay.users.fetchUserSuggestions({ query: "ali" });
```

<ParamField body="query" type="string" required>
  Partial name or username to search for.
</ParamField>

**Returns** — `Promise<User[]>`

***

### checkUsernameAvailability

Checks whether a username is available for registration.

```typescript theme={null}
const { available } = await sublay.users.checkUsernameAvailability({
  username: "alice",
});
```

<ParamField body="username" type="string" required>
  The username to check.
</ParamField>

**Returns** — `Promise<{ available: boolean }>`

***

### fetchFollowersByUserId

Returns a paginated list of users following the specified user.

```typescript theme={null}
const { data, pagination } = await sublay.users.fetchFollowersByUserId({
  userId: "usr_abc123",
  page: 1,
  limit: 20,
});
```

<ParamField body="userId" type="string" required>
  The Sublay user ID.
</ParamField>

<ParamField body="page" type="number">
  Page number (1-indexed). Defaults to `1`.
</ParamField>

<ParamField body="limit" type="number">
  Results per page. Defaults to `20`.
</ParamField>

**Returns** — `Promise<PaginatedResponse<User>>`

***

### fetchFollowersCountByUserId

Returns the total number of followers for a user.

```typescript theme={null}
const { count } = await sublay.users.fetchFollowersCountByUserId({
  userId: "usr_abc123",
});
```

<ParamField body="userId" type="string" required>
  The Sublay user ID.
</ParamField>

**Returns** — `Promise<{ count: number }>`

***

### fetchFollowingByUserId

Returns a paginated list of users that the specified user is following.

```typescript theme={null}
const { data, pagination } = await sublay.users.fetchFollowingByUserId({
  userId: "usr_abc123",
  page: 1,
  limit: 20,
});
```

<ParamField body="userId" type="string" required>
  The Sublay user ID.
</ParamField>

<ParamField body="page" type="number">
  Page number (1-indexed). Defaults to `1`.
</ParamField>

<ParamField body="limit" type="number">
  Results per page. Defaults to `20`.
</ParamField>

**Returns** — `Promise<PaginatedResponse<User>>`

***

### fetchFollowingCountByUserId

Returns the number of users the specified user is following.

```typescript theme={null}
const { count } = await sublay.users.fetchFollowingCountByUserId({
  userId: "usr_abc123",
});
```

<ParamField body="userId" type="string" required>
  The Sublay user ID.
</ParamField>

**Returns** — `Promise<{ count: number }>`

***

### fetchConnectionsByUserId

Returns a paginated list of established mutual connections for a user.

```typescript theme={null}
const { data, pagination } = await sublay.users.fetchConnectionsByUserId({
  userId: "usr_abc123",
  page: 1,
  limit: 20,
});
```

<ParamField body="userId" type="string" required>
  The Sublay user ID.
</ParamField>

<ParamField body="page" type="number">
  Page number (1-indexed). Defaults to `1`.
</ParamField>

<ParamField body="limit" type="number">
  Results per page. Defaults to `20`.
</ParamField>

**Returns** — `Promise<PaginatedResponse<EstablishedConnection>>`

***

### fetchConnectionsCountByUserId

Returns the number of established connections for a user.

```typescript theme={null}
const { count } = await sublay.users.fetchConnectionsCountByUserId({
  userId: "usr_abc123",
});
```

<ParamField body="userId" type="string" required>
  The Sublay user ID.
</ParamField>

**Returns** — `Promise<{ count: number }>`

***

## Acting on a user's follows and connections

The functions above are read-only queries about a target user. The functions below **perform an action** on behalf of one user toward another. Because a service key isn't tied to a single user, these routes take both:

* `userId` — the **target** of the action (the user being followed, connected with, etc.), taken from the request path.
* `actingUserId` — the **actor** performing it (the follower, the requester, the user whose perspective a status is from).

<Note>
  Listing and managing the acting user's own follow/connection graph by record ID
  lives on the dedicated [`follows`](/v7/node-sdk/follows) and
  [`connections`](/v7/node-sdk/connections) modules.
</Note>

***

### createFollow

Makes one user follow another.

```typescript theme={null}
const follow = await sublay.users.createFollow({
  userId: "usr_target",
  actingUserId: "usr_follower",
});
```

<ParamField body="userId" type="string" required>
  The user being followed (the target).
</ParamField>

<ParamField body="actingUserId" type="string" required>
  The user performing the follow (the follower).
</ParamField>

**Returns** — `Promise<Follow>`

***

### deleteFollow

Makes one user unfollow another.

```typescript theme={null}
await sublay.users.deleteFollow({
  userId: "usr_target",
  actingUserId: "usr_follower",
});
```

<ParamField body="userId" type="string" required>
  The user being unfollowed (the target).
</ParamField>

<ParamField body="actingUserId" type="string" required>
  The user performing the unfollow (the follower).
</ParamField>

**Returns** — `Promise<void>`

***

### fetchFollowStatus

Checks whether the acting user follows the target user.

```typescript theme={null}
const { isFollowing, followId } = await sublay.users.fetchFollowStatus({
  userId: "usr_target",
  actingUserId: "usr_viewer",
});
```

<ParamField body="userId" type="string" required>
  The user whose follow relationship is being checked (the target).
</ParamField>

<ParamField body="actingUserId" type="string" required>
  The user whose perspective the status is from.
</ParamField>

**Returns** — `Promise<{ isFollowing: boolean; followId?: string }>`

***

### requestConnection

Sends a connection request from the acting user to the target user.

```typescript theme={null}
const connection = await sublay.users.requestConnection({
  userId: "usr_target",
  actingUserId: "usr_requester",
  message: "Let's connect!",
});
```

<ParamField body="userId" type="string" required>
  The user the connection is requested with (the target).
</ParamField>

<ParamField body="actingUserId" type="string" required>
  The user sending the request (the requester).
</ParamField>

<ParamField body="message" type="string">
  Optional message to include with the request.
</ParamField>

**Returns** — `Promise<Connection>`

***

### fetchConnectionStatus

Returns the connection status between the acting user and the target user.

```typescript theme={null}
const status = await sublay.users.fetchConnectionStatus({
  userId: "usr_target",
  actingUserId: "usr_viewer",
});
// status.status is "none" | "pending" | "connected" | "declined"
```

<ParamField body="userId" type="string" required>
  The other user in the connection (the target).
</ParamField>

<ParamField body="actingUserId" type="string" required>
  The user whose perspective the status is from.
</ParamField>

**Returns** — `Promise<ConnectionStatusResponse>` — a discriminated union on `status`: `"none"`, `"pending"` (with `type` and `connectionId`), `"connected"`, or `"declined"`.

***

### removeConnectionByUserId

Removes the connection between the acting user and the target user — withdrawing a sent request, declining a received one, or disconnecting an established connection, depending on the current state.

```typescript theme={null}
const result = await sublay.users.removeConnectionByUserId({
  userId: "usr_target",
  actingUserId: "usr_viewer",
});
// result.action is "withdraw" | "disconnect" | "decline"
```

<ParamField body="userId" type="string" required>
  The other user in the connection (the target).
</ParamField>

<ParamField body="actingUserId" type="string" required>
  The user withdrawing, declining, or disconnecting.
</ParamField>

**Returns** — `Promise<RemoveConnectionByUserIdResponse>`
