Slack
Access the Slack API with managed OAuth authentication. Send messages, manage channels, list users, and automate Slack workflows.
Quick Start
# Post a message to a channel
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'channel': 'C0123456789', 'text': 'Hello from Maton!'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/slack/api/chat.postMessage', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/slack/{method}
The gateway proxies requests to slack.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your Slack OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=slack&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'slack'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
json
{
"connection": {
"connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "slack",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Slack connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'channel': 'C0123456789', 'text': 'Hello!'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/slack/api/chat.postMessage', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
Post Message
POST /slack/api/chat.postMessage
Content-Type: application/json
{
"channel": "C0123456789",
"text": "Hello, world!"
}
With blocks:
POST /slack/api/chat.postMessage
Content-Type: application/json
{
"channel": "C0123456789",
"blocks": [
{"type": "section", "text": {"type": "mrkdwn", "text": "*Bold* and _italic_"}}
]
}
Post Thread Reply
POST /slack/api/chat.postMessage
Content-Type: application/json
{
"channel": "C0123456789",
"thread_ts": "1234567890.123456",
"text": "This is a reply in a thread"
}
Update Message
POST /slack/api/chat.update
Content-Type: application/json
{
"channel": "C0123456789",
"ts": "1234567890.123456",
"text": "Updated message"
}
Delete Message
POST /slack/api/chat.delete
Content-Type: application/json
{
"channel": "C0123456789",
"ts": "1234567890.123456"
}
List Channels
GET /slack/api/conversations.list?types=public_channel,private_channel
Get Channel Info
GET /slack/api/conversations.info?channel=C0123456789
Get Channel Members
GET /slack/api/conversations.members?channel=C0123456789&limit=100
List Messages in Channel
GET /slack/api/conversations.history?channel=C0123456789&limit=100
Get Thread Replies
GET /slack/api/conversations.replies?channel=C0123456789&ts=1234567890.123456
List Users
GET /slack/api/users.list
Get User Info
GET /slack/api/users.info?user=U0123456789
Search Messages
GET /slack/api/search.messages?query=keyword
Open DM Conversation
POST /slack/api/conversations.open
Content-Type: application/json
{
"users": "U0123456789"
}
Add Reaction
POST /slack/api/reactions.add
Content-Type: application/json
{
"channel": "C0123456789",
"name": "thumbsup",
"timestamp": "1234567890.123456"
}
Upload File
POST /slack/api/files.upload
Content-Type: multipart/form-data
channels=C0123456789
content=file content here
filename=example.txt
Auth Test
Get current user and team info:
GET /slack/api/auth.test
Code Examples
JavaScript
const response = await fetch('https://gateway.maton.ai/slack/api/chat.postMessage', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
},
body: JSON.stringify({ channel: 'C0123456', text: 'Hello!' })
});
Python
import os
import requests
response = requests.post(
'https://gateway.maton.ai/slack/api/chat.postMessage',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
json={'channel': 'C0123456', 'text': 'Hello!'}
)
Notes
- Channel IDs start with
C(public),G(private/group), orD(DM) - User IDs start with
U, Team IDs start withT - Message timestamps (
ts) are used as unique identifiers - Use
mrkdwntype for Slack-flavored markdown formatting - Thread replies use
thread_tsto reference the parent message - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets (fields[],sort[],records[]) to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing Slack connection |
| 401 | Invalid or missing Maton API key |
| 429 | Rate limited (10 req/sec per account) |
| 4xx/5xx | Passthrough error from Slack API |
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
slack. For example:
- Correct:
https://gateway.maton.ai/slack/api/chat.postMessage - Incorrect:
https://gateway.maton.ai/api/chat.postMessage