Relationships
A relationship is the caller’s stored record of one friendship, block, or pending friend request. Each account holds its own record, so one friendship is two records. The private note the caller keeps against another account lives on User notes.
The routes here are user-only. A bot or OAuth2 bearer credential receives 403 ACCESS_DENIED, and an account with an outstanding required action receives 403 ACCOUNT_SUSPICIOUS_ACTIVITY.
A deleted account has the deleted flag with no pending deletion timestamp. An account inside a scheduled deletion window has a timestamp, so it stays a valid friend request target.
Relationship object
Section titled “Relationship object”A relationship record belongs to one account and names one other account. Every field describes the owning account’s side. The caller reads its own record on every operation except the friendly bot auto-acceptance of Send friend request by user ID, which returns the bot’s record.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id1 | snowflake | The ID of the related account |
| type | integer | The relationship type |
| user | partial user object | The related account |
| since?2 | ISO8601 timestamp | The time at which the record’s current type was established |
| nickname3 | ?string | The caller-private nickname for the related account, or null when none is set |
| share_voice_activity4 | boolean | Whether the caller shares voice activity with the related account |
| friend_shares_voice_activity5 | boolean | Whether the related account shares voice activity with the caller |
1 A relationship has no identifier of its own, so this is always the related account’s ID
2 Omitted when the stored record has no timestamp. A nickname write and a sharing rewrite both preserve it, so it does not track the last write
3 Only a FRIEND record has one, and Modify relationship nickname is its only writer. A type change rewrites the record, so a nickname does not survive one
4 A FRIEND record is written with the owning account’s default when the friendship is created. Every non-FRIEND record is written with true
5 Only List relationships resolves the reciprocal record. Every other operation reports true, and so does List relationships for a record with no reciprocal of its type
Example
Section titled “Example”{ "id": "1501314428688998182", "type": 1, "user": {"id": "1501314428688998182", "username": "aria", "discriminator": "0042"}, "since": "2026-01-14T09:31:00.000Z", "nickname": "climbing partner", "share_voice_activity": true, "friend_shares_voice_activity": false}Relationship types
Section titled “Relationship types”| Value | Name | Description |
|---|---|---|
| 1 | FRIEND | The two accounts are friends |
| 2 | BLOCKED | The caller has blocked the related account |
| 3 | INCOMING_REQUEST | The related account has sent the caller a friend request |
| 4 | OUTGOING_REQUEST | The caller has sent the related account a friend request |
Bulk ignore result object
Section titled “Bulk ignore result object”A bulk ignore result reports how many incoming friend requests one call removed.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| ignored_count | integer | The number of incoming friend requests that were removed |
Bulk ignore filters
Section titled “Bulk ignore filters”| Value | Name | Description |
|---|---|---|
| all | All | Matches every incoming friend request |
| new_accounts1 | New accounts | Matches an incoming friend request whose sender account is younger than max_account_age_seconds |
1 The age comparison applies only when max_account_age_seconds is supplied, so this filter matches every incoming request when that member is absent
Relationship limit
Section titled “Relationship limit”The max_relationships limit governs the combined number of friendship, block, and pending request records one account holds. Fluxer resolves it from the account’s traits and premium state, so the value can be higher for a premium account. The fallback is 1000 when the deployment resolves no rule. The registry entry is listed under limit keys.
Fluxer refuses the write once the stored record count reaches the resolved value. It checks the caller and the target independently, and a request fails when either has reached that value.
A refusal returns 400 MAX_FRIENDS with the applied value in a top-level max_relationships member. Fluxer skips the limit for a bot account on either side, for a block, and under staff forced acceptance.
List relationships
Section titled “List relationships”GET/v1/users/@me/relationshipsReturns every relationship object the caller holds, covering friendships, blocks, and pending requests in both directions.
The operation is not paged, and the whole set comes back in one response. The order is not dependable. friend_shares_voice_activity is meaningful only in this response, and every other operation reports it as true.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | array[relationship object] | Relationships were returned |
Rate limit
Section titled “Rate limit”40 requests per 10 seconds for each authenticated user, on the user:relationships:list bucket.
Send friend request by tag
Section titled “Send friend request by tag”POST/v1/users/@me/relationshipsSends a friend request to the account identified by username and discriminator. Returns a relationship object on success.
Limitations
Section titled “Limitations”- An unresolved tag returns 400
NO_USERS_WITH_FLUXERTAG_EXIST. - A resolved deleted account returns 400
FRIEND_REQUEST_BLOCKED. - An existing friendship returns 400
ALREADY_FRIENDS.
Fluxer resolves the tag to exactly one account before any relationship rule runs. Every remaining admission rule is the one described under Send friend request by user ID.
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| username1 | string | The username of the target account |
| discriminator2 | string | integer | The discriminator of the target account |
1 Trimmed before validation, then 1 to 32 characters of ASCII letters, digits, and underscores. It cannot be everyone or here, or contain fluxer or system message, in any casing
2 An integer and a decimal string of 1 to 4 digits are both accepted, and 0007 and 7 resolve the same account
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | relationship object | A pending request, an existing relationship, or an accepted friendship was returned |
| 400 | error response | The tag is unresolved, the caller or target is ineligible, target or block policy rejects the request, deployment policy disables the operation, or the relationship limit is reached |
| 403 | error response | The caller’s email address is unverified and the request returns FRIEND_REQUEST_EMAIL_VERIFICATION_REQUIRED |
| 404 | error response | The caller or resolved target no longer exists, or the pending request being accepted has been withdrawn |
Side effects
Section titled “Side effects”The side effects are those of Send friend request by user ID. Neither route opens a direct message channel.
Rate limit
Section titled “Rate limit”10 requests per minute for each authenticated user, on the user:friend_request:send bucket, shared with Send friend request by user ID.
Send friend request by user ID
Section titled “Send friend request by user ID”POST/v1/users/@me/relationships/{user_id}Sends a friend request to the selected account. Returns a relationship object on success.
Admission is ordered. The deployment direct message policy runs first, so an ordinary caller receives 400 DIRECT_MESSAGES_DISABLED while that policy disables direct messages. A caller with the STAFF flag skips that first evaluation, whether or not it requests forced acceptance. When the target has already sent a request, a staff caller’s send turns into an acceptance and still receives 400 DIRECT_MESSAGES_DISABLED. An unresolved caller then returns 404 UNKNOWN_USER.
The caller’s own ID returns 400 CANNOT_SEND_FRIEND_REQUEST_TO_SELF. An unresolved target returns 404 UNKNOWN_USER. A deleted target returns 400 FRIEND_REQUEST_BLOCKED.
Fluxer consults the current relationship state next. A pending request from the target is accepted. An existing friendship or outgoing request is returned unchanged. The rules that follow apply to a genuinely new request alone, so they never refuse an existing friend.
The remaining rules reject an unclaimed caller with 400 UNCLAIMED_ACCOUNT_CANNOT_SEND_FRIEND_REQUESTS and an unverified email with 403 FRIEND_REQUEST_EMAIL_VERIFICATION_REQUIRED. A bot target is rejected with 400 FRIEND_REQUEST_BLOCKED unless it has FRIENDLY_BOT. A target with the internal app store reviewer flag is rejected with the same code.
A target the caller has blocked returns 400 CANNOT_SEND_FRIEND_REQUEST_TO_BLOCKED_USER. A target that has blocked the caller returns 400 FRIEND_REQUEST_BLOCKED. Fluxer reads the target’s friend source flags next1, and a target accepting requests only from mutual friends or mutual guild members rejects an unrelated caller with 400 FRIEND_REQUEST_BLOCKED. The relationship limit applies last, independently for both accounts.
1 The friend source evaluation is skipped when the target has no stored settings, which admits the request as though the target permitted requests from anyone
That path also skips the rules that follow it: the target’s block of the caller, the target’s friend source flags, the app store reviewer rule, the relationship limit, and friendly bot auto-acceptance. The caller’s own block of the target is still enforced and still returns 400 CANNOT_SEND_FRIEND_REQUEST_TO_BLOCKED_USER. The policy path can also set the SPAMMER flag on the caller, which makes every later send one-sided.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| user_id | snowflake | The ID of the target account |
JSON body
Section titled “JSON body”The body can be omitted, in which case it is treated as an empty object.
| Field | Type | Description |
|---|---|---|
| staff_force_accept?1 | boolean | Whether the friendship is created immediately without a pending request |
1 Honoured only when the caller has the STAFF flag, and a caller without it is treated as though the member were absent. The stored flag governs, so hidden staff status still qualifies
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | relationship object | A pending request, an existing relationship, or an accepted friendship was returned |
| 400 | error response | The caller or target is ineligible, target or block policy rejects the request, deployment policy disables the operation, or the relationship limit is reached |
| 403 | error response | The caller’s email address is unverified and the request returns FRIEND_REQUEST_EMAIL_VERIFICATION_REQUIRED |
| 404 | error response | The caller, the target account, or the pending request being accepted does not exist |
Side effects
Section titled “Side effects”A new request writes matching OUTGOING_REQUEST and INCOMING_REQUEST records and emits Relationship Add to both accounts. Both records are written with share_voice_activity set to true.
When the target has already sent the caller a request, the operation accepts that request. Acceptance replaces both pending records with FRIEND records and emits Relationship Update to both accounts, each side taking its own sharing default. No acceptance path on this route opens a direct message channel, unlike Accept request or block user.
A bot target that has FRIENDLY_BOT without FRIENDLY_BOT_MANUAL_APPROVAL accepts in the same call, so the caller observes Relationship Add followed by Relationship Update. Both flags are read only on a bot account. The response body of that call is the bot’s own record, and its id and user name the caller and its share_voice_activity is the bot’s default. The Dispatch the caller receives has the caller’s record.
Staff forced acceptance replaces every existing record between the two accounts, in either direction, with a friendship, and emits Relationship Add to both. A replaced record emits at most one Relationship Remove to each account first. When the two accounts already hold a mutual friendship and nothing else, the existing record comes back unchanged. Forced acceptance still enforces the self rule, both unresolved account rules, the deleted account rule on both parties, the unclaimed account rule, and the email verification rule. It enforces no relationship rule, so it overrides a block in either direction, the target’s friend source flags, the bot target rule, and the relationship limit.
Rate limit
Section titled “Rate limit”10 requests per minute for each authenticated user, on the user:friend_request:send bucket, shared with Send friend request by tag.
Accept request or block user
Section titled “Accept request or block user”PUT/v1/users/@me/relationships/{user_id}Accepts a pending incoming friend request, or blocks the selected account when the body selects BLOCKED. Returns a relationship object on success.
Acceptance evaluates the deployment direct message policy first and returns 400 DIRECT_MESSAGES_DISABLED while that policy disables direct messages, with no staff exemption. An unresolved caller or requester returns 404 UNKNOWN_USER. A deleted account on either side returns 400 FRIEND_REQUEST_BLOCKED. An unclaimed caller returns 400 UNCLAIMED_ACCOUNT_CANNOT_ACCEPT_FRIEND_REQUESTS. A missing pending incoming request returns 404 UNKNOWN_USER, and the relationship limit then applies to both accounts. Acceptance has no email verification requirement.
Blocking returns 404 UNKNOWN_USER for an unresolved target and 400 CANNOT_BLOCK_SYSTEM_USER for the Fluxer system account. Those are its only admission rules, so blocking runs regardless of the deployment direct message policy, the unclaimed account rule, the email verification rule, and the relationship limit. It applies no self-target rule.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| user_id | snowflake | The ID of the target account |
JSON body
Section titled “JSON body”The body can be omitted, in which case it is treated as an empty object and acceptance is selected.
| Field | Type | Description |
|---|---|---|
| type?1 | integer | The relationship type selecting the operation |
1 One of the four enumerated types when present. Only BLOCKED selects blocking, and every other accepted value selects acceptance
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | relationship object | The friendship or the block was returned |
| 400 | error response | An account is ineligible, the block target is the system account, deployment policy disables acceptance, or the relationship limit is reached |
| 404 | error response | The target account does not exist, or no pending incoming request exists |
Side effects
Section titled “Side effects”Acceptance replaces the pending records with FRIEND records on both accounts and emits Relationship Update to each. It then opens the pair’s direct message channel for both accounts, creating the channel when none exists, and emits Channel Create to each account whose open state changed. No other relationship operation opens one.
Blocking replaces the caller’s existing friendship or pending request with a BLOCKED record. Removing a friendship or an outgoing request also removes the target’s reciprocal record and emits Relationship Remove to the target. Removing an incoming request touches the caller’s record alone. Relationship Add then reaches the caller for the block. Blocking an already blocked target changes nothing. Blocking never closes or deletes the pair’s direct message channel.
Rate limit
Section titled “Rate limit”20 requests per 10 seconds for each authenticated user, on the user:friend_request:accept bucket.
Remove relationship
Section titled “Remove relationship”DELETE/v1/users/@me/relationships/{user_id}Removes the caller’s current friendship, pending friend request in either direction, or block involving the selected account. Returns 204 with an empty body on success.
The route reads no request body. The caller’s current record determines what is removed. A caller holding no record of any type receives 404 UNKNOWN_USER. Removal has no deployment policy, email verification, unclaimed account, or limit rule, so a relationship stays removable while every creation path is closed.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| user_id | snowflake | The ID of the related account |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | The relationship was removed |
| 404 | error response | No relationship of any type exists with the target |
Side effects
Section titled “Side effects”Removing a friendship or an outgoing request removes both accounts’ records and emits Relationship Remove to each account.
A block is stored on one account only, so removing one deletes the caller’s record and emits Relationship Remove to the caller alone.
Rate limit
Section titled “Rate limit”30 requests per 10 seconds for each authenticated user, on the user:relationship:delete bucket.
Modify relationship nickname
Section titled “Modify relationship nickname”PATCH/v1/users/@me/relationships/{user_id}Sets or clears the caller’s private nickname for a friend. Returns the updated relationship object. Emits a Relationship Update Gateway event.
Only a FRIEND record accepts a nickname, and every other relationship state returns 404 UNKNOWN_USER.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| user_id | snowflake | The ID of the friend |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| nickname1 | ?string | The nickname to store, or null to clear it |
1 The member is required, so an empty body is rejected. The value is trimmed, stripped of the form feed and right-to-left override characters, and then at most 256 characters
A literal empty string clears the nickname, the same as null. A value that is only whitespace normalises to an empty string and is stored as one.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | relationship object | The updated relationship was returned |
| 404 | error response | No FRIEND record exists with the target |
Side effects
Section titled “Side effects”The record changes only for the caller, and the sharing preference keeps its stored value. A stored since value is preserved, and a record that has none is stamped with the current time. Relationship Update reaches the caller for every accepted request, including one that submits the value already stored.
Rate limit
Section titled “Rate limit”30 requests per 10 seconds for each authenticated user, on the user:relationship:update bucket.
Ignore pending requests in bulk
Section titled “Ignore pending requests in bulk”POST/v1/users/@me/relationships/bulk-ignoreRemoves matching incoming friend requests. Returns a bulk ignore result object on success.
Matching applies only to the caller’s INCOMING_REQUEST records. Fluxer derives a sender’s account age from the timestamp embedded in its snowflake and compares it against max_account_age_seconds as an exclusive upper bound, so a sender exactly that old is not matched. One call removes every matching request.
JSON body
Section titled “JSON body”The body can be omitted, in which case it is treated as an empty object and the all filter applies.
| Field | Type | Description |
|---|---|---|
| filter? | string | The bulk ignore filter to apply (default all) |
| max_account_age_seconds?1 | integer | The exclusive maximum sender account age in seconds |
1 A positive integer, read only by the new_accounts filter
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | bulk ignore result object | Matching requests were removed |
Side effects
Section titled “Side effects”Each matched request removes the caller’s INCOMING_REQUEST record and the sender’s OUTGOING_REQUEST record, and emits Relationship Remove to the caller and to the sender. A call that matches nothing changes nothing.
Fluxer processes senders one at a time, and the operation is not atomic across them. A failure part of the way through keeps the removals already made, and the call returns no count.
Rate limit
Section titled “Rate limit”5 requests per minute for each authenticated user, on the user:friend_request:bulk_ignore bucket.