The ChartPull REST API lets you integrate org chart data into your own applications, scripts, and workflows. Pull employee lists, search your directory, and retrieve the full org tree — all from a simple, well-documented JSON API.
The REST API requires the Integrations add-on. During your 14-day trial, all workspaces have full access to all API endpoints.
All API requests go to the ChartPull API base URL:
https://chartpull.com/api/v1Authentication uses API keys with the cpk_ prefix. Pass your key in the Authorization header as a Bearer token:
Authorization: Bearer cpk_your_api_key_hereAPI keys are generated at Admin > API Keys in ChartPull. Each key is stored as a SHA-256 hash on our servers — we never store the plain-text key. If you lose a key, you need to generate a new one.
Never expose API keys in client-side code
Your API key grants read access to your entire org chart. Only use it in server-side code, backend services, cron jobs, or CI/CD pipelines. Never include it in frontend JavaScript, mobile apps, or any code that runs in a user’s browser.Go to Admin › API Keys
Open ChartPull and navigate to Admin › API Keys in the sidebar. You will see a list of existing keys (if any) and a button to create a new one.
Click "Create API Key"
Enter a descriptive name for the key, like "Production Backend" or "CI Pipeline." This helps you identify which key is used where.
Copy the key immediately
The key (starting with cpk_) is displayed once. Copy it and store it securely in your environment variables or secrets manager. You will not be able to see the full key again.
Test with a curl request
Run a quick test to make sure the key works: curl -H "Authorization: Bearer cpk_..." https://chartpull.com/api/v1/departments. You should get a JSON response with your department list.
The API provides 5 endpoints covering employees, hierarchy, search, and more. All responses are JSON.
| Method & path | Description | Rate limit |
|---|---|---|
| GET /api/v1/employees | List all employees (paginated) | 30 / 60s |
| GET /api/v1/employees/:id | Get a specific employee by ID | 60 / 60s |
| GET /api/v1/employees/search?q= | Search by name, title, or department | 30 / 60s |
| GET /api/v1/org-tree | Full org tree as nested JSON | 10 / 60s |
| GET /api/v1/departments | List all departments with headcounts | 30 / 60s |
curl -H "Authorization: Bearer cpk_your_key" \
"https://chartpull.com/api/v1/employees?page=1&limit=20"{
"data": [
{
"id": "emp_abc123",
"name": "Sarah Chen",
"email": "sarah.chen@example.com",
"title": "Senior Product Manager",
"department": "Product",
"managerId": "emp_def456",
"location": "San Francisco"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 342,
"totalPages": 18
}
}The API uses standard HTTP status codes. Here are the codes you are most likely to encounter:
| Status | Meaning | What to do |
|---|---|---|
| 401 | Unauthorized | Your API key is missing or invalid. Check that the Authorization header is correct and the key has not been revoked. |
| 403 | Forbidden | Your plan does not include API access, or the key does not have permission for this endpoint. Check that your plan includes API access or verify your key permissions. |
| 429 | Too Many Requests | You have hit a rate limit. Check the Retry-After header for how many seconds to wait before retrying. Implement exponential backoff in your client. |
| 500 | Internal Server Error | Something went wrong on our end. Retry the request after a few seconds. If it persists, contact support@chartpull.com. |
All error responses include a JSON body with a message field explaining the issue:
{
"error": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"retryAfter": 45
}Rate limits are enforced per API key on a rolling window. When you hit a limit, the API returns a 429 status code with a Retry-After header indicating how many seconds to wait.
Build with rate limits in mind
If you are building a sync pipeline, batch your requests and add a small delay between calls. For real-time integrations, consider using webhooks to receive push notifications instead of polling the API.