Skip to content

@venturekit/integrations API

@venturekit/integrations provides tools for calling third-party APIs from your Lambda functions:

  • HTTP Client — configurable fetch-based client with retry, timeout, interceptors
  • OAuth2 — client credentials & authorization code flows with automatic token refresh
  • API Key Management — retrieve and cache keys from env vars, SSM, or Secrets Manager
Terminal window
npm install @venturekit/integrations

Create a configured HTTP client for calling external APIs.

import { apiClient } from '@venturekit/integrations';
const stripe = apiClient({
baseUrl: 'https://api.stripe.com/v1',
headers: { Authorization: `Bearer ${process.env.STRIPE_KEY}` },
retry: { maxRetries: 3 },
timeout: 10_000,
});
const customer = await stripe.post<StripeCustomer>('/customers', {
body: { email: 'user@example.com' },
});
// customer.data, customer.status, customer.headers
OptionTypeDescription
baseUrlstringBase URL for all requests
headersRecord<string, string>Default headers
timeoutnumberDefault timeout in ms (default: 30000)
retryRetryOptionsRetry configuration
onRequestRequestInterceptor[]Interceptors called before each request
onResponseResponseInterceptor[]Interceptors called after each response
onErrorErrorInterceptorCalled on any error before it’s thrown
OptionTypeDefaultDescription
maxRetriesnumber0Max retry attempts
initialDelayMsnumber1000Initial backoff delay
backoffMultipliernumber2Exponential backoff multiplier
retryableStatusesnumber[][408, 429, 500, 502, 503, 504]HTTP statuses that trigger retry
OptionTypeDescription
bodyunknownRequest body (auto-JSON-stringified)
headersRecord<string, string>Per-request headers
paramsRecord<string, string>Query parameters
timeoutnumberTimeout override (ms)
formbooleanSend as application/x-www-form-urlencoded
signalAbortSignalCancellation signal
interface ApiResponse<T> {
status: number;
headers: Record<string, string>;
data: T;
retried: boolean;
attempts: number;
}

Thrown on non-2xx responses or network errors.

class ApiError extends Error {
status: number;
headers: Record<string, string>;
data: unknown;
url: string;
method: string;
}

Create an OAuth2 client for automatic token management.

Server-to-server authentication (no user interaction):

import { oauth2, apiClient } from '@venturekit/integrations';
const auth = oauth2({
flow: 'client_credentials',
tokenUrl: 'https://oauth.provider.com/token',
clientId: process.env.CLIENT_ID!,
clientSecret: process.env.CLIENT_SECRET!,
scopes: ['read', 'write'],
});
// Attach to an API client — tokens refresh automatically
const client = apiClient({
baseUrl: 'https://api.provider.com',
onRequest: [auth.interceptor()],
});

User-delegated authentication (e.g. Google, Slack):

const auth = oauth2({
flow: 'authorization_code',
tokenUrl: 'https://oauth2.googleapis.com/token',
authorizeUrl: 'https://accounts.google.com/o/oauth2/v2/auth',
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
redirectUri: 'https://myapp.com/callback',
scopes: ['profile', 'email'],
store: await createDynamoDBTokenStore({ tableName: 'oauth-tokens' }),
});
// 1. Redirect user to authorize
const url = auth.getAuthorizeUrl!('random-state');
// 2. Exchange code in callback handler
const token = await auth.exchangeCode!('auth-code-from-callback');
// 3. Use with API client
const google = apiClient({
baseUrl: 'https://www.googleapis.com',
onRequest: [auth.interceptor()],
});
MethodDescription
getToken()Get a valid access token (auto-refreshes)
refreshToken()Force a token refresh
interceptor()Returns a request interceptor that attaches the Bearer token
exchangeCode(code)Exchange an authorization code (auth code flow only)
getAuthorizeUrl(state?)Build the authorization URL (auth code flow only)
StoreDescription
createMemoryTokenStore()In-memory (default) — resets on cold start
createDynamoDBTokenStore({ tableName })DynamoDB — persists across invocations

Create a handle for retrieving and caching an API key.

import { apiKey, apiKeyHeader, apiClient } from '@venturekit/integrations';
// From environment variable
const stripeKey = apiKey({ env: 'STRIPE_SECRET_KEY' });
// From SSM Parameter Store
const twilioKey = apiKey({ ssm: '/myapp/prod/twilio-key' });
// From Secrets Manager (with JSON field extraction)
const slackToken = apiKey({
secret: 'myapp/slack-bot-token',
field: 'token',
});
// Use with apiClient
const stripe = apiClient({
baseUrl: 'https://api.stripe.com/v1',
onRequest: [apiKeyHeader(stripeKey)],
});
SourceFieldsDescription
{ env: string }Environment variable nameReads from process.env
{ ssm: string, region?, withDecryption? }SSM pathReads from Parameter Store
{ secret: string, field?, region? }Secret name/ARNReads from Secrets Manager
MethodDescription
get()Get the key (cached after first call, 5-min TTL)
refresh()Force a re-fetch
clear()Clear the cache

apiKeyHeader(handle, headerName?, prefix?)

Section titled “apiKeyHeader(handle, headerName?, prefix?)”

Convenience function that returns a request interceptor attaching the key as a header.

// Default: Authorization: Bearer <key>
apiKeyHeader(myKey)
// Custom header, no prefix: X-Api-Key: <key>
apiKeyHeader(myKey, 'X-Api-Key', '')