Skip to main content

API Integration Starter Prompt

Context

Use this prompt when integrating with external APIs in Pacing Agency projects (TwentyCRM, Webflow, Google Ads, Stape, etc.). Ensures proper authentication, error handling, rate limiting, and testing.

Prerequisites

  • API documentation reviewed
  • Authentication credentials available
  • Understanding of API endpoints needed
  • Test environment access

See tool documentation for API details: TwentyCRM, Webflow, Google Ads.

Prompt Template

I need to integrate with the following API in a Pacing Agency project:

**API Information:**
- API name: [API_NAME]
- API documentation: [API_DOCS_URL]
- Base URL: [BASE_URL]
- Version: [API_VERSION]

**Authentication:**
- Auth method: [AUTH_METHOD] (API key/OAuth 2.0/JWT/Basic)
- Credentials location: [CREDS_LOCATION] (Environment variables/Secret manager)
- Token refresh: [REFRESH_REQUIREMENTS]

**Endpoints Needed:**
- Endpoint 1: [METHOD] [PATH] - [PURPOSE]
- Endpoint 2: [METHOD] [PATH] - [PURPOSE]
- Endpoint 3: [METHOD] [PATH] - [PURPOSE]

**Integration Requirements:**
- Language/framework: [LANGUAGE] (Node.js/Python/TypeScript)
- Error handling: [ERROR_HANDLING]
- Rate limiting: [RATE_LIMITS]
- Retry logic: [RETRY_STRATEGY]
- Caching: [CACHING_REQUIREMENTS]

**Data Requirements:**
- Request format: [REQUEST_FORMAT]
- Response format: [RESPONSE_FORMAT]
- Data validation: [VALIDATION_REQUIREMENTS]
- Type safety: [TYPE_REQUIREMENTS]

Please provide:

1. **API client module** with authentication
2. **Type definitions** for requests/responses
3. **Error handling** with retries and backoff
4. **Rate limiting** implementation
5. **Testing script** with examples
6. **Documentation** for team use

Follow best practices:
- Never commit API keys
- Use environment variables
- Implement exponential backoff
- Log errors appropriately
- Handle rate limits gracefully

Format with clear sections and code blocks.

Variables to Customize

VariableDescriptionExample
[API_NAME]API service name"TwentyCRM REST API", "Webflow CMS API", "Google Ads API"
[API_DOCS_URL]Documentation URL"https://twenty.com/api/rest"
[BASE_URL]API base URL"https://crm.pacing.agency/rest", "https://api.webflow.com/v2"
[API_VERSION]API version"v2", "2024-01-01", "latest"
[AUTH_METHOD]Authentication type"Bearer token", "OAuth 2.0", "API key", "JWT"
[CREDS_LOCATION]Where credentials stored"Environment variables (.env)", "Hetzner secrets"
[REFRESH_REQUIREMENTS]Token refresh needs"Access token expires in 1 hour", "No refresh needed"
[METHOD]HTTP method"GET", "POST", "PUT", "DELETE", "PATCH"
[PATH]Endpoint path"/companies", "/items", "/conversions/upload"
[PURPOSE]What endpoint does"Fetch all companies", "Create new deal", "Upload conversion"
[LANGUAGE]Programming language"TypeScript", "JavaScript", "Python"
[ERROR_HANDLING]Error strategy"Throw custom errors with context", "Return error objects"
[RATE_LIMITS]API rate limits"100 requests/minute", "10,000 requests/day"
[RETRY_STRATEGY]Retry logic"3 retries with exponential backoff"
[CACHING_REQUIREMENTS]Caching needs"Cache GET responses for 5 minutes", "No caching"
[REQUEST_FORMAT]Request format"JSON", "Form data", "GraphQL"
[RESPONSE_FORMAT]Response format"JSON", "XML", "Plain text"
[VALIDATION_REQUIREMENTS]Data validation"Validate with Zod schema", "TypeScript types only"
[TYPE_REQUIREMENTS]Type safety"Full TypeScript types for all endpoints"

Expected Output

API Client Module (Example: TwentyCRM)

// api/twentycrm.ts
import axios, { AxiosInstance, AxiosError } from 'axios';

interface TwentyCRMConfig {
baseURL: string;
apiKey: string;
timeout?: number;
}

interface Company {
id: string;
name: string;
domainName?: string;
employees?: number;
createdAt: string;
}

interface CreateCompanyRequest {
name: string;
domainName?: string;
employees?: number;
}

class TwentyCRMClient {
private client: AxiosInstance;
private rateLimitRemaining: number = 100;
private rateLimitReset: number = 0;

constructor(config: TwentyCRMConfig) {
this.client = axios.create({
baseURL: config.baseURL,
timeout: config.timeout || 10000,
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json',
},
});

// Response interceptor for rate limit tracking
this.client.interceptors.response.use(
(response) => {
this.updateRateLimitInfo(response.headers);
return response;
},
async (error) => {
if (error.response?.status === 429) {
return this.handleRateLimit(error);
}
return Promise.reject(this.handleError(error));
}
);
}

private updateRateLimitInfo(headers: any) {
if (headers['x-ratelimit-remaining']) {
this.rateLimitRemaining = parseInt(headers['x-ratelimit-remaining']);
}
if (headers['x-ratelimit-reset']) {
this.rateLimitReset = parseInt(headers['x-ratelimit-reset']);
}
}

private async handleRateLimit(error: AxiosError): Promise<any> {
const waitTime = this.rateLimitReset - Math.floor(Date.now() / 1000);
console.warn(`Rate limit exceeded. Waiting ${waitTime}s...`);

await new Promise(resolve => setTimeout(resolve, waitTime * 1000));

// Retry the request
return this.client.request(error.config!);
}

private handleError(error: AxiosError): Error {
if (error.response) {
const message = `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`;
return new Error(message);
} else if (error.request) {
return new Error('No response from API');
} else {
return new Error(`Request failed: ${error.message}`);
}
}

async getCompanies(): Promise<Company[]> {
const response = await this.client.get<Company[]>('/companies');
return response.data;
}

async getCompanyById(id: string): Promise<Company> {
const response = await this.client.get<Company>(`/companies/${id}`);
return response.data;
}

async createCompany(data: CreateCompanyRequest): Promise<Company> {
const response = await this.client.post<Company>('/companies', data);
return response.data;
}

async updateCompany(id: string, data: Partial<CreateCompanyRequest>): Promise<Company> {
const response = await this.client.patch<Company>(`/companies/${id}`, data);
return response.data;
}

async deleteCompany(id: string): Promise<void> {
await this.client.delete(`/companies/${id}`);
}

getRateLimitStatus() {
return {
remaining: this.rateLimitRemaining,
resetAt: new Date(this.rateLimitReset * 1000),
};
}
}

// Initialize client
export function createTwentyCRMClient(apiKey?: string): TwentyCRMClient {
const config: TwentyCRMConfig = {
baseURL: process.env.TWENTYCRM_BASE_URL || 'https://crm.pacing.agency/rest',
apiKey: apiKey || process.env.TWENTYCRM_API_KEY || '',
};

if (!config.apiKey) {
throw new Error('TwentyCRM API key is required');
}

return new TwentyCRMClient(config);
}

export { TwentyCRMClient };
export type { Company, CreateCompanyRequest };

Testing Script

// test-twentycrm.ts
import { createTwentyCRMClient } from './api/twentycrm';

async function testTwentyCRMIntegration() {
try {
console.log('🧪 Testing TwentyCRM API integration...\n');

const client = createTwentyCRMClient();

// Test 1: Fetch companies
console.log('1. Fetching companies...');
const companies = await client.getCompanies();
console.log(`✅ Found ${companies.length} companies\n`);

// Test 2: Create new company
console.log('2. Creating new company...');
const newCompany = await client.createCompany({
name: 'Test Company',
domainName: 'test.com',
employees: 10,
});
console.log(`✅ Created company: ${newCompany.id}\n`);

// Test 3: Update company
console.log('3. Updating company...');
const updated = await client.updateCompany(newCompany.id, {
employees: 15,
});
console.log(`✅ Updated company employees: ${updated.employees}\n`);

// Test 4: Delete company
console.log('4. Deleting test company...');
await client.deleteCompany(newCompany.id);
console.log('✅ Deleted company\n');

// Test 5: Rate limit status
const rateLimit = client.getRateLimitStatus();
console.log('5. Rate limit status:');
console.log(` Remaining: ${rateLimit.remaining}`);
console.log(` Resets at: ${rateLimit.resetAt}\n`);

console.log('✅ All tests passed!');
} catch (error) {
console.error('❌ Test failed:', error);
process.exit(1);
}
}

// Run tests
if (require.main === module) {
testTwentyCRMIntegration();
}

Success Criteria

✅ Authentication working
✅ All endpoints tested
✅ Error handling implemented
✅ Rate limiting handled
✅ Types defined
✅ Documentation written
✅ No credentials committed


Last updated: 2026-01-07
Estimated time: 1-2 hours