0
# Core API Methods
1
2
Essential WebClient methods for making API calls, handling pagination, and uploading files.
3
4
## Capabilities
5
6
### Generic API Call
7
8
Make calls to any Slack Web API method with automatic error handling and retry logic.
9
10
```typescript { .api }
11
/**
12
* Make a generic API call to any Slack Web API method
13
* @param method - The API method name (e.g., 'chat.postMessage')
14
* @param options - Parameters for the API call
15
* @returns Promise resolving to the API response
16
*/
17
apiCall(method: string, options?: Record<string, unknown>): Promise<WebAPICallResult>;
18
```
19
20
**Usage Examples:**
21
22
```typescript
23
import { WebClient } from "@slack/web-api";
24
25
const web = new WebClient(token);
26
27
// Direct API call
28
const result = await web.apiCall('chat.postMessage', {
29
channel: '#general',
30
text: 'Hello world!'
31
});
32
33
// Call with complex parameters
34
const result = await web.apiCall('conversations.create', {
35
name: 'new-channel',
36
is_private: false
37
});
38
39
// Override token per call
40
const result = await web.apiCall('auth.test', {
41
token: 'xoxp-different-token'
42
});
43
```
44
45
### Pagination Support
46
47
Automatically handle cursor-based pagination for methods that return large datasets.
48
49
```typescript { .api }
50
/**
51
* Paginate through all results of an API method
52
* @param method - The API method name that supports pagination
53
* @param options - Parameters for the API call
54
* @returns AsyncIterable for iterating through all pages
55
*/
56
paginate(
57
method: string,
58
options?: Record<string, unknown>
59
): AsyncIterable<WebAPICallResult>;
60
```
61
62
**Usage Examples:**
63
64
```typescript
65
import { WebClient } from "@slack/web-api";
66
67
const web = new WebClient(token);
68
69
// Iterate through all conversation members
70
const members = [];
71
for await (const page of web.paginate('conversations.members', {
72
channel: 'C1234567890',
73
limit: 100
74
})) {
75
members.push(...page.members);
76
}
77
78
// Get all channels
79
const channels = [];
80
for await (const page of web.paginate('conversations.list', {
81
types: 'public_channel,private_channel'
82
})) {
83
channels.push(...page.channels);
84
}
85
86
// Use with custom accumulator function
87
async function getAllUsers() {
88
const users = [];
89
for await (const page of web.paginate('users.list')) {
90
users.push(...page.members);
91
92
// Optional: break early based on condition
93
if (users.length > 1000) break;
94
}
95
return users;
96
}
97
```
98
99
### Advanced Pagination with Custom Logic
100
101
Use pagination with custom page reduction and stopping criteria.
102
103
```typescript { .api }
104
/**
105
* Custom page reducer function for accumulating results
106
* @param accumulator - Current accumulated value
107
* @param page - Current page result
108
* @returns Updated accumulator value
109
*/
110
type PageReducer<A = any> = (
111
accumulator: A | undefined,
112
page: WebAPICallResult
113
) => A;
114
115
/**
116
* Predicate function to determine when to stop pagination
117
* @param page - Current page result
118
* @returns True to continue, false to stop
119
*/
120
type PaginatePredicate = (page: WebAPICallResult) => boolean;
121
```
122
123
**Usage Examples:**
124
125
```typescript
126
// Custom accumulator pattern
127
const userCount = await web.paginate('users.list')
128
.reduce((count = 0, page) => count + page.members.length, 0);
129
130
// Stop pagination based on condition
131
for await (const page of web.paginate('conversations.history', {
132
channel: 'C1234567890'
133
})) {
134
const oldestMessage = page.messages[page.messages.length - 1];
135
136
// Stop if we've reached messages older than 30 days
137
if (Date.now() - (oldestMessage.ts * 1000) > 30 * 24 * 60 * 60 * 1000) {
138
break;
139
}
140
141
// Process messages...
142
}
143
```
144
145
### File Upload V2
146
147
Modern file upload implementation using Slack's external upload flow.
148
149
```typescript { .api }
150
/**
151
* Upload files using the v2 external upload method
152
* @param options - File upload configuration
153
* @returns Promise resolving to upload results
154
*/
155
filesUploadV2(options: FilesUploadV2Arguments): Promise<WebAPICallResult & {
156
files: FilesCompleteUploadExternalResponse[];
157
}>;
158
159
interface FilesUploadV2Arguments {
160
/** Channels or conversations where the file will be shared */
161
channel_id?: string;
162
/** Alternative to channel_id - channel names */
163
channels?: string;
164
/** Title of the file */
165
title?: string;
166
/** File content as Buffer, Stream, or string */
167
file?: Buffer | NodeJS.ReadableStream | string;
168
/** Filename if file content is provided */
169
filename?: string;
170
/** File type/extension */
171
filetype?: string;
172
/** Alternative file content (deprecated) */
173
content?: string;
174
/** Initial comment about the file */
175
initial_comment?: string;
176
/** Thread timestamp to upload file to a thread */
177
thread_ts?: string;
178
/** Alt text for screen readers */
179
alt_text?: string;
180
/** Snippet type for text files */
181
snippet_type?: string;
182
}
183
```
184
185
**Usage Examples:**
186
187
```typescript
188
import { WebClient } from "@slack/web-api";
189
import { createReadStream } from "fs";
190
191
const web = new WebClient(token);
192
193
// Upload file from filesystem
194
const result = await web.filesUploadV2({
195
channels: '#general',
196
file: createReadStream('./report.pdf'),
197
filename: 'monthly-report.pdf',
198
title: 'Monthly Report',
199
initial_comment: 'Here is this month\'s report'
200
});
201
202
// Upload text content as file
203
await web.filesUploadV2({
204
channels: 'D1234567890', // DM channel
205
content: 'console.log("Hello, world!");',
206
filename: 'hello.js',
207
filetype: 'javascript',
208
title: 'Hello World Script'
209
});
210
211
// Upload to specific thread
212
await web.filesUploadV2({
213
channel_id: 'C1234567890',
214
file: Buffer.from('Log data here...'),
215
filename: 'debug.log',
216
thread_ts: '1234567890.123456',
217
alt_text: 'Debug log file'
218
});
219
```
220
221
### Response Handling
222
223
All API methods return a standardized response format with consistent error handling.
224
225
```typescript { .api }
226
interface WebAPICallResult {
227
/** Indicates if the API call was successful */
228
ok: boolean;
229
/** Error message if the call failed */
230
error?: string;
231
/** Additional response metadata */
232
response_metadata?: {
233
/** Warning messages from Slack */
234
warnings?: string[];
235
/** Cursor for pagination */
236
next_cursor?: string;
237
/** OAuth scopes associated with the token */
238
scopes?: string[];
239
/** Messages array for bulk operations */
240
messages?: string[];
241
};
242
/** Method-specific response data */
243
[key: string]: any;
244
}
245
```
246
247
**Usage Examples:**
248
249
```typescript
250
const result = await web.chat.postMessage({
251
channel: '#general',
252
text: 'Hello!'
253
});
254
255
if (result.ok) {
256
console.log('Message posted:', result.ts); // Message timestamp
257
console.log('Channel:', result.channel); // Channel ID
258
259
// Check for warnings
260
if (result.response_metadata?.warnings) {
261
console.warn('Warnings:', result.response_metadata.warnings);
262
}
263
} else {
264
console.error('Error:', result.error);
265
}
266
267
// Handle pagination cursors
268
const listResult = await web.conversations.list({ limit: 100 });
269
if (listResult.response_metadata?.next_cursor) {
270
// More results available
271
const nextPage = await web.conversations.list({
272
limit: 100,
273
cursor: listResult.response_metadata.next_cursor
274
});
275
}
276
```
277
278
## Types
279
280
```typescript { .api }
281
interface FilesCompleteUploadExternalResponse {
282
id: string;
283
title: string;
284
name: string;
285
mimetype: string;
286
filetype: string;
287
pretty_type: string;
288
user: string;
289
created: number;
290
size: number;
291
permalink: string;
292
permalink_public?: string;
293
}
294
```