A TypeScript package for securely accessing API keys and OAuth tokens stored in your Keyflow account.
npm install @keyflow/credentials
import { credentials } from '@keyflow/credentials';
// Get OpenAI credentials
const openaiCreds = await credentials.openai();
// Use the access token for API calls
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${openaiCreds.access_token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: 'Hello!' }],
}),
});
Set your Keyflow API key as an environment variable:
export KEYFLOW_API_KEY="your-keyflow-api-key-here"
Alternatively, provide the API key directly:
const creds = await credentials.openai(undefined, {
apiKey: 'your-keyflow-api-key'
});
import { credentials } from '@keyflow/credentials';
// Access any supported provider
const creds = await credentials.provider_name();
credentials.provider_name(name?, options?)
Parameters:
-
name
(optional): String identifier for named credentials -
options
(optional): Configuration object withapiKey
property
Returns: Promise resolving to:
{
name: string; // The credential name/identifier
access_token: string; // The main access token
refresh_token?: string; // Optional refresh token (for OAuth providers)
}
The package supports 35+ integrations:
-
AI/ML:
openai
,gemini
,replicate
,eleven_labs
,groq
,cohere
,deepseek
,perplexity
,humanonic
-
Google Services:
drive
,gmail
,google_docs
,google_sheets
,google_calendar
,gcp
-
Communication:
slack
,discord
,twilio
,vapi
-
Productivity:
notion
,asana
,airtable
,typeform
-
Development:
github
,postgresql
,supabase
,turbopuffer
-
Social:
twitter
,linkedin
,linkedin_cookies
-
Search/Data:
serp
,exa
,apify
-
Other:
microsoft
,apify
import { credentials } from '@keyflow/credentials';
async function generateText(prompt: string) {
try {
const openaiCreds = await credentials.openai();
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${openaiCreds.access_token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: prompt }],
}),
});
const result = await response.json();
return result.choices[0].message.content;
} catch (error) {
console.error('Text generation failed:', error);
throw error;
}
}
Use named credentials when you have multiple accounts for the same service:
// Access different Slack workspaces
const workSlack = await credentials.slack('work-workspace');
const personalSlack = await credentials.slack('personal-workspace');
// Access different databases
const prodDB = await credentials.postgresql('production');
const devDB = await credentials.postgresql('development');
import { credentials } from '@keyflow/credentials';
async function syncDataAcrossServices() {
try {
// Get credentials for multiple services
const [notionCreds, airtableCreds, slackCreds] = await Promise.all([
credentials.notion(),
credentials.airtable(),
credentials.slack(),
]);
// Fetch data from Notion
const notionResponse = await fetch('https://api.notion.com/v1/databases', {
headers: {
'Authorization': `Bearer ${notionCreds.access_token}`,
'Notion-Version': '2022-06-28',
},
});
// Process and sync to Airtable
const notionData = await notionResponse.json();
const airtableResponse = await fetch('https://api.airtable.com/v0/your-base/table', {
method: 'POST',
headers: {
'Authorization': `Bearer ${airtableCreds.access_token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ records: processedData }),
});
// Send Slack notification
await fetch('https://slack.com/api/chat.postMessage', {
method: 'POST',
headers: {
'Authorization': `Bearer ${slackCreds.access_token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
channel: '#updates',
text: 'Data sync completed successfully!',
}),
});
return { success: true };
} catch (error) {
console.error('Data sync failed:', error);
throw error;
}
}
async function readSpreadsheet(spreadsheetId: string) {
const googleCreds = await credentials.google_sheets();
const response = await fetch(
`https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/Sheet1`,
{
headers: {
'Authorization': `Bearer ${googleCreds.access_token}`,
},
}
);
if (!response.ok) {
throw new Error(`Google Sheets API error: ${response.statusText}`);
}
const data = await response.json();
return data.values;
}
// Use HTTPS for all API calls
fetch('https://api.service.com/endpoint', {
headers: { Authorization: `Bearer ${creds.access_token}` }
});
// Log safely without exposing tokens
console.log('Successfully retrieved credentials for OpenAI');
// Handle errors appropriately
try {
const creds = await credentials.openai();
} catch (error) {
throw new Error('OpenAI integration required but not configured');
}
// Never log actual credentials
console.log(`Token: ${creds.access_token}`); // SECURITY RISK
// Don't expose credentials in responses
return { token: creds.access_token, data: result }; // SECURITY RISK
// Don't store credentials in global variables
let savedToken = creds.access_token; // BAD PRACTICE
// Don't use HTTP for sensitive API calls
fetch('http://api.service.com/endpoint'); // INSECURE
- Log into your Keyflow account
- Navigate to account settings
- Configure your integrations (OAuth apps, API keys, etc.)
- Optionally create named credentials for multiple accounts per service
- Use your Keyflow API key to access these credentials programmatically
# Required: Your Keyflow API key
KEYFLOW_API_KEY="your-keyflow-api-key-here"
# Optional: Set to development for local testing
NODE_ENV="development" # Uses localhost:8000 instead of production API
The package includes full TypeScript definitions:
import { credentials, AuthProviderType } from '@keyflow/credentials';
// Type-safe provider names
const provider: AuthProviderType = 'openai';
const creds = await credentials[provider]();
// Typed credential response
interface CredentialResponse {
name: string;
access_token: string;
refresh_token?: string;
}
Missing API Key
Error: API key for Keyflow is missing
Solution: Set the KEYFLOW_API_KEY
environment variable or provide it via options.
Credentials Not Found
Error: Couldn't get openai credential: 404 Not Found
Solution: Configure the OpenAI integration in your Keyflow account settings.
Unauthorized Access
Error: Couldn't get service credential: 401 Unauthorized
Solution: Check that your Keyflow API key is valid and has the necessary permissions.
Network Issues
Error: Failed to fetch
Solution: Ensure you have internet connectivity and the Keyflow API is accessible.
Set NODE_ENV=development
to use the local development API endpoint:
process.env.NODE_ENV = 'development';
const creds = await credentials.openai(); // Uses localhost:8000
This package is part of the Keyflow SDK monorepo. Please refer to the main repository for contribution guidelines.
For support, please contact the Keyflow team or refer to the main Keyflow documentation.