@apploi/partner-api
v0.1.5
Published
Official TypeScript client for Apploi Partner API with high-level abstractions
Readme
@apploi/partner-api
Official TypeScript client for the Apploi Partner API with high-level abstractions and type-safe interfaces.
Features
✅ Native TypeScript Types - Use number, Date, and enums instead of strings
✅ Input Validation - Catch errors before making API calls
✅ Strongly-Typed Responses - Full TypeScript interfaces with IDE autocomplete
✅ Better Error Handling - Custom exception hierarchy with detailed error information
✅ Zero External Dependencies - Everything you need in a single package
✅ Developer-Friendly - Intuitive API that follows TypeScript best practices
What is @apploi/partner-api?
@apploi/partner-api is the official TypeScript SDK for the Apploi Partner API, providing an enhanced developer experience with:
- TypeScript-native types: Use
Dateobjects,numbertypes, and type-safe enums instead of strings - Input validation: Validates parameters before making API calls, providing clear error messages
- Better error messages: Custom exception hierarchy with detailed context
- Type-safe responses: Strongly-typed interfaces for all API responses
Everything you need is included in a single package - no additional dependencies required.
Installation
npm install @apploi/partner-apior with yarn:
yarn add @apploi/partner-apiRequirements
- Node.js: >= 16.0.0
- TypeScript: >= 4.5.0 (optional, but recommended)
Quick Start
import { ApploiClient } from '@apploi/partner-api';
// Initialize the client
const client = new ApploiClient({
apiKey: 'your-api-key-here',
baseUrl: 'https://partners.apploi.com' // Optional, this is the default
});
// Get job applications with native types
const applications = await client.getJobApplications({
jobId: 12345, // number, not string!
limit: 50, // number, not string!
updatedAfter: new Date('2024-01-01') // Date object, not string!
});
// Strongly-typed response
console.log(applications.applicants[0].name); // Full TypeScript support
console.log(applications.pagination.total); // IDE autocomplete works
console.log(applications.pagination.hasMore); // Know exactly what fields existAPI Reference
Client Initialization
import { ApploiClient, ApploiClientConfig } from '@apploi/partner-api';
const config: ApploiClientConfig = {
apiKey: 'your-api-key', // Required - API key for authentication
authorization: 'your-auth-token', // Optional - not required by the API
baseUrl: 'https://api.example.com', // Optional - uses default if not provided
timeout: 30000, // Optional - timeout in milliseconds
customHeaders: { // Optional - additional headers
'X-Custom-Header': 'value'
}
};
const client = new ApploiClient(config);
// Or use minimal configuration (recommended):
const client = new ApploiClient({
apiKey: 'your-api-key'
});Getting Job Applications
import { GetJobApplicationsParams, ApplicationStatus } from '@apploi/partner-api';
const params: GetJobApplicationsParams = {
// All parameters are optional and strongly-typed
jobId: 12345, // number or string
teamId: 67890, // number or string
status: ApplicationStatus.SCREENING, // Enum value
updatedAfter: new Date('2024-01-01'), // Date object
updatedBefore: new Date('2024-12-31'), // Date object
limit: 50, // number (1-1000)
offset: 0, // number (>= 0)
includeArchived: false // boolean
};
try {
const result = await client.getJobApplications(params);
// Access strongly-typed response
for (const applicant of result.applicants) {
console.log(`${applicant.name} - ${applicant.status}`);
console.log(`Applied: ${applicant.createdAt}`);
console.log(`Email: ${applicant.email}`);
}
// Pagination information
console.log(`Total: ${result.pagination.total}`);
console.log(`Has more: ${result.pagination.hasMore}`);
} catch (error) {
// Handle errors (see Error Handling section)
}Paginating Through Results
When working with large datasets, use pagination to retrieve all results:
import { ApploiClient, GetJobApplicationsParams } from '@apploi/partner-api';
const client = new ApploiClient({ apiKey: 'your-api-key' });
async function getAllApplications(jobId: number) {
const allApplicants = [];
let offset = 0;
const limit = 100; // Max per page
while (true) {
const result = await client.getJobApplications({
jobId,
limit,
offset
});
allApplicants.push(...result.applicants);
// Check if there are more results
if (!result.pagination.hasMore) {
break;
}
offset += limit;
}
return allApplicants;
}
// Usage
const allApps = await getAllApplications(12345);
console.log(`Retrieved ${allApps.length} total applications`);Working with Application Status
import { ApplicationStatus } from '@apploi/partner-api';
// Use the enum for type safety
const status = ApplicationStatus.HIRED;
// Available statuses:
// - ApplicationStatus.APPLIED
// - ApplicationStatus.SCREENING
// - ApplicationStatus.INTERVIEWING
// - ApplicationStatus.REFERENCE_CHECK
// - ApplicationStatus.OFFER_EXTENDED
// - ApplicationStatus.HIRED
// - ApplicationStatus.REJECTED
// - ApplicationStatus.WITHDRAWN
// - ApplicationStatus.ON_HOLD
// - ApplicationStatus.UNKNOWN (fallback for unrecognized values)Error Handling
@apploi/partner-api provides a custom exception hierarchy for better error handling:
import {
ApploiValidationError,
ApploiAuthenticationError,
ApploiAPIError,
ApploiResponseParseError
} from '@apploi/partner-api';
try {
const result = await client.getJobApplications({ limit: 2000 }); // Invalid!
} catch (error) {
if (error instanceof ApploiValidationError) {
// Parameter validation failed
console.error(`Field ${error.field} is invalid:`, error.message);
console.error('Provided value:', error.value);
} else if (error instanceof ApploiAuthenticationError) {
// 401 or 403 status code
console.error('Auth failed:', error.statusCode, error.message);
} else if (error instanceof ApploiAPIError) {
// Other API errors
console.error('API error:', error.statusCode, error.message);
console.error('Response:', error.response);
} else if (error instanceof ApploiResponseParseError) {
// Failed to parse API response
console.error('Parse error:', error.message);
console.error('Raw response:', error.rawResponse);
}
}Type Definitions
JobApplication
interface JobApplication {
id: string;
jobId: string;
teamId?: string;
status?: ApplicationStatus;
firstName?: string;
lastName?: string;
name: string;
email?: string;
phone?: string;
createdAt?: Date;
updatedAt?: Date;
source?: string;
address?: Address;
resume?: Attachment;
coverLetter?: Attachment;
attachments?: Attachment[];
notes?: string;
tags?: string[];
score?: number;
isPriority?: boolean;
// ... and more fields
}ApplicantsList
interface ApplicantsList {
applicants: JobApplication[];
pagination: {
total: number;
limit: number;
offset: number;
hasMore: boolean;
};
}Validation Rules
@apploi/partner-api validates all inputs before making API calls:
- limit: Must be between 1 and 1000
- offset: Must be >= 0
- IDs: Can be numbers or strings, automatically converted
- Dates: Accept Date objects or ISO strings, converted to YYYY-MM-DD format
- Status: Must be a valid ApplicationStatus enum value
Why Use @apploi/partner-api?
Before: String-Based API
// Everything is strings, no type safety
const result = await api.applicants.getApplicants({
job_id: "12345", // Must convert manually
limit: "50", // Must convert manually
updated_after: "2024-01-01" // Must format manually
});
// Returns: unknown/any - no type information!After: Type-Safe SDK
// Native types, full validation
const result = await client.getJobApplications({
jobId: 12345, // Native number
limit: 50, // Native number
updatedAfter: new Date() // Native Date
});
// Returns: ApplicantsList - strongly typed!Troubleshooting
Common Issues
Authentication Errors (401/403)
Problem: Getting ApploiAuthenticationError
Solution: Verify your API key is correct and active. Contact Apploi support if issues persist.
try {
const result = await client.getJobApplications({ jobId: 123 });
} catch (error) {
if (error instanceof ApploiAuthenticationError) {
console.error('Check your API key:', error.message);
}
}Validation Errors
Problem: Getting ApploiValidationError for valid-looking inputs
Solution: Check the validation rules - limits must be 1-1000, offsets >= 0, etc.
// ❌ Wrong - limit too high
await client.getJobApplications({ limit: 5000 });
// ✅ Correct
await client.getJobApplications({ limit: 1000 });Type Errors in TypeScript
Problem: TypeScript compiler errors about missing types Solution: Ensure you're using TypeScript >= 4.5.0 and have imported types correctly.
// Import both the client and types you need
import { ApploiClient, GetJobApplicationsParams, ApplicationStatus } from '@apploi/partner-api';Module Not Found Errors
Problem: Cannot find module '@apploi/partner-api'
Solution:
- Ensure package is installed:
npm install @apploi/partner-api - Check your
tsconfig.jsonhas"moduleResolution": "node" - Restart your TypeScript server/IDE
Date Formatting Issues
Problem: Dates not being recognized or formatted correctly
Solution: Use native Date objects or ISO 8601 strings. @apploi/partner-api handles conversion automatically.
// ✅ All of these work
await client.getJobApplications({ updatedAfter: new Date() });
await client.getJobApplications({ updatedAfter: new Date('2024-01-01') });
await client.getJobApplications({ updatedAfter: '2024-01-01T00:00:00Z' });Getting Help
- API Documentation: https://integrate.apploi.com/
- Contact Support: Reach out to your Apploi partner support contact
Project Structure
typescript/
├── src/
│ ├── client.ts # Main ApploiClient class
│ ├── models/
│ │ ├── applicant.ts # JobApplication interface and parser
│ │ ├── common.ts # Shared types and pagination
│ │ ├── enums.ts # ApplicationStatus enum
│ │ └── index.ts # Model exports
│ ├── validators/
│ │ ├── dates.ts # Date conversion utilities
│ │ ├── parameters.ts # Parameter validation
│ │ └── index.ts # Validator exports
│ ├── exceptions.ts # Error classes
│ └── index.ts # Package exports
├── examples.ts # Comprehensive usage examples
├── package.json
├── tsconfig.json
└── README.mdAdvanced Usage
Custom Validators
You can also use the validators directly:
import { validateLimit, validateId, validateAndConvertDate } from '@apploi/partner-api';
// Validate parameters before use
const limit = validateLimit(50); // Returns "50"
const id = validateId(12345, 'jobId'); // Returns "12345"
const date = validateAndConvertDate(new Date(), 'startDate'); // Returns "YYYY-MM-DD"Building the Project
# Install dependencies
npm install
# Build TypeScript
npm run build
# Run linter
npm run lint
# Format code
npm run formatFuture Enhancements
While the core functionality is complete, future versions may include:
- Additional endpoints (jobs, documents, webhooks, analytics)
- Async/streaming support for large datasets
- Response caching with TTL
- Retry logic with exponential backoff
- Batch operations for multiple requests
- WebSocket support for real-time updates
Contributing
@apploi/partner-api is part of the Partner API project. To contribute:
- Make changes to the SDK code in
adapters/typescript/src/ - Build with
npm run build - Ensure code follows the existing patterns
- Submit a pull request with a clear description
For detailed development instructions, see the main repository.
Changelog
See GitHub Releases for version history and release notes.
License
MIT
