Skip to content

Bug: availablePhoneNumbers.list() ignores filtering parameters (national_destination_code, etc.) #289

@chris-runriviera

Description

@chris-runriviera

Bug Description

The availablePhoneNumbers.list() method silently ignores filtering parameters like national_destination_code, returning random phone numbers instead of filtering by the requested criteria. This occurs because the SDK doesn't wrap query parameters in the filter[] notation that the Telnyx v2 REST API requires.

Steps to Reproduce

import Telnyx from 'telnyx';

const telnyx = new Telnyx(process.env.TELNYX_API_KEY);

// Request 415 (San Francisco) area code numbers
const response = await telnyx.availablePhoneNumbers.list({
  country_code: 'US',
  national_destination_code: '415',
  limit: 3,
});

console.log(response.data.map(n => n.phone_number));
// Expected: ['+14157238134', '+14157970282', '+14158559792']
// Actual:   ['+19293243477', '+15135481135', '+17302020063'] (random area codes)

Expected Behavior

Should return phone numbers matching the national_destination_code filter (e.g., 415 area code numbers).

Actual Behavior

Returns random phone numbers from various area codes, completely ignoring the national_destination_code parameter.

Root Cause

The bug is in client.js:458 in the stringifyQuery() method:

stringifyQuery(query) {
    return qs.stringify(query, { arrayFormat: 'comma' });
}

This generates query strings like:

country_code=US&national_destination_code=415

But the Telnyx v2 API requires filter[] notation:

filter[country_code]=US&filter[national_destination_code]=415

The API silently ignores non-filter[] parameters, returning unfiltered results instead of an error.

Proof

Testing the REST API directly:

Without filter[] notation (what SDK sends):

curl "https://api.telnyx.com/v2/available_phone_numbers?country_code=US&national_destination_code=415&limit=3" \
  -H "Authorization: Bearer $TELNYX_API_KEY"
# Returns: +19293243477, +15135481135, +17302020063 (random)

With filter[] notation (what API expects):

curl "https://api.telnyx.com/v2/available_phone_numbers?filter[country_code]=US&filter[national_destination_code]=415&filter[limit]=3" \
  -H "Authorization: Bearer $TELNYX_API_KEY"
# Returns: +14157238134, +14157970282, +14158559792 (correct 415 numbers)

Suggested Fix

Modify stringifyQuery() in client.js to wrap parameters in filter[] notation:

stringifyQuery(query) {
    // Wrap all params in filter[] notation for Telnyx v2 API
    const filtered = {};
    for (const [key, value] of Object.entries(query)) {
        filtered[`filter[${key}]`] = value;
    }
    return qs.stringify(filtered, { arrayFormat: 'comma' });
}

Or use qs nested object support:

stringifyQuery(query) {
    return qs.stringify({ filter: query }, { arrayFormat: 'comma' });
}

Impact

  • Severity: High - Core filtering functionality completely broken
  • Scope: Affects all list endpoints that use query filtering (not just availablePhoneNumbers)
  • User Experience: Silent failure - no errors thrown, incorrect data returned
  • Workaround: Bypass SDK and call REST API directly

Environment

  • SDK Version: 5.20.0
  • Node Version: 24.13.0
  • Platform: macOS (but affects all platforms)

Additional Context

This likely broke when the Telnyx API moved to v2 with the filter[] notation requirement. The SDK documentation shows the correct usage (passing national_destination_code to list()), but the implementation doesn't match the API's expectations.

This is particularly problematic because:

  1. The SDK doesn't throw errors
  2. The documentation suggests the code is correct
  3. Users receive wrong data without knowing why
  4. This affects production applications expecting filtered results

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions