0
# OAuth Authentication
1
2
Complete OAuth flow implementation for Notion app integrations including token exchange and management.
3
4
## Capabilities
5
6
### Exchange Authorization Code for Access Token
7
8
Exchange an authorization code for an access token during the OAuth flow.
9
10
```typescript { .api }
11
/**
12
* Exchange authorization code for access token
13
* @param args - OAuth token exchange parameters
14
* @returns Promise resolving to token response
15
*/
16
oauth.token(args: OauthTokenParameters): Promise<OauthTokenResponse>;
17
18
interface OauthTokenParameters {
19
/** OAuth grant type */
20
grant_type: "authorization_code";
21
/** Authorization code from callback */
22
code: string;
23
/** Redirect URI used in authorization */
24
redirect_uri?: string;
25
}
26
27
interface OauthTokenResponse {
28
/** Access token for API requests */
29
access_token: string;
30
/** Token type (always "bearer") */
31
token_type: "bearer";
32
/** Bot user ID associated with the integration */
33
bot_id: string;
34
/** Workspace information */
35
workspace_name?: string;
36
workspace_id?: string;
37
workspace_icon?: string;
38
/** Owner information */
39
owner: {
40
type: "workspace" | "user";
41
user?: {
42
object: "user";
43
id: string;
44
name?: string;
45
avatar_url?: string;
46
type: "person";
47
person?: {
48
email?: string;
49
};
50
};
51
};
52
/** Duplicate properties for legacy compatibility */
53
duplicated_template_id?: string;
54
request_id: string;
55
}
56
```
57
58
**Usage Examples:**
59
60
```typescript
61
// Exchange authorization code for access token
62
const tokenResponse = await notion.oauth.token({
63
grant_type: "authorization_code",
64
code: "authorization-code-from-callback",
65
redirect_uri: "https://yourapp.com/oauth/callback",
66
});
67
68
console.log(tokenResponse.access_token); // Use this for API requests
69
console.log(tokenResponse.workspace_name); // Workspace name
70
console.log(tokenResponse.bot_id); // Bot user ID
71
72
// Create new client with access token
73
const authorizedNotion = new Client({
74
auth: tokenResponse.access_token,
75
});
76
```
77
78
### Revoke Access Token
79
80
Revoke an access token, ending the authorization for the integration.
81
82
```typescript { .api }
83
/**
84
* Revoke an access token
85
* @param args - OAuth token revocation parameters
86
* @returns Promise resolving to revocation response
87
*/
88
oauth.revoke(args: OauthRevokeParameters): Promise<OauthRevokeResponse>;
89
90
interface OauthRevokeParameters {
91
/** Access token to revoke */
92
token: string;
93
}
94
95
interface OauthRevokeResponse {
96
/** Always returns empty object on success */
97
}
98
```
99
100
**Usage Examples:**
101
102
```typescript
103
// Revoke access token
104
await notion.oauth.revoke({
105
token: "access-token-to-revoke",
106
});
107
108
console.log("Token revoked successfully");
109
```
110
111
### Introspect Access Token
112
113
Get information about an access token including its validity and associated workspace.
114
115
```typescript { .api }
116
/**
117
* Introspect an access token
118
* @param args - OAuth token introspection parameters
119
* @returns Promise resolving to introspection response
120
*/
121
oauth.introspect(args: OauthIntrospectParameters): Promise<OauthIntrospectResponse>;
122
123
interface OauthIntrospectParameters {
124
/** Access token to introspect */
125
token: string;
126
}
127
128
interface OauthIntrospectResponse {
129
/** Whether the token is active/valid */
130
active: boolean;
131
/** Token type */
132
token_type?: "bearer";
133
/** Bot user ID */
134
bot_id?: string;
135
/** Workspace information */
136
workspace_name?: string;
137
workspace_id?: string;
138
workspace_icon?: string;
139
/** Owner information */
140
owner?: {
141
type: "workspace" | "user";
142
user?: {
143
object: "user";
144
id: string;
145
name?: string;
146
avatar_url?: string;
147
type: "person";
148
person?: {
149
email?: string;
150
};
151
};
152
};
153
}
154
```
155
156
**Usage Examples:**
157
158
```typescript
159
// Check if token is valid
160
const introspection = await notion.oauth.introspect({
161
token: "access-token-to-check",
162
});
163
164
if (introspection.active) {
165
console.log("Token is valid");
166
console.log(`Workspace: ${introspection.workspace_name}`);
167
console.log(`Bot ID: ${introspection.bot_id}`);
168
} else {
169
console.log("Token is invalid or expired");
170
}
171
172
// Validate token before making API calls
173
async function validateAndUseToken(token: string) {
174
const introspection = await notion.oauth.introspect({ token });
175
176
if (!introspection.active) {
177
throw new Error("Token is invalid");
178
}
179
180
// Token is valid, use it for API calls
181
const client = new Client({ auth: token });
182
return client;
183
}
184
```
185
186
## Complete OAuth Flow Example
187
188
```typescript
189
import { Client } from "@notionhq/client";
190
191
// OAuth configuration
192
const CLIENT_ID = "your-oauth-client-id";
193
const CLIENT_SECRET = "your-oauth-client-secret";
194
const REDIRECT_URI = "https://yourapp.com/oauth/callback";
195
196
// Step 1: Redirect user to Notion OAuth URL
197
function getAuthorizationUrl() {
198
const baseUrl = "https://api.notion.com/v1/oauth/authorize";
199
const params = new URLSearchParams({
200
client_id: CLIENT_ID,
201
response_type: "code",
202
owner: "user", // or "workspace"
203
redirect_uri: REDIRECT_URI,
204
});
205
206
return `${baseUrl}?${params.toString()}`;
207
}
208
209
// Step 2: Handle OAuth callback and exchange code for token
210
async function handleOAuthCallback(code: string) {
211
// Create client with client credentials for token exchange
212
const notion = new Client();
213
214
const tokenResponse = await notion.oauth.token({
215
grant_type: "authorization_code",
216
code: code,
217
redirect_uri: REDIRECT_URI,
218
});
219
220
// Store the access token securely
221
const accessToken = tokenResponse.access_token;
222
223
// Create authenticated client for user
224
const userNotion = new Client({
225
auth: accessToken,
226
});
227
228
return {
229
client: userNotion,
230
tokenInfo: tokenResponse,
231
};
232
}
233
234
// Step 3: Validate token periodically
235
async function validateStoredToken(token: string) {
236
const notion = new Client();
237
238
const introspection = await notion.oauth.introspect({
239
token: token,
240
});
241
242
return introspection.active;
243
}
244
245
// Step 4: Revoke token when user disconnects
246
async function disconnectIntegration(token: string) {
247
const notion = new Client();
248
249
await notion.oauth.revoke({
250
token: token,
251
});
252
253
console.log("Integration disconnected");
254
}
255
```
256
257
## OAuth Client Authentication
258
259
For OAuth endpoints, the client must be configured with client credentials:
260
261
```typescript
262
// Configure client for OAuth operations
263
const oauthClient = new Client({
264
auth: {
265
client_id: "your-client-id",
266
client_secret: "your-client-secret",
267
},
268
});
269
270
// Or use the generic request method
271
const tokenResponse = await notion.request({
272
path: "oauth/token",
273
method: "post",
274
body: {
275
grant_type: "authorization_code",
276
code: "auth-code",
277
redirect_uri: "redirect-uri",
278
},
279
auth: {
280
client_id: "your-client-id",
281
client_secret: "your-client-secret",
282
},
283
});
284
```
285
286
## Types
287
288
```typescript { .api }
289
interface OauthTokenParameters {
290
grant_type: "authorization_code";
291
code: string;
292
redirect_uri?: string;
293
}
294
295
interface OauthTokenResponse {
296
access_token: string;
297
token_type: "bearer";
298
bot_id: string;
299
workspace_name?: string;
300
workspace_id?: string;
301
workspace_icon?: string;
302
owner: {
303
type: "workspace" | "user";
304
user?: {
305
object: "user";
306
id: string;
307
name?: string;
308
avatar_url?: string;
309
type: "person";
310
person?: {
311
email?: string;
312
};
313
};
314
};
315
duplicated_template_id?: string;
316
request_id: string;
317
}
318
319
interface OauthRevokeParameters {
320
token: string;
321
}
322
323
interface OauthRevokeResponse {
324
// Empty object on success
325
}
326
327
interface OauthIntrospectParameters {
328
token: string;
329
}
330
331
interface OauthIntrospectResponse {
332
active: boolean;
333
token_type?: "bearer";
334
bot_id?: string;
335
workspace_name?: string;
336
workspace_id?: string;
337
workspace_icon?: string;
338
owner?: {
339
type: "workspace" | "user";
340
user?: {
341
object: "user";
342
id: string;
343
name?: string;
344
avatar_url?: string;
345
type: "person";
346
person?: {
347
email?: string;
348
};
349
};
350
};
351
}
352
```