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

# How to join a community on Twitter via API

> Learn how to join a Twitter Community by ID with one connected account. Track API responses, verify membership, and resolve invitation or eligibility failures.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-write-join-community-200">
      ```json theme={null}
      {
        "object": "x_write_action",
        "id": "12345",
        "writeActionId": "12345",
        "action": "join_community",
        "status": "success",
        "terminal": true,
        "retryable": false,
        "safeToRetry": false,
        "statusUrl": "/api/v1/x/write-actions/12345",
        "pollAfterMs": null
      }
      ```
    </Tab>

    <Tab title="202" id="response-x-write-join-community-202">
      ```json theme={null}
      {
        "object": "x_write_action",
        "id": "12346",
        "writeActionId": "12346",
        "action": "join_community",
        "status": "dispatching",
        "terminal": false,
        "retryable": false,
        "safeToRetry": false,
        "statusUrl": "/api/v1/x/write-actions/12346",
        "pollAfterMs": 2000
      }
      ```
    </Tab>

    <Tab title="400" id="response-x-write-join-community-400">
      ```json theme={null}
      {
        "error": "missing_idempotency_key",
        "message": "Idempotency-Key is required. Generate one unique key for this write.",
        "charged": false,
        "chargedCredits": "0",
        "retryable": false,
        "safeToRetry": true
      }
      ```
    </Tab>

    <Tab title="401" id="response-x-write-join-community-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required. Provide a valid API key or bearer token."
      }
      ```
    </Tab>

    <Tab title="402" id="response-x-write-join-community-402">
      ```json theme={null}
      {
        "error": "insufficient_credits",
        "message": "Insufficient credits. Top up or subscribe to continue."
      }
      ```
    </Tab>

    <Tab title="403" id="response-x-write-join-community-403">
      ```json theme={null}
      {
        "error": "account_needs_reauth",
        "message": "X account needs re-authentication. Re-add the account."
      }
      ```
    </Tab>

    <Tab title="404" id="response-x-write-join-community-404">
      ```json theme={null}
      {
        "error": "account_not_found",
        "message": "X account not found. Connect it first at /dashboard/account?tab=x-accounts."
      }
      ```
    </Tab>

    <Tab title="409" id="response-x-write-join-community-409">
      ```json theme={null}
      {
        "error": "idempotency_conflict",
        "message": "Idempotency-Key was already used with a different request.",
        "charged": false,
        "chargedCredits": "0",
        "retryable": false,
        "safeToRetry": true
      }
      ```
    </Tab>

    <Tab title="422" id="response-x-write-join-community-422">
      ```json theme={null}
      {
        "error": "x_rejected",
        "message": "X rejected this request. Check what you sent & the account on x.com before you try again."
      }
      ```
    </Tab>

    <Tab title="429" id="response-x-write-join-community-429">
      ```json theme={null}
      {
        "error": "rate_limit_exceeded",
        "message": "Too many requests. Try again later.",
        "retryAfter": 60
      }
      ```
    </Tab>

    <Tab title="500" id="response-x-write-join-community-500">
      ```json theme={null}
      {
        "error": "x_write_failed",
        "message": "Write action failed unexpectedly. Contact support if this persists."
      }
      ```
    </Tab>

    <Tab title="503" id="response-x-write-join-community-503">
      ```json theme={null}
      {
        "error": "write_tracking_unavailable",
        "message": "Write tracking unavailable. Try again.",
        "charged": false,
        "chargedCredits": "0",
        "retryable": true,
        "safeToRetry": true
      }
      ```
    </Tab>
  </Tabs>
</Panel>

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

<Callout icon="coins" color="#5c3327">
  **10 credits per call** · [All plans](https://xquik.com/#pricing) from \$0.00012/credit
</Callout>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://xquik.com/api/v1/x/communities/1893726451023847424/join \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -H "Idempotency-Key: community-join-1895432178065391234" \
    -H "Content-Type: application/json" \
    -d '{
      "account": "myxhandle"
    }' | jq
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/x/communities/1893726451023847424/join", {
    method: "POST",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
      "Idempotency-Key": "community-join-1895432178065391234",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      account: "myxhandle",
    }),
  });
  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://xquik.com/api/v1/x/communities/1893726451023847424/join",
      headers={
          "x-api-key": "xq_YOUR_KEY_HERE",
          "Idempotency-Key": "community-join-1895432178065391234",
      },
      json={
          "account": "myxhandle",
      },
  )
  data = response.json()
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
  )

  func main() {
      body, _ := json.Marshal(map[string]interface{}{
          "account": "myxhandle",
      })

      req, err := http.NewRequest("POST", "https://xquik.com/api/v1/x/communities/1893726451023847424/join", bytes.NewReader(body))
      if err != nil {
          panic(err)
      }
      req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")
      req.Header.Set("Idempotency-Key", "community-join-1895432178065391234")
      req.Header.Set("Content-Type", "application/json")

      resp, err := http.DefaultClient.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      var data map[string]interface{}
      if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
          panic(err)
      }
      fmt.Println(data)
  }
  ```
</CodeGroup>

## How to join a community on Twitter through the API

Call `POST /x/communities/{id}/join` with one connected Twitter account and
numeric ID. X decides whether that account can join. The route cannot discover,
create, or moderate Communities. Approve each pair first.

## Understand open, restricted, and invited membership

Open Communities allow direct joins. Restricted Communities may require
approval or an invitation. X controls each membership mode.

Open the Community page and review its rules.
Use the join button for manual membership.
Find it at the top of the page.
Restricted Communities display Ask to join. A moderator decides that request.
No API field selects a mode or accepts an invitation.

Use the official [X Communities guide](https://help.x.com/en/using-x/communities)
for current interface behavior.

## Find Twitter communities before joining

Existing members can open the Community tab on X.com or iOS. Search by name,
description, creator, or handle.
X warns that some Communities never appear in search results.

Use a direct URL for an account's first Community. Ask an owner or moderator for
the exact link when search omits it. Confirm the specific Community name,
description, rules, moderators, membership mode, and recent posts. Never approve
membership from a similar display name. Match the numeric ID with
[Community Info](/api-reference/x/community-info).

[Community Search](/api-reference/x/community-search) searches posts inside one
known Community. It cannot find Community directories or topic-based groups.

## Compare manual and API community joining

For manual membership, sign in to X and open the Community URL. Review the
Community rules and membership mode. Select Join or Ask to join. Then wait for
any required moderator review.

For an API workflow, validate the connected Twitter account and numeric ID.
Capture approval before submission. Poll the returned action. Verify the
complete member roster after the action reaches a terminal state.

X handles invitations, rules, and moderator review for both paths. The API
cannot click controls, select a membership mode, or bypass moderator approval.

## Review account eligibility and moderator limits

Confirm that the X account remains public and connected. Check existing
membership and pending requests before submission. Reusing an existing action
prevents duplicate membership requests.

Admins and moderators enforce each Community's rules. They review restricted
requests. A block between the account and a moderator can stop membership. The
API cannot override that relationship.

X says an admin account must have a verified email address or phone number.
This verified-contact requirement applies only to admins.

Each Twitter Community covers one shared topic.
The contract defines no separate community account. Store the connected account
and Community ID as separate fields.

## Choose the correct X relationship

* Use Join Community for one approved membership.
* Use Follow for one account relationship.
* Use Create Tweet for an approved Community post.
* Use Community Members to verify the roster.
* Use Community Tweets to read the Community timeline.

Following, Lists, group messages, and Community Notes cannot change membership.

## Plan post-join reading and publishing

Joining adds one connected account to one Community. It does not
create posts, invitations, or moderator changes.

Read [Community Tweets](/api-reference/x/community-tweets) after confirmation.
Store Tweet IDs, replies, reposts, likes, media, and cursors. Use
[Community Search](/api-reference/x/community-search) for keyword matches inside
the reviewed Community ID.

Read recent conversations before drafting a reply or media post. Membership
never authorizes publishing.
Approve separate Create Tweet actions for members posting after joining.
Keep the reviewed rules with each approval. Avoid repetitive promotions and
unwanted invitations. Moderators can remove accounts that violate local rules.

## Resolve membership intent

Use a numeric Community ID. Record its connected account, membership mode, and
approval.

Keep enough evidence to explain every membership request.

| Approval evidence | Store | Purpose |
| - | - | - |
| Intended Community | Numeric ID, display name, and direct URL | Prevent membership in a similarly named Community |
| Connected account | Username, stable user ID, and connection status | Bind consent to one Twitter account |
| Membership review | Mode, rules, and moderator status | Explain an open, pending, or rejected request |
| API action | Idempotency key, action ID, status URL, and final status | Prevent duplicate writes and keep the state needed for recovery |

## Join a Twitter community step by step

1. Review the numeric Community ID and connected account.
2. Create one pair-specific `Idempotency-Key`.
3. Submit `POST /x/communities/{id}/join` once.
4. Poll the returned action to a terminal result.
5. Verify the account through Community Members.
6. Store the action, approval, membership mode, and result.

An HTTP `202` confirms processing, not membership. If a timeout occurs, keep
polling the existing action. A changed account or Community needs new approval.

Store the request hash, action ID, status URL, and final membership result. Keep
the same `Idempotency-Key` only when every input remains identical. A changed
account, Community ID, or approval requires a new key.

## Join communities in controlled batches

Assign one `Idempotency-Key` per approved pair. Process retries serially. Record
each result, action ID, and approval in one stored row. Pause only the
affected account after errors.

## Verify visible membership

After a terminal result, call
[Community Members](/api-reference/x/community-members). Follow every cursor.

Store the Community ID, action status, matched username, and stable user ID.
Never resubmit after checking only one page.
Anyone with the direct Community URL can see its member list.

## Explain community post visibility

Community posts are not private group messages. They can appear on Community
pages, profiles, timelines, and search. Review that visibility before
approving a post.

Anyone on X with the direct Community URL can see the Community's member list.
Joining never publishes a post. Use
[Create Tweet](/api-reference/x-write/create-tweet) after separate approval.

## Twitter community questions

### How to join a Twitter community with Xquik?

Review Community Info. Submit one connected account and numeric ID. Poll the
action, then verify Community Members.

### Can I join an invitation-only Twitter community?

For an invite-only Community, X still requires an invitation.
Confirm you are logged in to your account on X. This endpoint cannot accept
invitations. Save any `422` rejection.

### What happens when you join a Twitter community?

X adds the membership after approval.
Members can reply after X confirms membership.
They can connect, share posts, and follow the Community's rules.

### Can people see the communities you join on Twitter?

Direct Community URLs expose member lists. Posts can also appear publicly.

### How do I join a community on a phone?

Open a shared Community URL. Review its rules and membership mode. Use X for
manual membership or Xquik for server workflows.

### Do Twitter communities still exist?

Yes. X controls availability, search, membership modes, and moderation.

### Do I need X Premium to join a community?

The request has no Premium field. X decides account eligibility.

### Why can't I join a Twitter community?

Check the public account, numeric ID, connection, mode, and invitation. Check
whether the account and moderators block each other. Read `terminal`,
`retryable`, and `safeToRetry` before retrying.

### How do I find active Twitter communities by interest?

Search the Communities page by topic or creator after joining once. A first
membership needs a shared URL. Community Search cannot find Community directories.

### What are the benefits of joining a Twitter community?

Membership opens one topic-focused discussion space. Members can read its
timeline and participate under its rules. This endpoint cannot promise
followers, engagement, leads, or sales.

### How should a brand participate after joining?

Read recent Community posts first. Match the topic and follow moderator rules.
Approve each reply, post, and media upload separately. Avoid repetitive
promotions and unwanted invitations.

### Is community notes the same as X communities?

No. Community Notes adds context to posts. X Communities organize memberships
and discussions. Use X to join Community Notes.

### Can this API create, moderate, or grow a community?

No. Use [Create Community](/api-reference/x-write/create-community) for creation.
Join Community cannot moderate, invite, or grow members.

## Recover from join failures

Fix input after `400`. Replace credentials after `401`. Restore credits after
`402`. Reconnect the account after `403`. Check both IDs after `404`. Reuse the
same key only for identical input after `409`. Save `422` rejections. Honor
`Retry-After` after `429`. Inspect `safeToRetry` after `500` or `503`.

If a connection drops after submission, poll the existing action. Never create
a replacement action after a network error. Keep the original action
after `409`. Store X membership rejections after `422`. Wait for `Retry-After`
after `429`.

Store the action ID and final membership result.
Never infer posting permission from membership.

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key. OAuth bearer authentication is also supported. Generate a key from the [dashboard](https://xquik.com/dashboard).
</ParamField>

<ParamField header="Idempotency-Key" type="string" required>
  Unique key for this intended write. Reuse it only when every request field remains unchanged.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`.
</ParamField>

## Path parameters

<ParamField path="id" type="string" required>
  The ID of the community to join.
</ParamField>

## Body

<ParamField body="account" type="string" required>
  The connected X account to join the community with. Must be a username you have connected to your Xquik account.
</ParamField>

## Response

<Tabs>
  <Tab title="404 Account not found">
    Connect the requested account, then submit a newly approved write.
  </Tab>
</Tabs>

## Durable write recovery

<Warning>
  Send one unique `Idempotency-Key` per intended write.
  Replay the same account, target, payload, and media after a lost response.
  Keep the original key for that replay.
</Warning>

1. Store `id`, the nested `hash` in `request`, `billing`, and `statusUrl`.
2. Poll after `Retry-After` or `pollAfterMs` when `terminal` is `false`.
3. Retry only when `safeToRetry` is `true`.
4. Use a new key when `nextAction.requiresNewIdempotencyKey` is `true`.

### 200 terminal or 202 active

* After HTTP `200`, store the result and settled billing.
* After HTTP `202`, poll the same action. Never submit another write.
* After HTTP `400`, fix the named field. Use a new idempotency key.
* After HTTP `401`, fix authentication. Do not retry unchanged.
* After HTTP `402`, fund the account before another write.
* After HTTP `403`, reconnect the account.
* After HTTP `409`, keep the original action. Use a new key for new input.
* After HTTP `422`, fix the rejected request before retrying.
* After HTTP `429`, wait for `Retry-After`. Follow `nextAction`.

See [Get Write Action Status](/api-reference/x-write/get-write-action-status)
for every lifecycle field, terminal state, billing field, and retry rule.


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