Skip to content

Instantly share code, notes, and snippets.

@prajwal-stha
Last active February 27, 2026 06:58
Show Gist options
  • Select an option

  • Save prajwal-stha/f8cb436cab6968e14c1cc5e12ef804f6 to your computer and use it in GitHub Desktop.

Select an option

Save prajwal-stha/f8cb436cab6968e14c1cc5e12ef804f6 to your computer and use it in GitHub Desktop.
VTMO Filter Integration Guide

VTMO Call & Text Filter Integration (KosherPhone)

1. Purpose

This document defines the full business and integration logic for managing VT Mobile (vtmobile) Call and Text Filters.

This is not just an API reference.
It describes required behavior, enforcement rules, and edge-case handling that must be implemented in the frontend.


2. High-Level Business Model

Each subscription supports:

  • Call Filter
  • Text Filter
  • Two modes:
    • BLACKLIST
    • WHITELIST

Filters allow:

  • Managing individual phone numbers
  • Selecting curated blacklist groups
  • Enforcing plan-based required groups (Rate Plan Bot Code groups)

3. Required Subscription Inputs

Each filter UI requires:

  • subscriberId (VTMO subscriber ID)
  • phone
  • companyId (used to load curated groups)
  • blacklistGroupNames[]
    (Required group names derived from plan rate bot configuration)

Example:

{
  subscriberId: "TSUID-123",
  phone: "7732513541",
  companyId: "10",
  blacklistGroupNames: ["Spam Bots", "Robocalls"]
}

4. API Endpoints

4.1 Load Existing Filter

Call Filter:

GET /api/vtmobile/{subscriberId}/call-filter

Text Filter:

GET /api/vtmobile/{subscriberId}/message-filter

Behavior:

  • If API returns "no filters found" → treat as new filter
  • If response is array → use first item
  • Store FilterId if returned

4.2 Create Filter

POST /api/vtmobile/{subscriberId}/{call-filter|message-filter}

4.3 Update Filter

PUT /api/vtmobile/{subscriberId}/{call-filter|message-filter}/{filterId}

4.4 Load Curated Groups

GET /api/vtmobile/curated-groups?company_id={companyId}

Response:

{
  "status": "success",
  "data": [
    { "id": 1, "name": "Spam Bots" }
  ]
}

4.5 WHITELIST Conflict Check (Mandatory Before Save)

POST /api/vtmobile/curated-groups/check-numbers

Request:

{
  "numbers": ["7732513541"],
  "group_names": ["Spam Bots"]
}

If any result returns:

success: true

Then:

  • Block save
  • Show error:
    "Some numbers exist in blacklist groups. Please remove from blacklist first."

5. Filter Modes

5.1 BLACKLIST Mode

UI:

  • Show Blocked Numbers textarea
  • Show curated groups selector

Validation:

  • Must contain:
    • At least 1 blocked number OR
    • At least 1 selected group

Payload must include:

SelectedGroupIds: [...]

5.2 WHITELIST Mode

UI:

  • Show Allowed Numbers textarea
  • Hide or disable group selector

Validation:

  • Must contain at least 1 number
  • Must run conflict check before save

Payload must always include:

SelectedGroupIds: []

6. CRITICAL BUSINESS RULE

Required Group Enforcement

The biggest issue discovered:

A user could:

  1. Switch to WHITELIST
  2. Remove groups
  3. Switch back to BLACKLIST
  4. Add a single number
  5. Save without required plan-based groups

This is NOT allowed.


Enforcement Requirement

Whenever saving in BLACKLIST mode:

  1. Convert blacklistGroupNames[] into group IDs
    • Match names case-insensitive against curated groups
  2. Merge required group IDs into selected group IDs
  3. Auto re-add required groups if missing
  4. Prevent required groups from being removed in UI
  5. Re-enforce immediately before building payload

This must happen every time before save.

Required groups apply ONLY in BLACKLIST mode.


7. Payload Formats

7.1 Call Filter

{
  "Phone": "7732513541",
  "FilterMode": "BLACKLIST",
  "BlockedNumbers": ["2125551212"],
  "AllowedNumbers": [],
  "SelectedGroupIds": [1, 2]
}

7.2 Text Filter

{
  "Phone": "7732513541",
  "FilterMode": "WHITELIST",
  "BlockedContacts": [],
  "AllowedContacts": ["2125551212"],
  "SelectedGroupIds": []
}

8. Save Decision Logic

On modal open:

  • Call GET endpoint
  • If filter exists → store filterId
  • Else → create mode

On save:

  • If filterId exists → PUT
  • Else → POST

Before save:

  • If BLACKLIST → enforce required groups
  • If WHITELIST → run conflict check

After successful save:

  • Store returned FilterId
  • Show success

9. Edge Cases

  • API may return array → use first item
  • No filter found → treat as create
  • WHITELIST must never send group IDs
  • BLACKLIST can be valid with groups only (no numbers)
  • Required groups must auto-recover if user attempts bypass

10. What Must Never Break

  • Required plan groups must always exist in BLACKLIST
  • WHITELIST cannot silently bypass blacklist groups
  • Switching modes must not permanently drop required groups
  • Saving must always enforce server-safe state
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment