Skip to content

Latest commit

 

History

History
1575 lines (1087 loc) · 63.3 KB

File metadata and controls

1575 lines (1087 loc) · 63.3 KB

Community

Community header image

The community class lets you work with a Status Community and its channels. A Community is always bound to a logged-in Account, and each of its channels is exposed as a Channel.

  • Community - manages membership (members, join requests, bans), the community's channels and reports its minted tokens.
  • Channel - manages a single channel - its identity (name, description, emoji, colour) and messaging.

You never construct a Channel directly. Instead you create one or fetch an existing one by name with subscript access.

Membership

As of now Community works with already created Status App communities. To get started, please read Create your community. A Community can be created two ways:

  • By id - wrap a community the account is already a member of, using its community_id.
  • By invite URL - pass a shared community url.

If the account is already a member, the community is ready to use. Otherwise a join request is sent and the instance is left unusable until an administrator accepts it (see Joining a community).

Only members can read a community's state, and only privileged members (owner / admin / token master) can ban, accept or manage channels.

The account's own standing in the community is reported by is_member, has_joined, joined_timestamp and requested_timestamp.

Roles

Every member carries one or more roles, returned by get_members. The raw dict form exposes the backend's numeric codes, while the DataFrame form resolves them to the names below.

Code Name Description
0 none A regular member. Can read and post, but cannot manage the community.
1 owner The community's owner. Full control over members, channels and settings.
4 admin Can manage members (ban, kick, accept, decline) and channels.
5 token_master Manages the community's tokens and token-gated permissions.

Note: the backend omits the roles key entirely for regular members - 0 / none is the fallback applied by the SDK, so it shows up in the DataFrame but never in the raw payload. Only the codes above are recognised; a member carrying any other code cannot be resolved by get_members(dataframe=True).

Control node

The community's control node maintains your community's settings, configuration and functionality. If the control node goes offline, your community functionality is affected.

This matters for a bot, because a community created in Status App has its control node on the desktop application that created it, not on status-im/status-go. The control node is the only computer that manages community members. You can use another computer or delegate tasks, but all actions go through the control node. If it's offline, new members can't be accepted, and join requests stay Pending until it comes back online.

The account behind the bot can hold the owner role and still not be the device that owns the key.

upload_control_node closes that gap - it replaces the account data Status Backend runs on with the data folder of the Status App installation that created the community, so the bot runs as that same installation.

Community(account, community_id=None, url=None, data_folder=None)

Create a Community instance bound to a logged-in Account. Provide either community_id or url.

Name Type Required Description
account Account Yes A logged-in Account. If the account is not logged in, a custom exception is raised.
community_id str No* The id of a community the account is already a member of. Community ids can be obtained from communities on Account.
url str No* A shared community invite URL. Used to join the community if the account is not already a member. See Joining a community.
data_folder str No The folder on your machine that launch_docker_container mounts into Status Backend. That is the only place the account data written by Status Backend lives, so a different folder cannot be reached. The path is resolved to its data subfolder, so "status-backend-data" and "status-backend-data/data" are equivalent. This property is only needed when the same account is logged into Status App, created a community there, and you want status-im/status-go (Status Backend) to take over as its control node - it is where upload_control_node writes the uploaded account data. Leave it unset for every other use.

Wrap a community the account is already in:

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

# Community ids come from the account's communities
community_id = account.communities[0]["id"]
community = Community(account, community_id)

print(community.id)

URL initialization:

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

# Community ids come from the account's communities
url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.id)

When either url or community_id is provided, the constructor acts based on the account's membership current status:

  • Already a member - the community is ready to use immediately.
  • Not a member - a join request is sent on your behalf (revealing the account's wallet address), and the instance is left unusable until an administrator accepts it.
  • Request pending - a warning is logged and the instance is left unusable until the request is accepted.

Note: While a request is pending or has just been sent, the community's id is unset and accessing it raises a custom exception. Re-create the Community by id once the request has been accepted.

Methods

get_members(dataframe=False)

The current members of the community, returned in one of two shapes.

By default a raw dict is returned as it comes back from the backend, keyed by public key. This costs a single call, so it is the shape to reach for in membership checks, lookups and bots where speed matters. Passing dataframe=True instead returns an enriched pd.DataFrame that resolves each member's contact details and profile URL - that costs two additional calls per member. It can be used for reporting and data pipelines rather than instant checks.

Name Type Required Description
dataframe bool No When False (the default), a raw dict keyed by public key is returned. When True, an enriched pd.DataFrame is returned.

Raw dict - dataframe=False

Returns dict[str, dict], keyed by the member's public key. An empty dict is returned when there are no members. Each value is the backend's member payload:

Key Type Description
compressedKey str The member's compressed chat key as shown in Status App.
emojiHash list[str] The member's emoji identicon - a list of individual emojis, not a single string. Entries can be multi-codepoint (skin tones, ZWJ sequences), e.g. 🧑🏾‍✈️.
alias str The member's initial (generated) name, e.g. Carefree Joyful Bushviper.
colorId int The id of the colour Status App assigns to the member's identicon.
last_update_clock int The logical clock of the member's last update.
roles list[int] The member's role codes - 1 owner, 4 admin, 5 token master. Absent for regular members, so read it with member.get("roles", [0]).

Note: this is the unmodified backend payload, so its keys are inconsistently cased (compressedKey next to last_update_clock), keys can be missing per member, and further keys may be present. The DataFrame form is the stable, documented shape.

pd.DataFrame - dataframe=True

Returns pd.DataFrame, one row per member. An empty DataFrame is returned when there are no members.

Column Type Description
public_key str Public key that uniquely identifies the member.
chat_id str Chat identifier used for direct messaging.
compressed_key str The member's compressed chat key as shown in Status App.
emojis list[str] The member's emoji identicon, passed through from emojiHash as a list of individual emojis.
display_name str The member's display name. Members without one are shown as a short key + Status URL fragment.
alias str The member's initial (generated) name.
roles list[str] The member's roles, resolved to their names.
bio str The member's profile bio.
url str Shareable Status profile URL for the member.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

# Raw dict - one call, keyed by public key
for public_key, member in community.get_members().items():
    print(public_key, member["alias"])

# DataFrame - enriched, for data pipelines
members = community.get_members(dataframe=True)
print(members[["display_name", "roles"]].to_markdown(index=False))

Community Members

get_collectibles()

The community's minted tokens and who is holding them - one row per holder, per token, per chain.

A community can mint its own tokens, which are then used for token gating and rewards. This method takes every token the community has minted, looks up the holders of each of its contracts, and returns them as a pd.DataFrame. Tokens minted on more than one chain are looked up on each chain separately, so the same symbol can appear under several chain_id values.

Returns pd.DataFrame, one row per owner per contract. Rows are sorted by symbol, name, chain_id, contract_address and owner.

Column Type Description
symbol str The token's symbol, as minted by the community.
name str The token's name.
chain_id int Chain ID the contract is deployed on. Matches values from chains.
contract_address str Address of the token contract on that chain.
owner str Wallet address holding the token.
balance int Number of tokens that wallet holds.
is_owner bool True when owner is the logged-in account's own wallet_address, from info.

This costs one call per contract, on top of the community fetch - so it is a reporting method rather than something to poll. Contracts the wallet service returns no holders for contribute no rows.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

collectibles = community.get_collectibles()
print(collectibles.to_markdown(index=False))

What the account itself is holding:

collectibles = community.get_collectibles()

mine = collectibles.loc[collectibles["is_owner"]]
for row in mine.itertuples():
    print(f"{row.symbol}\t{row.balance}")

The biggest holders of a token, and how much of it is out there:

collectibles = community.get_collectibles()

snt_pump = collectibles.loc[collectibles["symbol"] == "PUMP"]
print(f"{snt_pump['balance'].sum()} held across {len(snt_pump)} wallets")
print(snt_pump.nlargest(5, "balance")[["owner", "balance"]].to_markdown(index=False))

Note: the returned holders are wallet addresses, not the public keys used everywhere else in this class. They cannot be passed to kick, ban or get_public_key, and a holder does not have to be a member of the community.

Note: a community that has not minted any tokens does not return an empty DataFrame - there are no columns to group by, so pandas raises a ValueError. Wrap the call in a try / except ValueError when the community is not known to have tokens.

upload_control_node(folder)

Hand Status Backend the account data of an existing Status App installation, so the bot runs as that installation and becomes the community's control node.

This is destructive. Everything inside the data_folder given to the Community constructor is deleted and replaced with the contents of folder. Point folder at a copy of the account data, never at the only one you have.

Name Type Required Description
folder str Yes The account data folder to upload - data when it comes from Status App, or data when it comes from a status-im/status-go container.
from status_sdk import Account, Community, launch_docker_container

# The container and the Community must be pointed at the same folder
data_folder = "status-backend-data"
launch_docker_container(data_folder=data_folder)

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP",
    # The account that created the community in Status App
    "mnemonic": "lens crater peanut ..."
}
account.login(**params)

community_id = account.communities[0]["id"]
community = Community(account, community_id, data_folder=data_folder)

# A copy of the Status App `data` folder for that same account
community.upload_control_node("status-app-copy/data")
print(f"{community.name} is now controlled by this backend")

Note: Status App does not show where it keeps its account data. Open the logs folder it writes to and go one directory up - data sits next to it:

Status App data folder

That data folder is the one to pass as folder.

ban(public_keys, delete_messages=False)

Ban one or more members from the community. Banned members appear in banned_members property. A custom exception is raised if none of the provided public keys belong to the community.

Each member can be identified in three different ways, so you can pass whichever value you have at hand - the public key, the chat key as shown in Status App, or the profile link a user shares with you:

Format Example Where to find it
Public key 0x04ebcad... The keys of get_members(), or public_key in its DataFrame form
Chat key (compressed key) zQ3shYSHp7... compressedKey in get_members(), or the chat key in Status App
Account URL https://status.app/u/... url in get_members(dataframe=True), or Share profile in Status App

Every value is normalised into the public key with get_public_key before it is matched against the community's members, so the formats can be mixed within the same list.

Name Type Required Description
public_keys list[str]
str
Yes The public keys (0x...), chat keys (zQ...) or account URLs (https://...) of the members to ban. A single value can be passed as a str. Current members can be obtained from get_members.
delete_messages bool No When True, all messages sent by the banned members are also deleted. Defaults to False.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

member = next(iter(community.get_members()))
community.ban(member, delete_messages=True)

Community Settings


Ban member

unban(public_keys)

Unban one or more previously banned members.

Each member can be identified by their public key, chat key or account URL, and the formats can be mixed within the same list.

Name Type Required Description
public_keys list[str]
str
Yes The public keys (0x...), chat keys (zQ...) or account URLs (https://...) of the members to unban. A single value can be passed as a str. Banned members can be obtained from banned_members properties.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

community.unban(community.banned_members)

Community Settings


Unban member

kick(public_keys)

Remove one or more members from the community. Unlike ban, a kicked member is not added to banned_members and can request to join again. A custom exception is raised if none of the provided public keys belong to the community.

Each member can be identified by their public key, chat key or account URL, and the formats can be mixed within the same list.

Name Type Required Description
public_keys list[str]
str
Yes The public keys (0x...), chat keys (zQ...) or account URLs (https://...) of the members to remove. A single value can be passed as a str. Current members can be obtained from get_members.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

member = next(iter(community.get_members()))
community.kick(member)

Community Settings


Kick member

accept(pending_request_id)

Accept a pending join request. Members waiting to be accepted are found in pending_members. A custom exception is raised if pending_request_id is not a pending (or declined) join request.

Name Type Required Description
pending_request_id str Yes The request_id of a member from pending_members.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

for member in community.pending_members:
    community.accept(member["request_id"])

Community Settings


Community Request - Pending

decline(pending_request_id)

Decline a pending join request. Declined members appear in declined_members.

Name Type Required Description
pending_request_id str Yes The request_id of a member from pending_members.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

member = community.pending_members[0]
community.decline(member["request_id"])

Community Settings


Community Request - Pending

leave()

Leave the community. After leaving, the Community instance can no longer be used - its id is unset and accessing it raises a custom exception. Re-create the Community (by id or url) if you rejoin.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

community.leave()

create_channel(name, description, emoji=None, colour=None, category_name=None)

Create a new channel in the community. Returns the created Channel. An unknown category_name is ignored and the channel is created without a category. Channel creation raises a custom exception if the backend rejects it, and a separate one when a channel with that name already exists in the community - so a duplicate can be caught on its own and the existing channel fetched instead.

Name Type Required Description
name str Yes The channel name. Must follow the channel name rules.
description str Yes The channel description. Must follow the channel description rules.
emoji str No A single emoji for the channel. When omitted, a random default emoji is chosen. See channel emoji.
colour str No The channel colour as a hex code, e.g. #4360DF. When omitted, a random default colour is chosen. See channel colour.
category_name str No The name of an existing category (from categories) to place the channel under. When omitted, the channel is uncategorised.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community.create_channel(
    name="announcements",
    description="Community news and updates",
    emoji="📢",
    colour="#4360DF"
)
print(channel.id)

Create Channel 1


Create Channel 2

delete_channel(channel_name)

Delete a channel by its name. Available channel names can be found in channels property. A custom exception is raised if no channel with that name exists.

Name Type Required Description
channel_name str Yes The name of the channel to delete.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

community.delete_channel("announcements")

Create Channel 2

listen_requests()

Listen for join requests to the community in real time.

Returns a Generator that yields one dict per request event:

Key Type Description
request_id str The join request id. Pass this to accept or decline.
state str The state the request moved into - see the table below.
public_key str Public key of the requesting member.

Request states

Code State Description
1 pending The request is waiting to be accepted or declined.
2 reject The request was declined.
3 accept The request was accepted and the member joined.
4 cancel The request was cancelled.

Events belonging to other communities, and requests whose state is not one of the four above, are skipped - so everything yielded is a request for this community.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

# Auto-accept everyone who asks to join
for request in community.listen_requests():
    print(f"{request['public_key']}\t{request['state']}")

    if request["state"] != "pending":
        continue

    community.accept(request["request_id"])
    community["general"].send_message("Welcome to the community!")

Community Request - Pending

Fetching a channel

A Channel is retrieved by name with subscript access on the community. Available names come from channels property.

Name Type Required Description
channel_name str Yes The name of the channel to fetch.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
channel.send_message("Hello from my Status bot!")

Note: A custom exception is raised if no channel with that name exists.

Counting members

The total number of members in the community is obtained by passing the community to the built-in len().

Returns int. This is the same count as the number of entries returned by get_members, without building the dict or the DataFrame.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(f"The community has {len(community)} members")

Properties

id

The unique identifier of the community.

Returns str. Raises a custom exception if the community is not usable (for example while a join request is pending).

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.id)

url

The shareable invite URL of the community. This is the same URL that can be passed to the Community constructor to join or wrap the community.

Returns str, or None if the backend does not return one.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.url)

name

The community's name.

Returns str.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.name)

Community Name

description

The community's description.

Returns str.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.description)

Community Name

introduction

The community's introduction message - the text shown to new members when they join.

Returns str.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.introduction)

Community Intro Message

leave_message

The community's leave message - the text shown to members when they leave the community.

Returns str.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.leave_message)

Community Leave Message

tags

The community's tags - the topics it is listed under in Status App, picked when the community is created.

Returns list[str], e.g. ["Crypto", "Technology"]. An empty list is returned when the community has no tags.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.tags)

is_encrypted

Whether the community's messages are encrypted. This is a community-wide setting chosen at creation - it cannot be turned on for a single Channel.

Returns bool. This is the same value as encrypted in communities on Account.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.is_encrypted)

is_member

Whether the logged-in account is a member of the community - that is, whether it appears in the community's member list.

Returns bool. This is the same value as is_member in communities on Account.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

if not community.is_member:
    print("The account is not a member of this community")

has_joined

Whether the account has joined the community. Where is_member reflects the account's presence in the community's member list, this is the join flag held on the account's side - it is set when the account joins and cleared when it leaves.

Returns bool.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.has_joined)

Note: this is not the same as the joined key of communities on Account, which currently mirrors verified.

joined_timestamp

When the account joined the community.

Returns datetime.datetime, or None when the account has not joined.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

joined = community.joined_timestamp
print(f"Joined on {joined:%Y-%m-%d}" if joined else "Not joined yet")

requested_timestamp

When the account's request to join the community was sent - the request created by the Community constructor when the account is not yet a member.

Returns datetime.datetime, or None when no join request was ever sent - for example when the account created the community itself.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.requested_timestamp)

Note: while a join request is still pending, the community's id is unset and every property - this one included - raises a custom exception. The timestamp becomes readable once the request has been accepted and the Community is re-created by id.

categories

The community's categories, keyed by category name.

Returns dict[str, dict] where each key is a category name and the value contains:

Key Type Description
id str The category id.
position int The category's position (ordering) in the community.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

for name, info in community.categories.items():
    print(name, info["id"], info["position"])

channels

High level information for every channel in the community.

Returns list[dict], one entry per channel.

Key Type Description
id str The channel id (within the community).
name str The channel name. Use this with subscript access and delete_channel.
category str
None
The id of the category the channel belongs to, or None if uncategorised.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

for channel in community.channels:
    print(channel["name"], channel["category"])

Community Channels

banned_members

The public keys of members currently banned from the community.

Returns list[str].

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.banned_members)

Banned Community Members

pending_members

Members whose join request is waiting to be accepted or declined.

Returns list[dict], each entry containing:

Key Type Description
public_key str Public key of the requesting member.
request_id str The join request id. Pass this to accept or decline.
from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

for member in community.pending_members:
    print(member["public_key"], member["request_id"])

Pending Community Members

declined_members

Members whose join request has been declined.

Returns list[dict] in the same shape as pending_members.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

print(community.declined_members)

Declined Community Members

Channel

A Channel represents a single channel inside a Community. You never construct it directly. Channels can be created with Community create_channel or by subscript access.

Channel name

The channel name identifies the channel. It is set when creating a channel and can be updated through the name property. Channel names must follow the validation rules enforced by the library and expected by the Status application. A valid channel name must satisfy all of the following conditions:

  • It may contain letters (A–Z, a–z)
  • It may contain numbers (0–9)
  • It may contain underscores (_)
  • It may contain periods (.)
  • It may contain hyphens (-)
  • Whitespaces are replaced with hyphens (-)
  • It must be at least 1 character long
  • It cannot be more than 24 characters long

Characters such as punctuation, emojis, or other symbols are not allowed.

Valid examples

announcements
general-chat
dev.team-42
SNT_PUMP
9000

Invalid examples

Example Reason
Too short (minimum length is 1)
a-channel-name-longer-than-24-chars Too long (maximum length is 24)
bot!123 Contains invalid character !
chan 🚀 Contains an emoji

Note: Whitespaces are automatically replaced with hyphens, so my cool channel becomes my-cool-channel.

Channel description

The channel description is the short text shown under the channel. It is set when creating a channel and can be updated through the description property.

A valid channel description must satisfy all of the following conditions:

  • It may contain letters (A–Z, a–z)
  • It may contain numbers (0–9)
  • It may contain underscores (_)
  • It may contain periods (.)
  • It may contain hyphens (-)
  • It may contain whitespaces ( )
  • It must be at least 1 character long
  • It cannot be more than 140 characters long

Characters such as punctuation, emojis, or other symbols are not allowed.

Valid examples

Community news and updates
General discussion
dev.team-42 planning

Invalid examples

Example Reason
Too short (minimum length is 1)
A description longer than one hundred and forty characters... + more Too long (maximum length is 140)
see the #general channel! Contains invalid character !
updates 🚀 Contains an emoji

Channel colour

The channel colour is the accent colour of the channel. It can be set when creating a channel and updated through the colour property. When omitted at creation, a random default colour is chosen.

A valid channel colour must be a hex colour code satisfying all of the following:

  • It must start with a #
  • It must be followed by 3 (#RGB) or 6 (#RRGGBB) hex digits
  • Hex digits are case-insensitive (0–9, a–f, A–F)

Valid examples

#4360DF
#FF7D46
#7140fd
#fff

Invalid examples

Example Reason
4360DF Missing the leading #
#12 Wrong number of digits (needs 3 or 6)
#GGGGGG Contains non-hex characters
blue Not a hex colour code

If a channel colour does not follow these rules, a custom exception will be raised.

Channel emoji

The channel emoji is the icon shown next to the channel. It can be set when creating a channel and updated through the emoji property. When omitted at creation, a random default emoji is chosen.

A valid channel emoji must satisfy all of the following:

  • It must be a single emoji
  • Skin tones, flags and Zero-Width Joiner (ZWJ) sequences are not supported

Valid examples

📢
🚀
❤️
⭐

Invalid examples

Example Reason
AB Not an emoji
🎉🎉 More than one emoji
👍🏽 Uses a skin-tone modifier
🇬🇧 Flag (multi-codepoint)
👨‍👩‍👧 ZWJ sequence

Methods

send_message(message, reply_to_message_id=None)

Send a text message to the channel. Supports text messages only, optionally as a reply.

Name Type Required Description
message str Yes The text message to send.
reply_to_message_id str No The id of the message being replied to, from get_messages. When omitted, the message is sent standalone.

Returns str - the id of the message that was just sent, delegated from send_message on Account. It is the same identifier that appears under the id key in get_messages, so it can be passed straight into delete_message or used as the reply_to_message_id of a follow-up message, without having to fetch the channel's messages first.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
message_id = channel.send_message("Hello from my Status bot!")
print(f"Sent message: {message_id}")

send_image(file_path, message=None, reply_to_message_id=None)

Send an image to the channel, with an optional text caption. The image renders inline in Status App, the same as attaching an image in the app. Like send_message, it can be sent as a reply to an existing message in the channel.

Name Type Required Description
file_path str Yes Local full path to the image file.
message str No Caption sent together with the image.
reply_to_message_id str No The id of the message being replied to. Message IDs can be obtained from the id key of get_messages. When omitted (default), the image is sent as a standalone message.

Returns str - the id of the message that was just sent, delegated from send_image on Account. It is the same identifier that appears under the id key in get_messages, so it can be passed straight into delete_message or used as the reply_to_message_id of a follow-up message.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
message_id = channel.send_image("./meme-67.png", "Daily random meme")
print(f"Sent image: {message_id}")

get_messages(start_timestamp=None, end_timestamp=None)

Retrieve messages from the channel within an optional time range. Messages are returned in descending order (newest to oldest).

Name Type Required Description
start_timestamp datetime.datetime No The earliest timestamp to include. Messages older than this stop the fetch.
end_timestamp datetime.datetime No The latest timestamp to include. Messages newer than this are skipped.

Returns list[dict] of message objects. This delegates to get_messages on Account.

from status_sdk import Account, Community
import datetime

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]

messages = channel.get_messages(start_timestamp=datetime.datetime(2024, 1, 1))
for message in messages:
    print(f"{message['timestamp']}\t{message['text']}")

delete_message(id)

Delete a message from the channel. You can delete your own messages, and if you are an administrator you can delete other members' messages too.

Name Type Required Description
id str Yes The id of the message to delete, from get_messages or directly from the return value of send_message.

Returns bool - True if the message was deleted, False if the account did not have permission.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]

messages = channel.get_messages()
deleted = channel.delete_message(messages[0]["id"])
print(f"Deleted: {deleted}")

Properties

id

The channel's unique identifier - the community id combined with the channel id. This is the value used with send_message and get_messages on Account.

Returns str.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
print(channel.id)

url

The shareable URL of the channel. Where the community URL points at the community as a whole, this one opens this channel in Status App.

Returns str, or None if the backend does not return one.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
channel.send_message(f"Talk about it here: {channel.url}")

name

Get or update the channel's name. The name must follow the channel name validation.

Returns str when reading.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]

# Read
print(channel.name)

# Update
channel.name = "general-chat"

Community Edit Name

description

Get or update the channel's description. The description must follow the channel description validation.

Returns str when reading.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]

channel.description = "General discussion"
print(channel.description)

Community Edit Name

colour

Get or update the channel's colour. The colour must follow the channel colour validation.

Returns str when reading.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]

channel.colour = "#7140FD"
print(channel.colour)

Community Edit Colour

emoji

Get or update the channel's emoji. The emoji must follow the channel emoji validation.

Returns str when reading, or None if the channel has no emoji.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]

channel.emoji = "🚀"
print(channel.emoji)

Community Edit Emoji

Permissions

Four properties describe what the logged-in account may do in the channel - can_post, can_view, can_react and is_token_gated. They are the per-channel counterpart of the permissions keys exposed by communities on Account, and every one of them returns a bool.

Property permissions key Description
can_post posting The account can send messages to the channel.
can_view viewing The account can read the channel.
can_react reactions The account can post emoji reactions.
is_token_gated token_gated Access to the channel is gated behind a token.

can_post

Whether the logged-in account is allowed to post in the channel.

Returns bool.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
if channel.can_post:
    channel.send_message("Hello!")

can_view

Whether the logged-in account is allowed to read the channel. When this is False, get_messages has nothing to return.

Returns bool.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

# Only read the channels the account is allowed to see
for info in community.channels:
    channel = community[info["name"]]
    if not channel.can_view:
        continue

    print(info["name"], len(channel.get_messages()))

can_react

Whether the logged-in account is allowed to post emoji reactions in the channel.

Returns bool.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
print(channel.can_react)

Note: this reports the permission as Status App does. Sending reactions is not supported by the SDK - channels are written to with send_message. Channels created through the SDK allow their viewers to post reactions.

is_token_gated

Whether access to the channel is gated behind a token. Members who do not hold the required token are refused access, which shows up as can_view and can_post being False.

Returns bool.

from status_sdk import Account, Community

account = Account()
params = {
    "name": "status-app-bot",
    "password": "SNTPUMP"
}
account.login(**params)

url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
community = Community(account, url=url)

channel = community["general"]
if channel.is_token_gated and not channel.can_post:
    print("The account does not hold the token this channel requires")

Note: token gating is configured in Status App. The SDK reports it, and always creates channels that are open to every member.