MemorySync
API Reference

Slack Configuration

Choose which Slack channels a connection reads, filter what inside them counts, and map Slack users to your own end users so their messages become their memories.

Operations on this page

OperationMethod and pathPythonNode.js
List selectable channelsGET …/{connection_id}/slack/available-channelsconnections.slack.available_channelsconnections.slack.availableChannels
List selected channelsGET …/{connection_id}/slack/channelsconnections.slack.channelsconnections.slack.channels
Select channelsPOST …/{connection_id}/slack/channelsconnections.slack.add_channelsconnections.slack.addChannels
Deselect a channelDELETE …/{connection_id}/slack/channels/{channel_id}connections.slack.remove_channelconnections.slack.removeChannel
Read the exclusion policyGET …/{connection_id}/slack/exclusion-policyconnections.slack.exclusion_policyconnections.slack.exclusionPolicy
Replace the exclusion policyPUT …/{connection_id}/slack/exclusion-policyconnections.slack.set_exclusion_policyconnections.slack.setExclusionPolicy
List identity mappingsGET …/{connection_id}/slack/identitiesconnections.slack.identitiesconnections.slack.identities
Link an identityPOST …/{connection_id}/slack/identities/linkconnections.slack.link_identityconnections.slack.linkIdentity
Re-sync identitiesPOST …/{connection_id}/slack/identities/syncconnections.slack.sync_identitiesconnections.slack.syncIdentities

Authentication and scope

RequirementContract
CredentialAn API key sent as X-API-Key. Connector operations are not end-user scoped.
Read scopeintegrations:read for every GET.
Write scopeintegrations:write for every POST, PUT, PATCH and DELETE.
TenantDerived from the authenticated key. There is no tenant parameter to pass or to get wrong.
X-End-User-IDNot used. A connection belongs to the organization, not to one end user.

Before you start

You need a working Slack connection. Create one with the OAuth flow on Providers & OAuth — Slack cannot be connected with an API key. Everything on this page assumes connection["status"] == "connected".

1. See which channels are available

Reads the channels the installation can see, annotated for a picker, so a user chooses from reality rather than typing a channel name that may not exist or may not be visible to the bot. It takes no parameters and performs no ingestion.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
available = client.connections.slack.available_channels("conn_8f21a4")
print(available["total"])
for channel in available["channels"]:
print(channel["id"], channel["name"], channel["selectable"], channel["reason"])
GET/api/v2/integrations/connections/{connection_id}/slack/available-channels
200 OK
Field on each channelMeaning
id, nameThe Slack channel id and name.
channel_type, is_private, is_external_sharedWhat kind of channel it is.
is_member, is_archivedWhether the bot is in it, and whether Slack has archived it.
num_members, topic, purposeContext for a human choosing from a list. May be absent.
approvedAlready selected on this connection.
selectableWhether it can be approved at all. Check this before offering it.
reasonWhy it is not selectable, when it is not — an exclusion pattern, or a missing invite.

2. Select the channels to sync

Selecting a channel does not import it immediately. It marks it for the next sync, which you trigger on Sync & Jobs.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
client.connections.slack.add_channels("conn_8f21a4", ["C0123SUPPORT", "C0456PRODUCT"])
POST/api/v2/integrations/connections/{connection_id}/slack/channels
200 OK

3. Read back what is selected

This one returns a bare JSON array rather than an object with a channels key, so iterate the response itself.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
for channel in client.connections.slack.channels("conn_8f21a4"):
print(channel["channel_id"], channel["channel_name"], channel["state"], channel["is_active"])
GET/api/v2/integrations/connections/{connection_id}/slack/channels
200 OK
FieldMeaning
channel_id, channel_nameSlack's identifier and name. The name is nullable.
state, state_detailApproval state, and why it is in that state.
is_activeWhether future syncs will read it.
messages_syncedLifetime tally of messages read across all runs.
last_message_ts, last_synced_atPosition reached and when it was last read.
authorized_atWhen it was approved.

4. Block channels by name pattern

The exclusion policy is a list of channel-name patterns this connection will never sync. It is a standing rule rather than a per-channel decision: a pattern blocks matching channels that are selected now and any that appear later, which is what you want for whole families like incident-* or dm-*.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
client.connections.slack.set_exclusion_policy(
"conn_8f21a4",
patterns=["random", "incident-*", "*-alerts"],
)
policy = client.connections.slack.exclusion_policy("conn_8f21a4")
print(policy["tenant_patterns"], policy["effective_patterns"])
PUT/api/v2/integrations/connections/{connection_id}/slack/exclusion-policy
200 OK
GET/api/v2/integrations/connections/{connection_id}/slack/exclusion-policy
200 OK
Response fieldMeaning
deployment_patternsThe floor set by the deployment. Read-only here; PUT cannot remove one.
tenant_patternsThe patterns you sent. This is the only list PUT replaces.
effective_patternsBoth lists combined — what actually gets applied.
Pattern ruleBehaviour
SyntaxShell-style globbing: *, ? and [seq]. incident-* blocks incident-2026-01.
CaseBoth pattern and channel name are lowercased before matching, so HR-* and hr-* behave alike.
Leading #Stripped. #random and random are the same pattern.
LimitsUp to 200 patterns, each truncated to 128 characters. Duplicates are dropped.
Unnamed channelsA channel with no resolvable name is not blocked by a pattern.

5. Map Slack users to MemorySync users

This is the step that makes Slack memories useful. Without a mapping, a message is not attributed to a person, so querying as that person will not find it. A mapping joins a Slack member id to a numeric MemorySync user id.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
roster = client.connections.slack.identities("conn_8f21a4")
print(roster["total"], roster["matched"], roster["unmatched"])
client.connections.slack.link_identity(
"conn_8f21a4",
slack_user_id="U024BE7LH",
memorysync_user_id=4821,
)
GET/api/v2/integrations/connections/{connection_id}/slack/identities
200 OK
POST/api/v2/integrations/connections/{connection_id}/slack/identities/link
200 OK
FieldMeaning
slack_user_idRequired. The Slack member id, such as U024BE7LH.
memorysync_user_idThe numeric MemorySync user id to attribute messages to. Send null to unlink.

6. Refresh the roster

Pulls the workspace member list again so newly joined people appear as linkable. It does not create mappings — those stay deliberate.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
client.connections.slack.sync_identities("conn_8f21a4")
POST/api/v2/integrations/connections/{connection_id}/slack/identities/sync
200 OK

7. Drop a channel

Removes it from the selection so future syncs skip it. Objects and memories already imported are untouched.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
client.connections.slack.remove_channel("conn_8f21a4", "C0456PRODUCT")
DELETE/api/v2/integrations/connections/{connection_id}/slack/channels/{channel_id}
204 No Content

Errors and next action

StatusMeaningNext action
401Missing, malformed or inactive API key.Check server configuration without printing the key.
403The key lacks integrations:read or integrations:write.Grant the scope on the key, or use a key that has it.
404The connection, object or job is not visible to this tenant.Confirm the identifier belongs to this organization.
409The connection is in a state that forbids the operation.Read the connection status first and act on it.
429Rate limited, either by MemorySync or by the upstream provider.Back off; do not tighten a polling loop in response.
5xxService failure.Treat a write outcome as uncertain and reconcile by reading the connection back.