0
# Client Configuration
1
2
Client configuration in the OpenAI Node.js SDK covers initialization options for the `OpenAI` and `AzureOpenAI` clients, per-request customization through `RequestOptions`, and environment variable setup for both standard and Azure deployments.
3
4
## Overview
5
6
The SDK provides flexible configuration at multiple levels:
7
8
1. **Client-level configuration** - Set when instantiating `OpenAI` or `AzureOpenAI`
9
2. **Request-level configuration** - Override per-request via `RequestOptions`
10
3. **Environment variables** - Automatic discovery of credentials and settings
11
12
This approach allows you to balance convenience (environment variables for simple scripts) with flexibility (request-level overrides for complex applications).
13
14
## OpenAI Client
15
16
### Constructor
17
18
```typescript { .api }
19
class OpenAI {
20
constructor(options?: ClientOptions): void;
21
}
22
```
23
24
The main API client for standard OpenAI services.
25
26
**Basic usage:**
27
28
```typescript
29
import { OpenAI } from 'openai';
30
31
const client = new OpenAI({
32
apiKey: 'sk-...',
33
});
34
```
35
36
### withOptions Method
37
38
```typescript { .api }
39
withOptions(options: Partial<ClientOptions>): this;
40
```
41
42
Create a new client instance re-using the same options given to the current client with optional overriding. This method is useful for creating derived clients with different configurations while preserving most settings from the parent client.
43
44
**Usage:**
45
46
```typescript
47
import { OpenAI } from 'openai';
48
49
// Base client with default settings
50
const baseClient = new OpenAI({
51
apiKey: 'sk-...',
52
organization: 'org-...',
53
timeout: 60000,
54
});
55
56
// Create a new client with modified timeout, keeping other settings
57
const slowClient = baseClient.withOptions({
58
timeout: 120000,
59
});
60
61
// Create a new client with different organization
62
const otherOrgClient = baseClient.withOptions({
63
organization: 'org-other',
64
});
65
```
66
67
Common use cases:
68
- **Per-tenant clients**: Create clients with different organization/project IDs
69
- **Variable timeouts**: Create clients with different timeout settings for long-running operations
70
- **Custom headers**: Add request-specific headers while preserving base configuration
71
- **Testing**: Create test clients with modified settings without duplicating configuration
72
73
### ClientOptions Interface
74
75
```typescript { .api }
76
/**
77
* API key setter function that returns a promise resolving to a string token.
78
* Invoked before each request to allow dynamic key rotation or refresh.
79
*/
80
type ApiKeySetter = () => Promise<string>;
81
82
interface ClientOptions {
83
apiKey?: string | ApiKeySetter | undefined;
84
organization?: string | null | undefined;
85
project?: string | null | undefined;
86
baseURL?: string | null | undefined;
87
timeout?: number | undefined;
88
maxRetries?: number | undefined;
89
defaultHeaders?: HeadersLike | undefined;
90
defaultQuery?: Record<string, string | undefined> | undefined;
91
dangerouslyAllowBrowser?: boolean | undefined;
92
fetchOptions?: MergedRequestInit | undefined;
93
fetch?: Fetch | undefined;
94
logLevel?: LogLevel | undefined;
95
logger?: Logger | undefined;
96
webhookSecret?: string | null | undefined;
97
}
98
```
99
100
#### Configuration Options
101
102
**apiKey** (string | ApiKeySetter)
103
104
API key for authentication. Can be a static string or an async function that returns a token.
105
106
- Defaults to `process.env['OPENAI_API_KEY']`
107
- Function form enables runtime credential rotation
108
- Function must return non-empty string; throws `OpenAIError` otherwise
109
- When function throws, error wrapped in `OpenAIError` with original as `cause`
110
111
```typescript
112
// Static string
113
const client = new OpenAI({ apiKey: 'sk-...' });
114
115
// Dynamic token provider
116
const client = new OpenAI({
117
apiKey: async () => {
118
const token = await getAccessToken();
119
return token;
120
}
121
});
122
```
123
124
**organization** (string | null)
125
126
OpenAI organization ID for API requests.
127
128
- Defaults to `process.env['OPENAI_ORG_ID']`
129
- Set to `null` to explicitly disable
130
- Sent in `OpenAI-Organization` header
131
132
**project** (string | null)
133
134
OpenAI project ID for API requests.
135
136
- Defaults to `process.env['OPENAI_PROJECT_ID']`
137
- Set to `null` to explicitly disable
138
- Sent in `OpenAI-Project` header
139
140
**baseURL** (string)
141
142
Override the default base URL for API requests.
143
144
- Defaults to `process.env['OPENAI_BASE_URL']` or `https://api.openai.com/v1`
145
- Must be a valid HTTPS URL
146
- Useful for proxies, custom deployments, or testing
147
148
**timeout** (number)
149
150
Maximum time in milliseconds to wait for a response.
151
152
- Defaults to `600000` (10 minutes)
153
- Retryable timeouts (408, 429, 5xx) will retry up to `maxRetries` times
154
- Total wait could exceed timeout in worst case
155
- Per-request override available via `RequestOptions`
156
157
**maxRetries** (number)
158
159
Maximum number of retry attempts for transient failures.
160
161
- Defaults to `2`
162
- Applies to: timeouts (408), locks (409), rate limits (429), server errors (5xx)
163
- Uses exponential backoff with jitter (0.5s to 8s)
164
- Per-request override available via `RequestOptions`
165
166
**defaultHeaders** (HeadersLike)
167
168
Default HTTP headers sent with every request.
169
170
- Applied to all requests unless overridden per-request
171
- Set header to `null` in request options to remove
172
- Useful for custom headers (tracing, correlation IDs, etc.)
173
174
**defaultQuery** (Record<string, string | undefined>)
175
176
Default query parameters added to all requests.
177
178
- Applied to all requests unless overridden per-request
179
- Set parameter to `undefined` in request options to remove
180
- Useful for API keys in query strings or experiment flags
181
182
**dangerouslyAllowBrowser** (boolean)
183
184
Enable browser execution of the client.
185
186
- Defaults to `false`
187
- Disabled to protect against accidental credential exposure
188
- Only set `true` if credentials are properly protected (e.g., API gateway, proxy)
189
- Passing `azureADTokenProvider` in AzureOpenAI automatically enables
190
191
**fetchOptions** (MergedRequestInit)
192
193
Additional options passed to `fetch` calls.
194
195
- Common use cases: custom `Agent`, SSL certificates, keepalive settings
196
- Properties overridden by per-request `fetchOptions`
197
- Platform-specific options may not be available in all environments
198
199
**fetch** (Fetch)
200
201
Custom `fetch` implementation.
202
203
- Defaults to platform-native fetch (Node.js, browser, Cloudflare)
204
- Use for: testing, custom HTTP handling, request/response interception
205
- Must be compatible with standard Fetch API
206
207
**logLevel** (LogLevel)
208
209
Control logging verbosity.
210
211
```typescript { .api }
212
type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug';
213
```
214
215
- Defaults to `process.env['OPENAI_LOG']` or `'off'`
216
- Useful for debugging request/response issues
217
- Filters log messages by level: 'off' disables logging, 'error' only shows errors, etc.
218
219
**logger** (Logger)
220
221
Custom logger implementation.
222
223
```typescript { .api }
224
interface Logger {
225
error: (message: string, ...rest: unknown[]) => void;
226
warn: (message: string, ...rest: unknown[]) => void;
227
info: (message: string, ...rest: unknown[]) => void;
228
debug: (message: string, ...rest: unknown[]) => void;
229
}
230
```
231
232
- Defaults to `globalThis.console`
233
- Implement interface with `debug()`, `info()`, `warn()`, `error()` methods
234
- Use with `logLevel` to control verbosity
235
236
**webhookSecret** (string)
237
238
Secret for verifying webhook signatures.
239
240
- Defaults to `process.env['OPENAI_WEBHOOK_SECRET']`
241
- Used with `client.webhooks.verifySignature()`
242
243
## AzureOpenAI Client
244
245
### Constructor
246
247
```typescript { .api }
248
class AzureOpenAI extends OpenAI {
249
constructor(options?: AzureClientOptions): void;
250
}
251
```
252
253
Azure-specific OpenAI client with Azure authentication and deployment support.
254
255
**Basic usage:**
256
257
```typescript
258
import { AzureOpenAI } from 'openai';
259
260
const client = new AzureOpenAI({
261
endpoint: 'https://my-resource.openai.azure.com/',
262
apiKey: 'your-azure-api-key',
263
apiVersion: '2024-08-01-preview',
264
});
265
```
266
267
### AzureClientOptions Interface
268
269
```typescript { .api }
270
interface AzureClientOptions extends ClientOptions {
271
apiVersion?: string | undefined;
272
endpoint?: string | undefined;
273
deployment?: string | undefined;
274
apiKey?: string | undefined;
275
azureADTokenProvider?: (() => Promise<string>) | undefined;
276
}
277
```
278
279
#### Azure-Specific Options
280
281
**apiVersion** (string)
282
283
Azure OpenAI API version for requests.
284
285
- Defaults to `process.env['OPENAI_API_VERSION']`
286
- Required - throws `OpenAIError` if missing
287
- Format typically: `'2024-08-01-preview'`
288
- Sent as `api-version` query parameter
289
290
**endpoint** (string)
291
292
Azure OpenAI endpoint URL including resource name.
293
294
- Format: `https://{resource-name}.openai.azure.com/`
295
- Defaults to `process.env['AZURE_OPENAI_ENDPOINT']`
296
- Mutually exclusive with `baseURL`
297
- Automatically appends `/openai` to construct base URL
298
299
**deployment** (string)
300
301
Model deployment name for Azure.
302
303
- If provided, constructs paths as `/deployments/{deployment}`
304
- Overridden per-request by `model` parameter if not specified
305
- Cannot be used with Assistants APIs
306
- Simplifies requests to single deployment
307
308
**apiKey** (string)
309
310
Azure API key for authentication.
311
312
- Defaults to `process.env['AZURE_OPENAI_API_KEY']`
313
- Mutually exclusive with `azureADTokenProvider`
314
- Sent in `api-key` header
315
316
**azureADTokenProvider** (() => Promise<string>)
317
318
Function providing Microsoft Entra access tokens.
319
320
- Called before each request
321
- Enables: managed identity, service principal, user credentials
322
- Mutually exclusive with `apiKey`
323
- Automatically enables `dangerouslyAllowBrowser`
324
325
**Example with Microsoft Entra:**
326
327
```typescript
328
import { AzureOpenAI } from 'openai';
329
import { DefaultAzureCredential } from '@azure/identity';
330
331
const credential = new DefaultAzureCredential();
332
333
const client = new AzureOpenAI({
334
endpoint: 'https://my-resource.openai.azure.com/',
335
apiVersion: '2024-08-01-preview',
336
azureADTokenProvider: async () => {
337
const token = await credential.getToken('https://cognitiveservices.azure.com/.default');
338
return token.token;
339
}
340
});
341
```
342
343
## RequestOptions
344
345
Per-request configuration for individual API calls.
346
347
```typescript { .api }
348
type RequestOptions = {
349
method?: HTTPMethod;
350
path?: string;
351
query?: object | undefined | null;
352
body?: unknown;
353
headers?: HeadersLike;
354
maxRetries?: number;
355
timeout?: number;
356
fetchOptions?: MergedRequestInit;
357
signal?: AbortSignal | undefined | null;
358
idempotencyKey?: string;
359
defaultBaseURL?: string | undefined;
360
stream?: boolean | undefined;
361
}
362
```
363
364
### Common Per-Request Options
365
366
**headers** (HeadersLike)
367
368
Request-specific HTTP headers.
369
370
- Merged with `defaultHeaders` from client config
371
- Set to `null` to remove default header
372
- Overrides defaults for same header name
373
374
**maxRetries** (number)
375
376
Retry count for this specific request.
377
378
- Overrides client-level `maxRetries`
379
- Useful for one-off requests needing different retry behavior
380
381
**timeout** (number)
382
383
Timeout in milliseconds for this request.
384
385
- Overrides client-level `timeout`
386
- Per-request timeouts enable fine-grained control
387
388
**signal** (AbortSignal)
389
390
Abort signal for canceling request.
391
392
- Passed to `fetch` call
393
- Automatically canceled on client-level timeout
394
- Enables: CancellationToken pattern, request cancellation UI
395
396
```typescript
397
const controller = new AbortController();
398
const timeout = setTimeout(() => controller.abort(), 5000);
399
400
try {
401
const response = await client.chat.completions.create({
402
model: 'gpt-4',
403
messages: [...],
404
}, { signal: controller.signal });
405
} finally {
406
clearTimeout(timeout);
407
}
408
```
409
410
**idempotencyKey** (string)
411
412
Unique key for idempotency tracking.
413
414
- Required for POST requests if client configured with idempotency header
415
- Prevents duplicate requests with same key
416
- Format: any unique string (UUID recommended)
417
418
## Environment Variables
419
420
The SDK automatically reads these environment variables if not provided in options:
421
422
**OPENAI_API_KEY** (required for standard OpenAI)
423
424
API key for OpenAI platform.
425
426
```bash
427
export OPENAI_API_KEY='sk-...'
428
```
429
430
**OPENAI_ORG_ID** (optional)
431
432
OpenAI organization ID.
433
434
```bash
435
export OPENAI_ORG_ID='org-...'
436
```
437
438
**OPENAI_PROJECT_ID** (optional)
439
440
OpenAI project ID.
441
442
```bash
443
export OPENAI_PROJECT_ID='proj_...'
444
```
445
446
**OPENAI_BASE_URL** (optional)
447
448
Custom base URL for requests.
449
450
```bash
451
export OPENAI_BASE_URL='https://api.example.com/v1'
452
```
453
454
**OPENAI_LOG** (optional)
455
456
Logging level: `'debug'`, `'info'`, `'warn'`, `'error'`
457
458
```bash
459
export OPENAI_LOG='debug'
460
```
461
462
**OPENAI_WEBHOOK_SECRET** (optional)
463
464
Secret for webhook signature verification.
465
466
```bash
467
export OPENAI_WEBHOOK_SECRET='whsec_...'
468
```
469
470
**Azure-specific environment variables:**
471
472
- **AZURE_OPENAI_API_KEY** - Azure API key
473
- **AZURE_OPENAI_ENDPOINT** - Azure endpoint URL
474
- **OPENAI_API_VERSION** - Azure API version
475
476
## Configuration Examples
477
478
### Basic Setup
479
480
```typescript
481
import { OpenAI } from 'openai';
482
483
// Uses OPENAI_API_KEY from environment
484
const client = new OpenAI();
485
486
// Explicit API key
487
const client = new OpenAI({
488
apiKey: 'sk-...',
489
});
490
```
491
492
### Azure Setup
493
494
```typescript
495
import { AzureOpenAI } from 'openai';
496
497
// Using API key
498
const client = new AzureOpenAI({
499
endpoint: 'https://my-resource.openai.azure.com/',
500
apiKey: 'your-key',
501
apiVersion: '2024-08-01-preview',
502
});
503
504
// Using deployment
505
const client = new AzureOpenAI({
506
endpoint: 'https://my-resource.openai.azure.com/',
507
apiKey: 'your-key',
508
apiVersion: '2024-08-01-preview',
509
deployment: 'gpt-4-deployment',
510
});
511
```
512
513
### Custom Base URL
514
515
```typescript
516
import { OpenAI } from 'openai';
517
518
// Use proxy or custom API
519
const client = new OpenAI({
520
apiKey: 'sk-...',
521
baseURL: 'https://proxy.example.com/openai/v1',
522
});
523
524
// Per-request override
525
const response = await client.chat.completions.create({
526
model: 'gpt-4',
527
messages: [...],
528
}, {
529
defaultBaseURL: 'https://alternate-proxy.example.com/v1',
530
});
531
```
532
533
### Proxy Configuration
534
535
```typescript
536
import { OpenAI } from 'openai';
537
import { HttpProxyAgent, HttpsProxyAgent } from 'http-proxy-agent';
538
539
const httpAgent = new HttpProxyAgent('http://proxy.example.com:8080');
540
const httpsAgent = new HttpsProxyAgent('https://proxy.example.com:8080');
541
542
const client = new OpenAI({
543
apiKey: 'sk-...',
544
fetchOptions: {
545
agent: httpAgent, // Node.js HTTP agent
546
},
547
});
548
```
549
550
### Timeouts and Retries
551
552
```typescript
553
import { OpenAI } from 'openai';
554
555
// Custom timeout and retries
556
const client = new OpenAI({
557
apiKey: 'sk-...',
558
timeout: 30000, // 30 seconds
559
maxRetries: 3, // Retry up to 3 times
560
});
561
562
// Per-request override
563
const response = await client.chat.completions.create({
564
model: 'gpt-4',
565
messages: [...],
566
}, {
567
timeout: 60000, // 60 seconds for this request
568
maxRetries: 1, // Only 1 retry for this request
569
});
570
```
571
572
### Default Headers
573
574
```typescript
575
import { OpenAI } from 'openai';
576
577
const client = new OpenAI({
578
apiKey: 'sk-...',
579
defaultHeaders: {
580
'X-Custom-Header': 'value',
581
'X-Correlation-ID': generateTraceId(),
582
},
583
});
584
585
// Remove default header for specific request
586
const response = await client.chat.completions.create({
587
model: 'gpt-4',
588
messages: [...],
589
}, {
590
headers: {
591
'X-Custom-Header': null, // Remove this header
592
},
593
});
594
```
595
596
### Browser Usage
597
598
```typescript
599
import { OpenAI } from 'openai';
600
601
// Enable browser usage (only with appropriate security measures)
602
const client = new OpenAI({
603
apiKey: 'sk-...',
604
dangerouslyAllowBrowser: true,
605
});
606
607
// WARNING: This exposes your API key to the client browser.
608
// Only use with:
609
// - Proxies that hide the real API key
610
// - API gateways that enforce auth
611
// - Time-limited tokens
612
```
613
614
### Per-Request Options
615
616
```typescript
617
import { OpenAI } from 'openai';
618
619
const client = new OpenAI({ apiKey: 'sk-...' });
620
621
// Override headers, timeout, retries per request
622
const response = await client.chat.completions.create({
623
model: 'gpt-4',
624
messages: [{ role: 'user', content: 'Hello' }],
625
}, {
626
headers: {
627
'X-Request-ID': generateRequestId(),
628
},
629
timeout: 120000,
630
maxRetries: 0, // Don't retry this request
631
signal: abortController.signal,
632
});
633
```
634
635
### Dynamic API Keys
636
637
```typescript
638
import { OpenAI } from 'openai';
639
640
async function getAccessToken() {
641
// Fetch from your token service
642
return 'sk-...';
643
}
644
645
const client = new OpenAI({
646
apiKey: getAccessToken, // Function called before each request
647
});
648
649
// Keys automatically refreshed on each request
650
const response = await client.chat.completions.create({
651
model: 'gpt-4',
652
messages: [...],
653
});
654
```
655
656
## API Key Management Best Practices
657
658
### Security
659
660
1. **Never commit API keys to version control**
661
- Use `.gitignore` for `.env` files
662
- Use environment variables or secrets management
663
664
2. **Protect keys in browser environments**
665
- Only use `dangerouslyAllowBrowser: true` with backend proxy
666
- Never expose keys directly to clients
667
- Implement server-side authentication layer
668
669
3. **Rotate credentials regularly**
670
- Use dynamic token providers for service accounts
671
- Implement key rotation schedules
672
- Monitor key usage and disable unused keys
673
674
### Environment Setup
675
676
```bash
677
# Development (.env file - add to .gitignore)
678
OPENAI_API_KEY=sk-...
679
OPENAI_ORG_ID=org-...
680
681
# Production (use secrets management)
682
# AWS: AWS Secrets Manager, Parameter Store
683
# Azure: Key Vault
684
# Google Cloud: Secret Manager
685
# GitHub: Secrets (for CI/CD)
686
```
687
688
### Secrets Management Example
689
690
```typescript
691
import { OpenAI } from 'openai';
692
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
693
694
async function initializeClient() {
695
const secretsClient = new SecretsManagerClient({ region: 'us-east-1' });
696
697
const response = await secretsClient.send(
698
new GetSecretValueCommand({ SecretId: 'openai-api-key' })
699
);
700
701
const apiKey = response.SecretString;
702
703
return new OpenAI({ apiKey });
704
}
705
706
const client = await initializeClient();
707
```
708
709
### Monitoring and Auditing
710
711
1. **Log all API requests** (without exposing keys)
712
2. **Monitor quota and usage**
713
3. **Set rate limits and alarms**
714
4. **Audit key access in organization**
715
716
```typescript
717
import { OpenAI } from 'openai';
718
719
const client = new OpenAI({
720
apiKey: 'sk-...',
721
logLevel: 'info', // Log requests for audit trail
722
});
723
```
724
725
### Organization and Project Scoping
726
727
Use organization and project IDs to scope API access:
728
729
```typescript
730
const client = new OpenAI({
731
apiKey: 'sk-...',
732
organization: 'org-...', // Restrict to organization
733
project: 'proj_...', // Further restrict to project
734
});
735
```
736
737
This enables:
738
- Cost allocation per project
739
- Access control per team
740
- Audit logs per project
741
- Quota management
742
743
## Related Documentation
744
745
- [ChatCompletions](./chat-completions.md) - Per-request parameters
746
- [Assistants](./assistants.md) - Specialized configuration
747
- [Realtime](./realtime.md) - WebSocket-specific options
748