AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Call Log

skill-voicenterteam-claude-marketplace-call-log · by VoicenterTeam

Pull call detail records (CDR) from Voicenter using the Call Log API

No reviews yet
0 installs
17 views
0.0% view→install

Install

$ agentstack add skill-voicenterteam-claude-marketplace-call-log

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-voicenterteam-claude-marketplace-call-log)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Call Log? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

> Language. Reply in the user's language: detect what they write — Hebrew→Hebrew, English→English — and mirror it, switching if they switch mid-conversation. This shapes your prose, your questions, and your AskUserQuestion option labels only. It does not change the artifacts you produce — identifiers, JSON keys, BCP-47 language codes, API field names, and other data stay exactly as specified.

> CRM integration context. When the user is building a full CRM integration — not just this API in isolation — always invoke the crm-onboarding skill alongside this one and frame the answer covering all three core services: Click2Call, Screen Pop, and Call History.

Help the developer query call history (CDR records) from the Voicenter Call Log API — filter by date, phone, extension, call type, and choose exactly which fields to return.

When to use this skill

Use this skill when the user wants to:

  • Retrieve historical call records for reporting or analytics
  • Find all calls to/from a specific phone number or extension
  • Get recording URLs for past calls to display in a CRM
  • Build missed-call reports (filter by DialStatus: ABANDONE or NOANSWER)
  • Correlate a specific call by its ID (ivruniqueid / CALLID)
  • Export call data to BI tools or billing systems
  • Audit agent activity over a date range

Environment Variables

VOICENTER_API_CODE=your_api_token_here
# The server making requests must also have its IP authorized in Voicenter CPanel

Endpoint

https://api.voicenter.com/hub/cdr/

Accepts: POST-JSON or GET Response: JSON

Authentication

Send your code in the request body. The requesting server's IP must be authorized in the Voicenter CPanel under API Settings.

Request Structure

The request has two parts: search criteria (what to filter) and fields (what to return).

Search Criteria

| Parameter | Type | Required | Description | |---|---|---|---| | code | String | ✅ | API authentication token | | fromdate | ISO 8601 | ✅ | Start date/time in GMT+0 (e.g. 2024-06-01T00:00:00) | | todate | ISO 8601 | ✅ | End date/time in GMT+0 | | phones | String[] | ❌ | Phone numbers to filter (with country code, e.g. "972501234567") | | extensions | String[] | ❌ | SIP extension codes to filter | | IdentityCriteria | String | ❌ | Account, Hierarchical, Department, or User | | callID | String | ❌ | Filter for a specific call by ivruniqueid | | cdrTypes | Integer[] | ❌ | Filter by call type IDs (see table below) | | campaignID | Number[] | ❌ | Filter by dialer campaign IDs | | queueID | Number[] | ❌ | Filter by queue IDs |

CDR Type IDs

| ID | Type Name | |---|---| | 1 | Incoming Call | | 4 | Extension Outgoing | | 8 | Queue | | 9 | Click2Call leg1 | | 10 | Click2Call leg2 | | 11 | VoiceMail | | 13 | XferCDR (transferred) | | 14 | ProductiveCall Leg1 | | 15 | ProductiveCall Leg2 | | 17 | Click 2 IVR | | 18 | Click 2 IVR Incoming | | 19 | Click 2 Queue Incoming | | 21 | Attended CDR leg1 | | 22 | Attended CDR leg2 | | 23 | Auto forward |

Returnable Fields

Choose which CDR fields to receive:

CallerNumber, TargetNumber, Date, DateEpoch, Duration, CallID, Type, CdrType, DialStatus, Targetextension, Callerextension, DID, QueueName, RecordURL, RecordExpect, Price, RingTime, RepresentativeName, RepresentativeCode, UserName, UserId, DTMFData, CustomData, DepartmentName, DepartmentId, TargetPrefixName

Sort

"sort": [
  { "field": "date", "order": "desc" },
  { "field": "Duration", "order": "asc" }
]

Full POST-JSON Request Example

{
  "code": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "fields": [
    "CallerNumber", "TargetNumber", "Date", "Duration", "CallID",
    "Type", "CdrType", "DialStatus", "DID", "QueueName",
    "RecordURL", "RingTime", "RepresentativeName", "RepresentativeCode",
    "DTMFData", "CustomData", "DepartmentName"
  ],
  "search": {
    "fromdate": "2024-06-01T00:00:00",
    "todate": "2024-06-30T23:59:59",
    "cdrTypes": [1, 8, 9, 10],
    "phones": ["972501234567"],
    "extensions": ["SIPSIP1"],
    "IdentityCriteria": "Account"
  },
  "sort": [{ "field": "date", "order": "desc" }]
}

Response

{
  "ERROR_NUMBER": 0,
  "ERROR_DESCRIPTION": "OK",
  "STATUS_CODE": 200,
  "TOTAL_HITS": 2,
  "RETURN_HITS": 2,
  "CDR_LIST": [
    {
      "CallerNumber": "0722776772",
      "TargetNumber": "972501234567",
      "Date": "2024-06-10T09:04:58Z",
      "Duration": 2,
      "CallID": "202406101204550233243ghff3189e5c",
      "CustomData": {},
      "Type": "Extension Outgoing",
      "CdrType": 4,
      "DialStatus": "ANSWER",
      "CallerExtension": "SIPSIP1",
      "DID": "",
      "RecordURL": "https://cpanel.voicenter.co.il/CallsHistory/PlayRecord/2024061043950926.mp3",
      "RingTime": 10,
      "RepresentativeName": "John Doe",
      "RepresentativeCode": "87654321",
      "DTMFData": [],
      "DepartmentName": "Sales"
    }
  ]
}

Error Codes

| ERRORNUMBER | STATUSCODE | Description | |---|---|---| | 0 | 200 | OK | | 1 | 403 | Rate limit exceeded — wait 5 seconds between requests | | 2 | 403 | Authorization failed — invalid code | | 4 | 403 | IP not authorized — add server IP in CPanel | | 5 | 404 | Date range invalid |

TypeScript Implementation

const CALL_LOG_URL = 'https://api.voicenter.com/hub/cdr/';
const CODE = process.env.VOICENTER_API_CODE!;

interface CdrRecord {
  CallerNumber: string;
  TargetNumber: string;
  Date: string;
  Duration: number;
  CallID: string;
  Type: string;
  CdrType: number;
  DialStatus: string;
  DID: string;
  QueueName?: string;
  RecordURL: string;
  RingTime: number;
  RepresentativeName: string;
  RepresentativeCode: string;
  DTMFData: Array;
  CustomData: Record;
}

interface CallLogResponse {
  ERROR_NUMBER: number;
  ERROR_DESCRIPTION: string;
  TOTAL_HITS: number;
  RETURN_HITS: number;
  CDR_LIST: CdrRecord[];
}

async function getCallLog(
  fromdate: string,
  todate: string,
  options?: {
    phones?: string[];
    extensions?: string[];
    cdrTypes?: number[];
    callID?: string;
    fields?: string[];
    sort?: Array;
  }
): Promise {
  const body = {
    code: CODE,
    fields: options?.fields ?? [
      'CallerNumber', 'TargetNumber', 'Date', 'Duration', 'CallID',
      'Type', 'CdrType', 'DialStatus', 'DID', 'QueueName',
      'RecordURL', 'RingTime', 'RepresentativeName', 'CustomData',
    ],
    search: {
      fromdate,
      todate,
      IdentityCriteria: 'Account',
      ...(options?.phones && { phones: options.phones }),
      ...(options?.extensions && { extensions: options.extensions }),
      ...(options?.cdrTypes && { cdrTypes: options.cdrTypes }),
      ...(options?.callID && { callID: options.callID }),
    },
    sort: options?.sort ?? [{ field: 'date', order: 'desc' }],
  };

  const res = await fetch(CALL_LOG_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });

  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const data: CallLogResponse = await res.json();
  if (data.ERROR_NUMBER !== 0) throw new Error(`Call Log error ${data.ERROR_NUMBER}: ${data.ERROR_DESCRIPTION}`);
  return data;
}

// Example: get all missed incoming calls today
const { CDR_LIST } = await getCallLog(
  '2024-06-01T00:00:00',
  '2024-06-01T23:59:59',
  {
    cdrTypes: [1, 8],
    fields: ['CallerNumber', 'Date', 'DialStatus', 'QueueName', 'DID'],
  }
);

const missed = CDR_LIST.filter(r => r.DialStatus === 'ABANDONE' || r.DialStatus === 'NOANSWER');
console.log(`Missed calls: ${missed.length}`);

Service Limits

  • Maximum 10,000 CDR records per request — break large date ranges into daily chunks
  • Maximum 30 requests per minute — add a 2-second delay between sequential requests
  • CDRs appear a few minutes after a call ends — not suitable for real-time use
  • Only authorized IP addresses can call this API (set in CPanel under API Settings)

Tips

  • Use cdrTypes: [9, 10] to get only Click2Call records and correlate Leg1/Leg2 by CallID.
  • CustomData.OriginalIvrUniqueID links a transferred call back to the original call.
  • RecordURL is a direct MP3 link — store it in your CRM for playback.
  • All dates in requests must be GMT+0. Israeli time is GMT+2 (or GMT+3 in summer).
  • DialStatus values: ANSWER, NOANSWER, BUSY, CANCEL, ABANDONE, TIMEOUT, VOICEMAIL.

Related Skills

  • CDR Notification — Receive CDRs in real time via webhook instead of polling
  • Click2Call — The CALLID returned by Click2Call is the same as CallID in CDR records
  • Productive Dialer — Filter dialer call records with cdrTypes: [14, 15]
  • Active Calls — For live call state; Call Log is for historical records only

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.