Skip to content

ANI Planner API

The ANI Planner analyzes your recent dial volume and current ANI inventory, then recommends how many ANI numbers you should provision in each geographic region to keep daily dials per number at a healthy level. It returns the same data that powers the ANI Planner screen in the dashboard.

All API requests must include a Bearer token in the Authorization header:

Authorization: Bearer YOUR_API_KEY_HERE

If the key is missing, invalid, or of the wrong type, the server will return a 401 Unauthorized or 403 Forbidden response.

https://api.outboundiq.cloud/ani-planner

Computes the ANI recommendation for the authenticated company over a date range.

  • Method: POST
  • URL: /generate
  • Headers:
    • Authorization: Bearer YOUR_API_KEY_HERE
    • Content-Type: application/json

Body Schema:

type Payload = {
// Date range to analyze, "YYYY-MM-DD". Both optional.
// Defaults to the start of the current month through yesterday.
dateStart?: string;
dateEnd?: string;
// Target maximum dials per ANI per day. Defaults to "BETTER".
// "BEST" → 50 dials/day
// "BETTER" → 75 dials/day
// "GOOD" → 100 dials/day
dailyDialsTarget?: "BEST" | "BETTER" | "GOOD";
// How dial volume is grouped. Defaults to "area_code".
// "area_code" → the prospect's phone area code (who you called)
// "ani" → the area code of the ANI used to place the call
// "zip" → the area code of the prospect's ZIP (US/CA only)
groupBy?: "area_code" | "ani" | "zip";
// Which ANIs to count as "current". Defaults to "managed".
// "managed" → only active, managed numbers
// "all" → all numbers except those removed from the dialer
inventoryMode?: "managed" | "all";
// Optional campaign filters (outbound campaign internal identifiers).
// Provide at most one. Omit both to include every campaign.
// Unknown identifiers return a 400.
campaigns?: string[]; // include only these campaigns
campaignsExclude?: string[]; // include everything except these
};

Body Example:

{
"dateStart": "2026-05-01",
"dateEnd": "2026-05-28",
"dailyDialsTarget": "BETTER",
"groupBy": "area_code",
"inventoryMode": "managed",
"campaigns": ["west-coast-outbound", "east-coast-outbound"]
}

Success Response:

{
"success": true,
"data": {
"country": "us",
"dateStart": "2026-05-01",
"dateEnd": "2026-05-28",
"bizDays": 20,
"dailyDialsTarget": 75,
"groupBy": "area_code",
"inventoryMode": "managed",
"regionStats": [
{
"region": "Los Angeles",
"state": "CA",
"areaCodes": ["213", "310"],
"dailyDialsAverage": 412,
"currentAnis": 4,
"proposedAnis": 6,
"difference": 2
}
],
"totalDials": 12345,
"totalContacts": 3456,
"overallContactRate": 28.0,
"totalCurrentAnis": 40,
"totalProposedAnis": 58,
"aniDifference": 18,
"missingZipData": false,
"tollFreeRecommendation": 0,
"selectedCampaigns": [101, 102],
"campaigns": [
{
"id": 101,
"name": "West Coast Outbound",
"internalIdentifier": "wc-out",
"campaignType": "outbound",
"inboundCampaignIds": [205],
"inboundCampaignNames": ["West Coast Inbound"]
}
]
}
}
  • country"us", "ca", or "uk". Detected automatically from the company’s dialer; it determines how regions are grouped (see Country differences).
  • dateStart / dateEnd — the effective range that was analyzed (after applying defaults), as YYYY-MM-DD.
  • bizDays — number of weekdays (Mon–Fri) in the range; daily averages are computed against this.
  • dailyDialsTarget — the resolved numeric target (50, 75, or 100).
  • regionStats[] — one row per region, sorted by dailyDialsAverage descending:
    • region — region/city name (US/CA) or the comma-joined counties served by the area code (UK).
    • state — state abbreviation (US/CA), "TF" for toll-free, or the area code (UK).
    • areaCodes[] — the area codes rolled up into this region.
    • dailyDialsAverageceil(total dials in region / bizDays).
    • currentAnis — ANIs you currently have for this region (per inventoryMode).
    • proposedAnis — recommended ANI count: ceil(dailyDialsAverage / dailyDialsTarget), with a minimum floor per region.
    • differenceproposedAnis - currentAnis. Positive means you should add numbers; negative means you are over-provisioned.
  • totalDials, totalContacts, overallContactRate — totals across all regions (overallContactRate is a percentage).
  • totalCurrentAnis, totalProposedAnis, aniDifference — portfolio-wide ANI totals and their difference.
  • missingZipDatatrue only when groupBy is "zip" but no ZIP area-code data was found despite dials existing (i.e. ZIP enrichment is missing for this company).
  • tollFreeRecommendation — recommended toll-free ANI count. 0 for US/CA (toll-free appears as a "TF" row in regionStats); ~1% of totalProposedAnis for UK.
  • selectedCampaigns[] — the numeric IDs of the outbound campaigns that were included in the analysis. Use the internalIdentifier from campaigns[] to map these back to the identifiers you sent.
  • campaigns[] — the company’s outbound/autodial campaigns with their mapped inbound campaigns. Each entry’s internalIdentifier is the value to pass in the request campaigns / campaignsExclude filters.

Failure Response:

{
"success": false,
"message": "Invalid API key"
}

Validation errors (for example an unknown dailyDialsTarget, a malformed date, or a campaign identifier that does not exist for the company) return 400 Bad Request.

Terminal window
curl -X POST \
https://api.outboundiq.cloud/ani-planner/generate \
-H 'Authorization: Bearer YOUR_API_KEY_HERE' \
-H 'Content-Type: application/json' \
-d '{
"dateStart": "2026-05-01",
"dateEnd": "2026-05-28",
"dailyDialsTarget": "BETTER",
"groupBy": "area_code",
"inventoryMode": "managed",
"campaigns": ["west-coast-outbound", "east-coast-outbound"]
}'

The shape of regionStats adapts to the company’s country, which is detected automatically from the dialer:

  • US / CA — dials are grouped into state/region rows. Toll-free traffic is reported as a single row with state: "TF", and tollFreeRecommendation is 0. Each region has a minimum of 3 proposed ANIs (2 for toll-free).
  • UK — dials are grouped per area code (state holds the area code without its leading zero; region lists the counties it serves). Each area code has a minimum of 2 proposed ANIs. An additional "Mobile" row aggregates all mobile (07x) volume, and tollFreeRecommendation returns a non-zero suggestion.