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.
Authentication
Section titled “Authentication”All API requests must include a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_KEY_HEREIf the key is missing, invalid, or of the wrong type, the server will return a 401 Unauthorized or 403 Forbidden response.
Base URL
Section titled “Base URL”https://api.outboundiq.cloud/ani-plannerEndpoints
Section titled “Endpoints”Generate Plan
Section titled “Generate Plan”Computes the ANI recommendation for the authenticated company over a date range.
- Method:
POST - URL:
/generate - Headers:
Authorization: Bearer YOUR_API_KEY_HEREContent-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"] } ] }}Response fields
Section titled “Response fields”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), asYYYY-MM-DD.bizDays— number of weekdays (Mon–Fri) in the range; daily averages are computed against this.dailyDialsTarget— the resolved numeric target (50,75, or100).regionStats[]— one row per region, sorted bydailyDialsAveragedescending: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.dailyDialsAverage—ceil(total dials in region / bizDays).currentAnis— ANIs you currently have for this region (perinventoryMode).proposedAnis— recommended ANI count:ceil(dailyDialsAverage / dailyDialsTarget), with a minimum floor per region.difference—proposedAnis - currentAnis. Positive means you should add numbers; negative means you are over-provisioned.
totalDials,totalContacts,overallContactRate— totals across all regions (overallContactRateis a percentage).totalCurrentAnis,totalProposedAnis,aniDifference— portfolio-wide ANI totals and their difference.missingZipData—trueonly whengroupByis"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.0for US/CA (toll-free appears as a"TF"row inregionStats); ~1% oftotalProposedAnisfor UK.selectedCampaigns[]— the numeric IDs of the outbound campaigns that were included in the analysis. Use theinternalIdentifierfromcampaigns[]to map these back to the identifiers you sent.campaigns[]— the company’s outbound/autodial campaigns with their mapped inbound campaigns. Each entry’sinternalIdentifieris the value to pass in the requestcampaigns/campaignsExcludefilters.
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.
Example
Section titled “Example”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"] }'Country differences
Section titled “Country differences”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", andtollFreeRecommendationis0. Each region has a minimum of 3 proposed ANIs (2 for toll-free). - UK — dials are grouped per area code (
stateholds the area code without its leading zero;regionlists the counties it serves). Each area code has a minimum of 2 proposed ANIs. An additional"Mobile"row aggregates all mobile (07x) volume, andtollFreeRecommendationreturns a non-zero suggestion.