CallRail
CallRail API integration with managed OAuth. Track and analyze phone calls, manage tracking numbers, companies, and tags. Use this skill when users want to access call data, manage tracking numbers, v
CallRail API integration with managed OAuth. Track and analyze phone calls, manage tracking numbers, companies, and tags. Use this skill when users want to access call data, manage tracking numbers, v
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Access the CallRail API with managed OAuth authentication. Track calls, manage tracking numbers, analyze call data, and organize with tags.
# List all calls python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/callrail/v3/a/{account_id}/calls.json') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
https://gateway.maton.ai/callrail/{native-api-path}
Replace
{native-api-path} with the actual CallRail API endpoint path. The gateway proxies requests to api.callrail.com and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as
MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your CallRail OAuth connections at
https://ctrl.maton.ai.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=callrail&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'callrail'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
{ "connection": { "connection_id": "75364cb9-7116-4367-a707-1113d426f17d", "status": "ACTIVE", "creation_time": "2026-02-10T09:55:17.574212Z", "last_updated_time": "2026-02-10T09:55:34.693801Z", "url": "https://connect.maton.ai/?session_token=...", "app": "callrail", "metadata": {} } }
Open the returned
url in a browser to complete OAuth authorization.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If you have multiple CallRail connections, specify which one to use with the
Maton-Connection header:
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/callrail/v3/a.json') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '75364cb9-7116-4367-a707-1113d426f17d') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If omitted, the gateway uses the default (oldest) active connection.
All CallRail API endpoints follow this pattern:
/callrail/v3/a/{account_id}/{resource}.json
Account IDs start with
ACC, Company IDs start with COM, Call IDs start with CAL, Tracker IDs start with TRK, User IDs start with USR.
GET /callrail/v3/a.json
Response:
{ "page": 1, "per_page": 100, "total_pages": 1, "total_records": 1, "accounts": [ { "id": "ACC019c46b8a0807fbdb81c8bf12af91cb3", "name": "My Account", "numeric_id": 518664017, "inbound_recording_enabled": false, "outbound_recording_enabled": false, "hipaa_account": false, "created_at": "2026-02-10 03:43:50 -0500" } ] }
GET /callrail/v3/a/{account_id}.json
GET /callrail/v3/a/{account_id}/companies.json
Response:
{ "page": 1, "per_page": 100, "total_pages": 1, "total_records": 1, "companies": [ { "id": "COM019c46b8a26376a9a4f29671dcdd49e9", "name": "My Company", "status": "active", "time_zone": "America/Los_Angeles", "created_at": "2026-02-10T08:43:51.280Z", "callscore_enabled": false, "lead_scoring_enabled": true, "callscribe_enabled": true } ] }
GET /callrail/v3/a/{account_id}/companies/{company_id}.json
GET /callrail/v3/a/{account_id}/calls.json
Query Parameters:
| Parameter | Description |
|---|---|
| Page number (default: 1) |
| Results per page (default: 100, max: 250) |
| Preset: , , , , , , |
| ISO 8601 date (e.g., ) |
| ISO 8601 date |
| Filter by company |
| Filter by tracker |
| Search term |
| Comma-separated field names to return |
| Field to sort by |
| Sort order: or |
Response:
{ "page": 1, "per_page": 100, "total_pages": 1, "total_records": 1, "calls": [ { "id": "CAL019c46b9fc277a7881e3728fea20869b", "answered": false, "customer_name": "John Doe", "customer_phone_number": "+18886757190", "direction": "inbound", "duration": 36, "recording": "https://api.callrail.com/v3/a/.../recording", "recording_duration": 36, "start_time": "2026-02-10T00:45:19.781-08:00", "tracking_phone_number": "+18017846712", "voicemail": true } ] }
GET /callrail/v3/a/{account_id}/calls/{call_id}.json
PUT /callrail/v3/a/{account_id}/calls/{call_id}.json Content-Type: application/json{ "customer_name": "John Smith", "note": "Follow up scheduled", "lead_status": "good_lead", "spam": false }
Updatable Fields:
| Field | Description |
|---|---|
| Customer's name |
| Call notes |
| , , |
| Mark as spam (boolean) |
| Array of tag names to apply |
| Call value (numeric) |
| Add tags without removing existing |
GET /callrail/v3/a/{account_id}/calls/summary.json
Get aggregated call statistics for a date range.
Query Parameters:
| Parameter | Description |
|---|---|
| Preset date range |
| Start date (ISO 8601) |
| End date (ISO 8601) |
| Group results: , , , , etc. |
Response:
{ "start_date": "2026-02-03T00:00:00-0800", "end_date": "2026-02-10T23:59:59-0800", "time_zone": "Pacific Time (US & Canada)", "total_results": { "total_calls": 42 } }
GET /callrail/v3/a/{account_id}/calls/timeseries.json
Get call data over time for charts and graphs.
Response:
{ "start_date": "2026-02-03T00:00:00-0800", "end_date": "2026-02-10T23:59:59-0800", "data": [ {"key": "2026-02-03", "date": "2026-02-03", "total_calls": 5}, {"key": "2026-02-04", "date": "2026-02-04", "total_calls": 8} ] }
GET /callrail/v3/a/{account_id}/trackers.json
Response:
{ "page": 1, "per_page": 100, "total_records": 1, "trackers": [ { "id": "TRK019c46b9f18174d68bb8d7985260a11f", "name": "Google My Business", "type": "source", "status": "active", "destination_number": "+18019234886", "tracking_numbers": ["+18017846712"], "sms_supported": true, "sms_enabled": true, "company": { "id": "COM019c46b8a26376a9a4f29671dcdd49e9", "name": "My Company" }, "source": {"type": "google_my_business"}, "call_flow": { "type": "basic", "recording_enabled": true, "destination_number": "+18019234886" } } ] }
GET /callrail/v3/a/{account_id}/trackers/{tracker_id}.json
GET /callrail/v3/a/{account_id}/tags.json
Response:
{ "page": 1, "per_page": 100, "total_records": 6, "tags": [ { "id": 7886733, "name": "Schedule requested", "tag_level": "account", "color": "orange3", "background_color": "gray1", "company_id": null, "status": "enabled" }, { "id": 7886728, "name": "Opportunity", "tag_level": "company", "color": "gray1", "company_id": "COM019c46b8a26376a9a4f29671dcdd49e9", "status": "enabled" } ] }
POST /callrail/v3/a/{account_id}/tags.json Content-Type: application/json{ "name": "New Tag", "tag_level": "account", "color": "blue1" }
Tag Levels:
account - Available to all companies in the accountcompany - Specific to a company (requires company_id)Colors:
gray1, blue1, blue2, green1, green2, orange1, orange2, orange3, red1, etc.
PUT /callrail/v3/a/{account_id}/tags/{tag_id}.json Content-Type: application/json{ "name": "Updated Tag Name", "color": "green1" }
DELETE /callrail/v3/a/{account_id}/tags/{tag_id}.json
GET /callrail/v3/a/{account_id}/users.json
Response:
{ "page": 1, "per_page": 100, "total_records": 1, "users": [ { "id": "USR019c46b8a0557b2e85e5e1c651452509", "email": "user@example.com", "first_name": "John", "last_name": "Doe", "name": "John Doe", "role": "admin", "accepted": true, "created_at": "2026-02-10T03:43:50.798-05:00", "companies": [ {"id": "COM...", "name": "My Company"} ] } ] }
GET /callrail/v3/a/{account_id}/users/{user_id}.json
GET /callrail/v3/a/{account_id}/integrations.json?company_id={company_id}
Note:
company_id is required.
GET /callrail/v3/a/{account_id}/notifications.json
CallRail uses offset-based pagination:
GET /callrail/v3/a/{account_id}/calls.json?page=2&per_page=50
Response includes:
{ "page": 2, "per_page": 50, "total_pages": 10, "total_records": 487, "calls": [...] }
Parameters:
page - Page number (default: 1)per_page - Results per page (default: 100, max: 250)For the calls endpoint, you can also use relative pagination:
GET /callrail/v3/a/{account_id}/calls.json?relative_pagination=true
This returns
next_page URL and has_next_page boolean for efficient pagination of large datasets.
const response = await fetch( 'https://gateway.maton.ai/callrail/v3/a/{account_id}/calls.json', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json(); console.log(data.calls);
import os import requestsresponse = requests.get( 'https://gateway.maton.ai/callrail/v3/a/{account_id}/calls.json', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, params={'per_page': 50, 'date_range': 'last_30_days'} ) data = response.json() for call in data['calls']: print(f"{call['customer_name']}: {call['duration']}s")
| Endpoint Type | Hourly Limit | Daily Limit |
|---|---|---|
| General API | 1,000 | 10,000 |
| SMS Send | 150 | 1,000 |
| Outbound Calls | 100 | 2,000 |
Exceeding limits returns HTTP 429. Implement exponential backoff for retries.
ACCCOMCALTRKUSR.jsoncurl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Bad request or missing required parameter |
| 401 | Invalid or missing Maton API key |
| 403 | Forbidden - insufficient permissions |
| 404 | Resource not found |
| 422 | Unprocessable entity |
| 429 | Rate limited |
| 500 | Internal server error |
| 503 | Service unavailable |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
callrail. For example:https://gateway.maton.ai/callrail/v3/a.jsonhttps://gateway.maton.ai/v3/a.jsonNo automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.