A simple SDK for interacting with the Payspace API
Project description
PaySpace SDK
A comprehensive Python SDK for interacting with the PaySpace Deel Local Payroll API v2.0. This SDK provides a clean, Pythonic interface to all PaySpace API endpoints, making it easy to integrate payroll operations into your Python applications.
Table of Contents
- Features
- Installation
- Quick Start
- Authentication
- Environments
- API Coverage
- Usage Examples
- API Reference
- Rate Limits
- Error Handling
- Contributing
- License
Features
- ✅ Complete API v2.0 Coverage - Supports all PaySpace API v2.0 endpoints
- 🔐 OAuth 2.0 Authentication - Secure authentication with client credentials or access tokens
- 🌍 Multi-Environment Support - Production, Staging, and Development environments
- 📊 Comprehensive Data Access - Employee info, payroll, leave, benefits, and more
- 🔍 Lookup Tables - Access to all reference data and lookup values
- ⚡ Simple Interface - Clean, intuitive methods for all operations
- 🐍 Type Hints - Full type hints for better IDE support
- 📝 Extensive Documentation - Detailed docstrings and examples
Installation
From Source
git clone https://github.com/jb-tech1999/payspace_sdk.git
cd payspace_sdk
pip install -e .
Requirements
- Python 3.7+
- requests
Quick Start
from payspace_sdk import PaySpaceClient, PaySpaceEnvironment
# Initialize the client with your credentials
client = PaySpaceClient(
client_id="your_client_id",
client_secret="your_client_secret",
environment=PaySpaceEnvironment.PRODUCTION
)
# Authenticate
client.authenticate()
# Get available companies
companies = client.get_companies()
print(f"Found {len(companies)} companies")
# Get employee data
company_id = companies[0]['CompanyId']
employees = client.get_biographical(company_id, 2024, 1, 1)
print(f"Found {len(employees)} employees")
Authentication
The SDK supports two authentication methods:
1. Client Credentials (Recommended)
client = PaySpaceClient(
client_id="your_client_id",
client_secret="your_client_secret",
environment=PaySpaceEnvironment.PRODUCTION
)
# Authenticate and get access token
token = client.authenticate()
# Get available companies (returned during authentication)
companies = client.get_available_companies()
# Or fetch companies via API
companies = client.get_companies()
2. Pre-existing Access Token
client = PaySpaceClient(
access_token="your_existing_token",
environment=PaySpaceEnvironment.PRODUCTION
)
# No need to authenticate, token is already set
companies = client.get_companies()
Environments
The SDK supports three environments:
| Environment | URL | Auth URL | Rate Limit |
|---|---|---|---|
| Production | https://api.payspace.com/odata/v2.0 |
https://identity.yourhcm.com/connect/token |
2000 req/min |
| Staging | https://apistaging.payspace.com/odata/v2.0 |
https://staging-identity.yourhcm.com/connect/token |
200 req/min |
| Development | https://localhost:44393/odata/v2.0 |
https://localhost:44392/connect/token |
No limit |
Using Different Environments
from payspace_sdk import PaySpaceClient, PaySpaceEnvironment
# Production (default)
prod_client = PaySpaceClient(
client_id="id",
client_secret="secret",
environment=PaySpaceEnvironment.PRODUCTION
)
# Staging
staging_client = PaySpaceClient(
client_id="id",
client_secret="secret",
environment=PaySpaceEnvironment.STAGING
)
# Development
dev_client = PaySpaceClient(
client_id="id",
client_secret="secret",
environment=PaySpaceEnvironment.DEVELOPMENT
)
# Custom environment
custom_client = PaySpaceClient(
client_id="id",
client_secret="secret",
environment="https://custom-api.example.com/odata/v2.0",
auth_url="https://custom-auth.example.com/connect/token"
)
API Coverage
The SDK provides comprehensive coverage of the PaySpace API v2.0:
Company Information
get_companies()- Get all companiesget_company_names()- Get company namesget_company_frequency()- Get pay frequenciesget_company_runs()- Get payroll runsget_company_training_courses()- Get training coursesget_company_custom_forms()- Get custom formsget_company_review_process()- Get review processesget_organization_units()- Get organization unitsget_currency_exchange_rates()- Get exchange rates
Employee Information
get_biographical()- Get employee biographical dataget_biographical_including_terminated()- Include terminated employeesget_employee_addresses()- Get employee addressesget_employee_bank_details()- Get bank account detailsget_employee_dependants()- Get dependant informationget_employee_positions()- Get position detailsget_employee_attachments()- Get employee documentsget_employee_skills()- Get employee skillsget_employee_qualifications()- Get qualificationsget_employee_suspension()- Get suspension records
Payroll & Compensation
get_payslips()- Get employee payslipsget_payslip_lines()- Get detailed payslip linesget_costed_payslip_lines()- Get costed payslip linesget_pay_rate_details()- Get pay rate informationget_financial_transactions()- Get financial transactionsget_recurring_costing_split()- Get recurring costs
Leave Management
get_leave_applications()- Get leave applicationsget_leave_adjustments()- Get leave adjustmentsget_payslip_leave_balances()- Get leave balances
Benefits & Deductions
get_employee_medical()- Medical aid informationget_employee_pension_fund()- Pension fund detailsget_employee_disability()- Disability insuranceget_employee_group_life()- Group life insuranceget_employee_income_protection()- Income protectionget_employee_retirement_annuity()- Retirement annuitiesget_employee_garnishee()- Garnishee ordersget_employee_loan()- Employee loansget_employee_saving()- Savings schemesget_employee_union()- Union membershipget_employee_company_car_detail()- Company car detailsget_employee_bonus_provision()- Bonus provisions
Components & Custom Data
get_employee_component()- Get employee componentsget_employee_component_values()- Get component valuesget_employee_custom_forms()- Get custom form data
Training & Development
get_employee_training()- Get training recordsget_employee_incidents()- Get incident records
Performance Management
get_employee_review_template()- Get review templatesget_employee_review_header()- Get review headersget_employee_review_kpa()- Get KPA reviews
Projects & Costing
get_employee_project()- Get project assignments
Tax Information
get_tax_profile()- Get tax profile information
Lookup Tables (60+ lookup endpoints)
The SDK provides access to all lookup/reference data tables:
# Examples of lookup methods
client.get_account_type_lookup(company_id)
client.get_address_country_lookup(company_id)
client.get_citizenship_lookup(company_id)
client.get_classification_lookup(company_id)
client.get_currency_lookup(company_id)
client.get_employment_category_lookup(company_id)
client.get_job_lookup(company_id)
client.get_marital_status_lookup(company_id)
# ... and 50+ more lookup methods
Usage Examples
Example 1: Get Employee Payslips for Current Month
from payspace_sdk import PaySpaceClient, PaySpaceAPIHelper
client = PaySpaceClient(
client_id="your_client_id",
client_secret="your_client_secret"
)
client.authenticate()
companies = client.get_companies()
company_id = companies[0]['CompanyId']
# Get current period
year, month = PaySpaceAPIHelper.get_current_period()
# Fetch payslips
payslips = client.get_payslips(company_id, year, month)
for payslip in payslips:
print(f"Employee: {payslip['EmployeeNumber']}")
print(f"Net Pay: {payslip['NetPay']}")
print(f"Period: {payslip['Period']}")
print("---")
Example 2: Get Employee Details with Address
# Get biographical data
year, month, day = PaySpaceAPIHelper.get_current_date()
employees = client.get_biographical(company_id, year, month, day)
# Get addresses
addresses = client.get_employee_addresses(company_id, year, month, day)
# Combine data
for employee in employees:
emp_number = employee['EmployeeNumber']
emp_addresses = [a for a in addresses if a['EmployeeNumber'] == emp_number]
print(f"Employee: {employee['FirstName']} {employee['LastName']}")
print(f"Number: {emp_number}")
for addr in emp_addresses:
print(f"Address: {addr.get('AddressLine1', '')}")
print("---")
Example 3: Search for Specific Company
# Search by company name
companies = client.get_companies(company_search="Acme Corp")
if companies:
company = companies[0]
print(f"Found: {company['CompanyName']}")
print(f"ID: {company['CompanyId']}")
print(f"Group: {company['CompanyGroup']}")
Example 4: Get Leave Applications for Date Range
from datetime import date
start_date = date(2024, 1, 1)
end_date = date(2024, 1, 31)
leave_apps = client.get_leave_applications(
company_id=company_id,
year=2024,
month=1,
start_date=start_date,
end_date=end_date
)
for leave in leave_apps:
print(f"Employee: {leave['EmployeeNumber']}")
print(f"Type: {leave['LeaveType']}")
print(f"Days: {leave['Days']}")
print(f"Status: {leave['Status']}")
print("---")
Example 5: Get Payroll Runs for a Frequency
# Get company frequencies first
frequencies = client.get_company_frequency(company_id)
for freq in frequencies:
print(f"Frequency: {freq['Frequency']}")
# Get runs for this frequency
runs = client.get_company_runs(company_id, freq['Frequency'])
for run in runs:
print(f" Period: {run['Period']}")
print(f" Start: {run['PeriodStartDate']}")
print(f" End: {run['PeriodEndDate']}")
Example 6: Using Lookup Tables
# Get employment categories
categories = client.get_employment_category_lookup(company_id)
for cat in categories:
print(f"{cat['Code']}: {cat['Description']}")
# Get job titles
jobs = client.get_job_lookup(company_id)
for job in jobs:
print(f"{job['Code']}: {job['Description']}")
# Get currencies
currencies = client.get_currency_lookup(company_id)
for curr in currencies:
print(f"{curr['Code']}: {curr['Description']}")
Example 7: Working with Benefits
# Get pension fund details
pension = client.get_employee_pension_fund(
company_id=company_id,
frequency="Monthly",
period="2024-01"
)
for record in pension:
print(f"Employee: {record['EmployeeNumber']}")
print(f"Fund: {record['PensionFund']}")
print(f"Employee Contribution: {record['EmployeeContribution']}")
print(f"Employer Contribution: {record['EmployerContribution']}")
print("---")
# Get medical aid details
medical = client.get_employee_medical(
company_id=company_id,
frequency="Monthly",
period="2024-01"
)
API Reference
PaySpaceClient Class
The main client class for interacting with the PaySpace API.
Constructor
PaySpaceClient(
client_id: Optional[str] = None,
client_secret: Optional[str] = None,
access_token: Optional[str] = None,
environment: str = PaySpaceEnvironment.PRODUCTION,
auth_url: Optional[str] = None
)
Parameters:
client_id- OAuth client IDclient_secret- OAuth client secretaccess_token- Pre-existing OAuth 2.0 access token (optional)environment- API environment URLauth_url- Authentication URL (auto-configured based on environment)
Authentication Methods
authenticate() -> str
Authenticate with the API and retrieve an access token.
Returns: Access token string
Raises: ValueError if client_id/client_secret not provided
get_available_companies() -> List[Dict]
Get the list of companies available to the authenticated user.
Returns: List of company dictionaries
PaySpaceAPIHelper Class
Helper class with utility methods.
Static Methods
get_current_period() -> tuple
Get the current year and month.
Returns: Tuple of (year, month)
get_current_date() -> tuple
Get the current year, month, and day.
Returns: Tuple of (year, month, day)
format_date(dt: Union[date, datetime]) -> str
Format a date for API queries (yyyy-MM-dd format).
Parameters:
dt- Date or datetime object
Returns: Formatted date string
Rate Limits
PaySpace API v2.0 enforces the following rate limits:
- Production: 2000 requests per minute
- Staging: 200 requests per minute
- Development: No enforced limit
When rate limits are exceeded, the API returns a 429 status code. Implement appropriate retry logic with exponential backoff when needed.
Error Handling
The SDK raises exceptions for various error conditions:
from requests.exceptions import HTTPError
try:
client = PaySpaceClient(client_id="id", client_secret="secret")
client.authenticate()
companies = client.get_companies()
except ValueError as e:
print(f"Configuration error: {e}")
except HTTPError as e:
if e.response.status_code == 401:
print("Authentication failed - check credentials")
elif e.response.status_code == 429:
print("Rate limit exceeded - wait and retry")
elif e.response.status_code == 404:
print("Resource not found")
else:
print(f"HTTP error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Common Error Codes
- 400 Bad Request - Invalid parameters or malformed request
- 401 Unauthorized - Invalid or expired access token
- 403 Forbidden - Insufficient permissions
- 404 Not Found - Resource does not exist
- 429 Too Many Requests - Rate limit exceeded
- 500 Internal Server Error - Server-side error
API v2.0 Breaking Changes
If you're migrating from v1.0, note these changes:
- Lookup Endpoints: All lookup endpoints now require the
/Lookup/prefix - Date Format: Dates must be in
yyyy-MM-ddformat for Edm.Date types - OData Version: Requires OData 4.0 headers
- Rate Limits: Different limits for production (2000/min) vs staging (200/min)
Best Practices
1. Reuse Client Instances
# Good - reuse the same client
client = PaySpaceClient(client_id="id", client_secret="secret")
client.authenticate()
companies = client.get_companies()
for company in companies:
employees = client.get_biographical(company['CompanyId'], 2024, 1, 1)
2. Use Environment Variables
import os
client = PaySpaceClient(
client_id=os.getenv("PAYSPACE_CLIENT_ID"),
client_secret=os.getenv("PAYSPACE_CLIENT_SECRET"),
environment=os.getenv("PAYSPACE_ENV", PaySpaceEnvironment.PRODUCTION)
)
3. Handle Pagination for Large Datasets
# Some endpoints return large datasets
# The API uses OData pagination with @odata.nextLink
def get_all_employees(client, company_id):
employees = []
response = client.get_biographical(company_id, 2024, 1, 1)
employees.extend(response)
# Note: Current SDK returns 'value' list
# If you need to handle nextLink, you may need to access raw response
return employees
4. Cache Lookup Data
# Lookup data rarely changes - cache it
lookup_cache = {}
def get_cached_lookup(client, company_id, lookup_name):
"""
Cache lookup data to avoid repeated API calls.
lookup_name should be like 'currency', 'job', 'marital_status', etc.
"""
cache_key = f"{company_id}_{lookup_name}"
if cache_key not in lookup_cache:
try:
method = getattr(client, f"get_{lookup_name}_lookup")
lookup_cache[cache_key] = method(company_id)
except AttributeError:
raise ValueError(f"Unknown lookup type: {lookup_name}")
return lookup_cache[cache_key]
# Usage example
currencies = get_cached_lookup(client, company_id, "currency")
jobs = get_cached_lookup(client, company_id, "job")
Troubleshooting
Authentication Issues
Problem: ValueError: client_id and client_secret are required
Solution: Ensure you provide both client_id and client_secret when initializing the client.
Problem: 401 Unauthorized error
Solution:
- Verify your credentials are correct
- Check that you're using the right environment
- Ensure your token hasn't expired (get a new one with
authenticate())
Connection Issues
Problem: Connection timeout or refused
Solution:
- For Development environment, ensure the local API is running
- Check your network connection
- Verify the environment URL is correct
Data Not Found
Problem: Empty results when you expect data
Solution:
- Verify the company_id is correct
- Check the date parameters (year, month, day)
- Ensure the company has data for the requested period
- Verify the frequency matches the company's pay frequency
Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
Development Setup
git clone https://github.com/jb-tech1999/payspace_sdk.git
cd payspace_sdk
pip install -e .
License
This project is open source. Please check the repository for license details.
Support
For issues, questions, or contributions, please visit:
- GitHub: https://github.com/jb-tech1999/payspace_sdk
- Issues: https://github.com/jb-tech1999/payspace_sdk/issues
Disclaimer
This SDK is provided as-is. Always test thoroughly in a staging environment before using in production. Ensure you comply with PaySpace's terms of service and API usage guidelines.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file payspace_sdk-0.1.1.tar.gz.
File metadata
- Download URL: payspace_sdk-0.1.1.tar.gz
- Upload date:
- Size: 20.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e2f60500ea1caa1bc6057489470e9ec33db5e018a3500c58d786c36abe22ecd
|
|
| MD5 |
1b1f2b506508847785753c3e83e4ce16
|
|
| BLAKE2b-256 |
8209c63bea1bb4a65c0fc714dc81b61246c28bc6dc5ab7ce9016c2f6f8f4c3c0
|
File details
Details for the file payspace_sdk-0.1.1-py3-none-any.whl.
File metadata
- Download URL: payspace_sdk-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6789d3e97d9be1a92d22e8075fdd48e53bc591c1020fed520406403c54b1d00
|
|
| MD5 |
9bd2f63a003adb13fb8dc4354841b939
|
|
| BLAKE2b-256 |
f34266c31e699ec4a8465e2668ede619cf93b2aaf9f1edbb69cd470b2fe28cf4
|