VocalDocscontracts 1.65.0

Estimate a Provider swap over measured usage

POST /v1/analytics/what-if

PropertyValue
Operationcreate_what_if
GroupCall trace and analytics
Scopeusage:read
Route classread
IdempotencyIdempotency-Key accepted: a retry with the same key replays the first answer
AuditNot audited: A read sent as a POST that changes no state and reads no Call content, exempt by ADR 0012 like the dry runs.
Released in1.57.0
Phase 0 hostServed (the hosted api pins 1.65.0)

Estimates what the Organization would have been charged had a substitute Provider and model served the measured quantities of one stage of an Agent's Calls over a window, at the prices in force now (1.57.0). It writes nothing. The answer carries the measured Calls and minutes, the substitute's latency from the Organization's own Turns on it or else Vocal's dated canary measurements, with sample sizes, and whether the Organization could run it. A stage on the Organization's own key shows quantities only. An Agent of another Organization is not found; a substitute equal to the current Provider and model, or a range over 760 days, is refused with validation_failed.

Request

Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the usage:read scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.

curl -X POST "$VOCAL_API/v1/analytics/what-if" \
  -H "Authorization: Bearer $VOCAL_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agt_...",
    "substitution": {
      "stage": "stt",
      "current_provider": "mock",
      "substitute_provider": "mock",
      "substitute_model": "<substitute_model>"
    }
  }'

Parameters

NameInTypeRequiredDescription
idempotency-keyheaderstringnoA client-chosen key, kept 24 hours per Organization, environment and route. A replay returns the stored response.

Request body

Content type application/json, required: WhatIfRequest.

FieldTypeRequiredDescription
agent_idAgentIdyes
agent_versionintegernoOnly the Calls of this version; every version of the Agent when absent.
fromRequestTimestampnoWith window=custom, the start of the range, inclusive (1.57.0).
substitutionWhatIfSubstitutionInputyes
toRequestTimestampnoWith window=custom, the end of the range, exclusive (1.57.0).
windowAnalyticsWindowno

Responses

StatusContent typeShapeError codes
200application/jsonWhatIf
400application/jsonErrorEnvelopeinvalid_request
401application/jsonErrorEnvelopeunauthenticated
403application/jsonErrorEnvelopeforbidden
404application/jsonErrorEnvelopenot_found
422application/jsonErrorEnvelopevalidation_failed
429application/jsonErrorEnveloperate_limited
500application/jsonErrorEnvelopeinternal_error

Fields of the 200 answer

The shape is WhatIf.

FieldTypeRequiredDescription
agent_idAgentIdyes
agent_versioninteger or nullyes
callsintegeryesThe Calls whose quantities were measured.
currency"USD"yes
currentWhatIfSideyes
delta_microsinteger or nullyesThe substitute amount minus the current amount; null when either is null.
eligiblebooleanyes
estimatetrueyes
fromstringyes
ineligible_reasonsarray of WhatIfIneligibleReasonyes
latencyWhatIfLatencyEvidenceyes
minutesnumberyesTheir billable Call minutes.
object"what_if"yes
price_list_versionstringyesThe version of the price list the estimate used; a date in 1.5.0.
stageWhatIfStageyes
substituteWhatIfSideyes
tostringyes