Skip to content
Markets open

Switch API reference

Switch: rating

Rate decks, sell decks and sell rates: what you pay and what you charge.

38 operationsBase URL https://packetexchange.io/api/v1Postman collection

BrowseSwitch: rating

Analyse the cost and configured margin of a destination

GET/api/v1/switch/cost-analysis

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Resolves the route a call from this customer trunk would take (the same resolver the switch uses), prices every eligible supplier with its own increment and deck, and estimates margin on a call of seconds length. Read-only: no call record, balance or capacity is touched. This is an estimate; see /margin/realised for what was actually earned.

Parameters

NameInTypeDescription
destinationrequiredquerystring-
originquerystring-
customerIdquerystring (uuid)-
customerTrunkIdquerystring (uuid)-
secondsqueryintegerReference call length for the margin estimate

Response 200

FieldTypeDescription
datarequiredobject-
atrequireddata.atstring (date-time)ISO-8601 timestamp (UTC)
inputrequireddata.inputobjectThe destination, routed number, origin, customer, trunk and reference call length used
basisrequireddata.basisobject-
resolvedrequireddata.basis.resolvedboolean-
detailrequireddata.basis.detailstring-
routingKindrequireddata.basis.routingKindstring-One of fixed, group, dialplan, none
routingNamerequireddata.basis.routingNamestring | null-
selectionModerequireddata.basis.selectionModestring | null-
maxAttemptsrequireddata.basis.maxAttemptsinteger | null-
sellrequireddata.sellobject-
outcomerequireddata.sell.outcomeobject | nullA price, or the reason there is none. Only kind = rated carries a rate.
kindrequireddata.sell.outcome.kindstring-One of rated, no_matching_rate, not_yet_effective, expired, forbidden, rating_failed, not_billable
ratedata.sell.outcome.ratenumberPresent when kind = rated. May legitimately be 0.
matchedPrefixdata.sell.outcome.matchedPrefixstring-
deckVersiondata.sell.outcome.deckVersioninteger | null-
sourcedata.sell.outcome.sourcestring-
destinationdata.sell.outcome.destinationstring-
effectiveFromdata.sell.outcome.effectiveFromstring-
expiredAtdata.sell.outcome.expiredAtstring-
reasondata.sell.outcome.reasonstringWhy it is forbidden or failed
billingRaterequireddata.sell.billingRatenumber | nullUSD as a JSON number (engine output, up to 6 decimal places)
matchedPrefixrequireddata.sell.matchedPrefixstring | null-
billingIncrementrequireddata.sell.billingIncrementstring-
suppliersrequireddata.suppliersobject[]-
vendorTrunkIdrequireddata.suppliers[].vendorTrunkIdstring (uuid) | null-
labelrequireddata.suppliers[].labelstring-
kindrequireddata.suppliers[].kindstring-One of supplier trunk, marketplace route
chainOrdinalrequireddata.suppliers[].chainOrdinalinteger | nullAttempt position in the failover chain; null if past the attempt ceiling
outcomerequireddata.suppliers[].outcomeobject | nullA price, or the reason there is none. Only kind = rated carries a rate.Same fields as SwitchRatingOutcome, shown earlier on this page.
billingRaterequireddata.suppliers[].billingRatenumber | nullUSD as a JSON number (engine output, up to 6 decimal places)
sourcerequireddata.suppliers[].sourcestring-One of supplier deck, trunk default, marketplace listing, unpriced
matchedPrefixrequireddata.suppliers[].matchedPrefixstring | null-
deckIdrequireddata.suppliers[].deckIdstring (uuid) | null-
deckVersionrequireddata.suppliers[].deckVersioninteger | null-
billingIncrementrequireddata.suppliers[].billingIncrementstring-
excludedrequireddata.suppliers[].excludedobject | null-
stagerequireddata.suppliers[].excluded.stagestring-
reasonrequireddata.suppliers[].excluded.reasonstring-
detailrequireddata.suppliers[].excluded.detailstring-
selectedrequireddata.selectedobject | null-
vendorTrunkIdrequireddata.selected.vendorTrunkIdstring (uuid) | null-
labelrequireddata.selected.labelstring-
kindrequireddata.selected.kindstring-One of supplier trunk, marketplace route
chainOrdinalrequireddata.selected.chainOrdinalinteger | nullAttempt position in the failover chain; null if past the attempt ceiling
outcomerequireddata.selected.outcomeobject | nullA price, or the reason there is none. Only kind = rated carries a rate.Same fields as SwitchRatingOutcome, shown earlier on this page.
billingRaterequireddata.selected.billingRatenumber | nullUSD as a JSON number (engine output, up to 6 decimal places)
sourcerequireddata.selected.sourcestring-One of supplier deck, trunk default, marketplace listing, unpriced
matchedPrefixrequireddata.selected.matchedPrefixstring | null-
deckIdrequireddata.selected.deckIdstring (uuid) | null-
deckVersionrequireddata.selected.deckVersioninteger | null-
billingIncrementrequireddata.selected.billingIncrementstring-
excludedrequireddata.selected.excludedobject | null-
stagerequireddata.selected.excluded.stagestring-
reasonrequireddata.selected.excluded.reasonstring-
detailrequireddata.selected.excluded.detailstring-
configuredMarginrequireddata.configuredMarginobject-
kindrequireddata.configuredMargin.kindstring-One of configured_estimate
perMinuterequireddata.configuredMargin.perMinutenumber | nullUSD as a JSON number (engine output, up to 6 decimal places)
perMinutePctrequireddata.configuredMargin.perMinutePctnumber | null-
referenceCallrequireddata.configuredMargin.referenceCallobject | nullRevenue, cost and margin of a call of the reference length, increment-aware (JSON numbers)
rangerequireddata.configuredMargin.rangeobject | null-
explainrequireddata.configuredMargin.explainobject[]-
labelrequireddata.configuredMargin.explain[].labelstring-
valuerequireddata.configuredMargin.explain[].valuestring-
notedata.configuredMargin.explain[].notestring-
sourcedata.configuredMargin.explain[].sourcestring-
traceIdrequireddata.traceIdstring (uuid)The route trace this analysis ran on
verdictrequireddata.verdictobject-
sideEffectsrequireddata.sideEffectsobject-
createdCdrrequireddata.sideEffects.createdCdrboolean-One of false
movedBalancerequireddata.sideEffects.movedBalanceboolean-One of false
consumedCapacityrequireddata.sideEffects.consumedCapacityboolean-One of false

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

List the suppliers that can carry a customer's traffic

GET/api/v1/switch/cost-analysis/suppliers

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Destination-independent: which supplier trunks the customer's routing makes eligible, and whether each can be priced. Name a customer or a customer trunk. When a customer has several trunks with different routing, ambiguous says so.

Parameters

NameInTypeDescription
customerIdquerystring (uuid)-
customerTrunkIdquerystring (uuid)-

Response 200

FieldTypeDescription
datarequiredobject-
suppliersrequireddata.suppliersobject[]-
vendorTrunkIdrequireddata.suppliers[].vendorTrunkIdstring (uuid)-
labelrequireddata.suppliers[].labelstring-
statusrequireddata.suppliers[].statusstring-
viarequireddata.suppliers[].viaobject[]-
sourcerequireddata.suppliers[].via[].sourcestring-One of fixed target, route group, failover group, dialplan rule
groupIdrequireddata.suppliers[].via[].groupIdstring (uuid) | null-
groupNamerequireddata.suppliers[].via[].groupNamestring | null-
prefixrequireddata.suppliers[].via[].prefixstring | null-
priorityrequireddata.suppliers[].via[].priorityinteger | null-
defaultRatePerUnitrequireddata.suppliers[].defaultRatePerUnitmoney | nullUS dollars as a decimal string with exactly 6 decimal places, e.g. "0.012500". Do money arithmetic with a decimal type, not floating point. USD as a decimal string with exactly 6 places, e.g. "0.012500".
activeRateRowsrequireddata.suppliers[].activeRateRowsinteger-
unpricedrequireddata.suppliers[].unpricedbooleanTrue when the trunk has no rates and no default: calls to it cannot be costed
billingIncrementrequireddata.suppliers[].billingIncrementstring-
routingrequireddata.routingobject-
kindrequireddata.routing.kindstring-One of fixed, group, dialplan, none
namerequireddata.routing.namestring | null-
selectionModerequireddata.routing.selectionModestring | null-
maxAttemptsrequireddata.routing.maxAttemptsinteger | null-
trunkIdsrequireddata.routing.trunkIdsstring (uuid)[]-
ambiguousrequireddata.ambiguousstring | null-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Get realised margin over a period

GET/api/v1/switch/margin/realised

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

What customers were actually charged minus what suppliers actually cost, including the estimated cost of answered attempts that did not win. All amounts are JSON numbers in USD. exposure lists what makes the figure less reliable (for example sessions billed with no supplier cost).

Parameters

NameInTypeDescription
fromquerystringISO timestamp; default 24 hours before to
toquerystringISO timestamp; default now
customerIdquerystring (uuid)-
customerTrunkIdquerystring (uuid)-
supplierTrunkIdquerystring (uuid)-
kindquerystringvoice (default) or all, which includes SMSOne of voice, all

Response 200

FieldTypeDescription
datarequiredobject-
kindrequireddata.kindstring-One of realised_actual
windowrequireddata.windowobject-
fromrequireddata.window.fromstring-
torequireddata.window.tostring-
labelrequireddata.window.labelstring-
basisrequireddata.basisobject-
answerrequireddata.answerobject-
revenuerequireddata.revenueobject-
customerChargesrequireddata.revenue.customerChargesnumberUSD as a JSON number (engine output, up to 6 decimal places)
platformFeerequireddata.revenue.platformFeenumberUSD as a JSON number (engine output, up to 6 decimal places)
feeCertaintyrequireddata.revenue.feeCertaintystring-One of exact, upper_bound
operatorRevenuerequireddata.revenue.operatorRevenuenumberUSD as a JSON number (engine output, up to 6 decimal places)
costrequireddata.costobject-
bookedrequireddata.cost.bookednumberUSD as a JSON number (engine output, up to 6 decimal places)
unbookedAttemptCostrequireddata.cost.unbookedAttemptCostnumberUSD as a JSON number (engine output, up to 6 decimal places)
unbookedAttemptsrequireddata.cost.unbookedAttemptsinteger-
totalrequireddata.cost.totalnumberUSD as a JSON number (engine output, up to 6 decimal places)
grossrequireddata.grossnumberUSD as a JSON number (engine output, up to 6 decimal places)
grossPctrequireddata.grossPctnumber | null-
exposurerequireddata.exposureobject-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

List per-call realised margin

GET/api/v1/switch/margin/realised/sessions

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

One row per session with its charge and every supplier attempt beneath it. Paged (limit up to 200).

Parameters

NameInTypeDescription
fromquerystringISO timestamp; default 24 hours before to
toquerystringISO timestamp; default now
customerIdquerystring (uuid)-
customerTrunkIdquerystring (uuid)-
supplierTrunkIdquerystring (uuid)-
kindquerystringvoice (default) or all, which includes SMSOne of voice, all
negativeOnlyquerybooleanOnly sessions that lost money
failoverOnlyquerybooleanOnly sessions that needed more than one attempt
limitqueryinteger-
offsetqueryinteger-

Response 200

FieldTypeDescription
datarequiredobject-
rowsrequireddata.rowsobject[]-
sessionKeyrequireddata.rows[].sessionKeystring-
callUuidrequireddata.rows[].callUuidstring | null-
atrequireddata.rows[].atstring (date-time)ISO-8601 timestamp (UTC)
destinationrequireddata.rows[].destinationstring | null-
destinationNamerequireddata.rows[].destinationNamestring | null-
customerTrunkIdrequireddata.rows[].customerTrunkIdstring (uuid) | null-
statusrequireddata.rows[].statusstring | null-
durationSecondsrequireddata.rows[].durationSecondsinteger-
billedSecondsrequireddata.rows[].billedSecondsinteger | null-
billingIncrementrequireddata.rows[].billingIncrementstring | null-
sellRaterequireddata.rows[].sellRatenumber | nullUSD as a JSON number (engine output, up to 6 decimal places)
chargerequireddata.rows[].chargenumberUSD as a JSON number (engine output, up to 6 decimal places)
bookedCostrequireddata.rows[].bookedCostnumberUSD as a JSON number (engine output, up to 6 decimal places)
attemptsrequireddata.rows[].attemptsobject[]-
ordinalrequireddata.rows[].attempts[].ordinalinteger-
supplierrequireddata.rows[].attempts[].supplierstring | null-
vendorTrunkIdrequireddata.rows[].attempts[].vendorTrunkIdstring (uuid) | null-
outcomerequireddata.rows[].attempts[].outcomestring-
sipStatusrequireddata.rows[].attempts[].sipStatusinteger | null-
wonrequireddata.rows[].attempts[].wonboolean-
answeredSecondsrequireddata.rows[].attempts[].answeredSecondsinteger | null-
buyRaterequireddata.rows[].attempts[].buyRatenumber | nullUSD as a JSON number (engine output, up to 6 decimal places)
costBasisrequireddata.rows[].attempts[].costBasisstring-One of booked, derived, none
derivedCostrequireddata.rows[].attempts[].derivedCostnumber | nullUSD as a JSON number (engine output, up to 6 decimal places)
attemptCostrequireddata.rows[].attemptCostnumberUSD as a JSON number (engine output, up to 6 decimal places)
marginrequireddata.rows[].marginnumberUSD as a JSON number (engine output, up to 6 decimal places)
flagsrequireddata.rows[].flagsstring[]-
totalrequireddata.totalinteger-
limitrequireddata.limitinteger-
offsetrequireddata.offsetinteger-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Get the realised margin of one call

GET/api/v1/switch/margin/realised/sessions/{callUuid}

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Parameters

NameInTypeDescription
callUuidrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchSessionMargin, shown earlier on this page.

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

List supplier rate decks

GET/api/v1/switch/rate-decks

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Newest first, up to 500, with row counts and the supplier trunks each deck prices.

Parameters

NameInTypeDescription
supplierIdquerystring (uuid)Only decks from this provider
trunkIdquerystring (uuid)Only decks that price this supplier trunk
statusquerystring-One of draft, uploaded, invalid, validated, pending_approval, scheduled, active, expired, rolled_back

Response 200

FieldTypeDescription
datarequiredobject-
decksrequireddata.decksobject[]-
idrequireddata.decks[].idstring (uuid)-
supplierIdrequireddata.decks[].supplierIdstring (uuid) | nullThe provider who sent it; null for a deck recorded before its provider was
namerequireddata.decks[].namestring-
currencyrequireddata.decks[].currencystring-max 3 chars
versionrequireddata.decks[].versioninteger-
statusrequireddata.decks[].statusstring-One of draft, uploaded, invalid, validated, pending_approval, scheduled, active, expired, rolled_back
effectiveFromrequireddata.decks[].effectiveFromstring (date-time) | nullISO-8601 timestamp (UTC)
expiresAtrequireddata.decks[].expiresAtstring (date-time) | nullISO-8601 timestamp (UTC)
sourcerequireddata.decks[].sourcestring | null-One of portal, csv, api, email, sftp
sourceRefrequireddata.decks[].sourceRefstring | null-
approvedAtrequireddata.decks[].approvedAtstring (date-time) | nullISO-8601 timestamp (UTC)
validationrequireddata.decks[].validationobject | nullThe last validation result; null before the deck is validated
checkedAtrequireddata.decks[].validation.checkedAtstring-
rowsrequireddata.decks[].validation.rowsinteger-
destinationsrequireddata.decks[].validation.destinationsinteger-
errorsrequireddata.decks[].validation.errorsobject[]-
warningsrequireddata.decks[].validation.warningsobject[]-
maxIncreasePctdata.decks[].validation.maxIncreasePctnumber-
supersedesIdrequireddata.decks[].supersedesIdstring (uuid) | null-
rolledBackAtrequireddata.decks[].rolledBackAtstring (date-time) | nullISO-8601 timestamp (UTC)
notesrequireddata.decks[].notesstring | null-
createdAtrequireddata.decks[].createdAtstring (date-time)ISO-8601 timestamp (UTC)
updatedAtrequireddata.decks[].updatedAtstring (date-time)ISO-8601 timestamp (UTC)
rowCountrequireddata.decks[].rowCountinteger-
trunksrequireddata.decks[].trunksobject[]Supplier trunks the deck prices
idrequireddata.decks[].trunks[].idstring (uuid)-
labelrequireddata.decks[].trunks[].labelstring-
mutablerequireddata.decks[].mutablebooleanWhether rows can still be edited

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Create a supplier rate deck

POST/api/v1/switch/rate-decks

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Creates a draft deck (version 1, or the next version of an existing name for that provider). Load rows with PUT /rate-decks/{id}/rows.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (application/json)

FieldTypeDescription
supplierIdstring (uuid) | null-
namerequiredstring-max 160 chars
currencystring-max 3 chars
sourcestring | null-One of portal, csv, api, email, sftp
sourceRefstring | null-max 500 chars
effectiveFromstring | null-max 40 chars
expiresAtstring | null-max 40 chars
trunkIdsstring (uuid)[]-
notesstring | null-max 4000 chars

Response 201

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Get a supplier rate deck

GET/api/v1/switch/rate-decks/{id}

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

The deck, its trunks and row count. Rows themselves are read from the supplier trunk rates.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Delete a rate deck

DELETE/api/v1/switch/rate-decks/{id}

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Deletes the deck and its rows. An active deck must be rolled back first.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobject-
deletedrequireddata.deletedboolean-One of true

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

List every version of a rate deck

GET/api/v1/switch/rate-decks/{id}/history

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

All versions sharing this deck's name and provider, newest first.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobject-
namerequireddata.namestring-
versionsrequireddata.versionsobject[]-
idrequireddata.versions[].idstring (uuid)-
supplierIdrequireddata.versions[].supplierIdstring (uuid) | nullThe provider who sent it; null for a deck recorded before its provider was
namerequireddata.versions[].namestring-
currencyrequireddata.versions[].currencystring-max 3 chars
versionrequireddata.versions[].versioninteger-
statusrequireddata.versions[].statusstring-One of draft, uploaded, invalid, validated, pending_approval, scheduled, active, expired, rolled_back
effectiveFromrequireddata.versions[].effectiveFromstring (date-time) | nullISO-8601 timestamp (UTC)
expiresAtrequireddata.versions[].expiresAtstring (date-time) | nullISO-8601 timestamp (UTC)
sourcerequireddata.versions[].sourcestring | null-One of portal, csv, api, email, sftp
sourceRefrequireddata.versions[].sourceRefstring | null-
approvedAtrequireddata.versions[].approvedAtstring (date-time) | nullISO-8601 timestamp (UTC)
validationrequireddata.versions[].validationobject | nullThe last validation result; null before the deck is validated
checkedAtrequireddata.versions[].validation.checkedAtstring-
rowsrequireddata.versions[].validation.rowsinteger-
destinationsrequireddata.versions[].validation.destinationsinteger-
errorsrequireddata.versions[].validation.errorsobject[]-
warningsrequireddata.versions[].validation.warningsobject[]-
maxIncreasePctdata.versions[].validation.maxIncreasePctnumber-
supersedesIdrequireddata.versions[].supersedesIdstring (uuid) | null-
rolledBackAtrequireddata.versions[].rolledBackAtstring (date-time) | nullISO-8601 timestamp (UTC)
notesrequireddata.versions[].notesstring | null-
createdAtrequireddata.versions[].createdAtstring (date-time)ISO-8601 timestamp (UTC)
updatedAtrequireddata.versions[].updatedAtstring (date-time)ISO-8601 timestamp (UTC)

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Compare a rate deck with the prices in force

GET/api/v1/switch/rate-decks/{id}/diff

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Per supplier trunk the deck covers, what activating it would change against the rows pricing calls now. Writes nothing.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobject-
deckIdrequireddata.deckIdstring (uuid)-
namerequireddata.namestring-
versionrequireddata.versioninteger-
statusrequireddata.statusstring-One of draft, uploaded, invalid, validated, pending_approval, scheduled, active, expired, rolled_back
effectiveFromrequireddata.effectiveFromstring (date-time) | nullISO-8601 timestamp (UTC)
trunksrequireddata.trunksobject[]-
trunkIdrequireddata.trunks[].trunkIdstring (uuid)-
labelrequireddata.trunks[].labelstring-
diffrequireddata.trunks[].diffobjectWhat a change does to live pricing, with the biggest movers
removalModerequireddata.trunks[].diff.removalModestring-One of merge, replace
changeModerequireddata.trunks[].diff.changeModestring-One of amendment, full_replacement
liverequireddata.trunks[].diff.liveintegerPrefixes priced on the live deck now
incomingrequireddata.trunks[].diff.incomingintegerPrefixes the new rows price
addedrequireddata.trunks[].diff.addedinteger-
changedrequireddata.trunks[].diff.changedinteger-
rateChangedrequireddata.trunks[].diff.rateChangedinteger-
incrementOnlyrequireddata.trunks[].diff.incrementOnlyintegerChanged rows where only the billing increment moved
unchangedrequireddata.trunks[].diff.unchangedinteger-
removedrequireddata.trunks[].diff.removedintegerLive prefixes the new rows do not mention
originScopedrequireddata.trunks[].originScopedinteger-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Set which supplier trunks a rate deck prices

PUT/api/v1/switch/rate-decks/{id}/trunks

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Request body (application/json)

FieldTypeDescription
trunkIdsrequiredstring (uuid)[]-

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Replace the rows of a draft rate deck

PUT/api/v1/switch/rate-decks/{id}/rows

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Up to 200,000 rows, replacing whatever the deck held. Rows are stored pending and price nothing until the deck is activated. Validation runs straight after, and the validated deck is returned. Rows can only be changed while the deck is draft, uploaded, invalid or validated (mutable: true); an active deck is changed by opening a new version.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Request body (application/json)

FieldTypeDescription
rowsrequiredobject[]-
prefixrequiredrows[].prefixstring-max 24 chars
raterequiredrows[].ratenumber | stringPrice per minute; a number or a decimal string. Blank is refused, 0 is a real price.
originrows[].originstringCaller-origin prefix; omit for any originmax 24 chars
destinationNamerows[].destinationNamestring | null-max 96 chars
countryrows[].countrystring | null-max 64 chars
mccrows[].mccstring | null-max 8 chars
mncrows[].mncstring | null-max 8 chars
jurisdictionrows[].jurisdictionstring | null-max 16 chars
connectionFeerows[].connectionFeenumber | string | null-
minChargedSecondsrows[].minChargedSecondsinteger | null-min 0
billingIncrementrows[].billingIncrementstring | null-max 10 chars
effectiveFromrows[].effectiveFromstring | null-max 40 chars
endDaterows[].endDatestring | null-max 40 chars

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Open a new draft version of a rate deck

POST/api/v1/switch/rate-decks/{id}/versions

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Copies this deck's rows and trunks into version n+1 as a draft, so an active deck can be repriced without editing it in place.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 201

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Validate a rate deck

POST/api/v1/switch/rate-decks/{id}/validate

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Checks the rows (missing prices, duplicate prefixes, increases) and stores the result on the deck. A deck with errors becomes invalid and cannot be activated.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Submit a rate deck for approval

POST/api/v1/switch/rate-decks/{id}/submit

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Approve a rate deck, now or from a future date

POST/api/v1/switch/rate-decks/{id}/approve

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

With no effectiveFrom (or a past one) the deck is activated immediately. A future effectiveFrom schedules it and emits the cost_rate.scheduled webhook.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Request body (application/json)

FieldTypeDescription
effectiveFromstring | null-max 40 chars

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Activate a rate deck

POST/api/v1/switch/rate-decks/{id}/activate

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Makes the deck's rows price calls on its trunks from now on and supersedes the deck they replace. Exactly one deck is active per trunk.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchRateDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Roll back an active rate deck

POST/api/v1/switch/rate-decks/{id}/rollback

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Withdraws the deck and restores the one it superseded (named in restoredDeckId). Emits the cost_rate.rolled_back webhook.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobject-
idrequireddata.idstring (uuid)-
supplierIdrequireddata.supplierIdstring (uuid) | nullThe provider who sent it; null for a deck recorded before its provider was
namerequireddata.namestring-
currencyrequireddata.currencystring-max 3 chars
versionrequireddata.versioninteger-
statusrequireddata.statusstring-One of draft, uploaded, invalid, validated, pending_approval, scheduled, active, expired, rolled_back
effectiveFromrequireddata.effectiveFromstring (date-time) | nullISO-8601 timestamp (UTC)
expiresAtrequireddata.expiresAtstring (date-time) | nullISO-8601 timestamp (UTC)
sourcerequireddata.sourcestring | null-One of portal, csv, api, email, sftp
sourceRefrequireddata.sourceRefstring | null-
approvedAtrequireddata.approvedAtstring (date-time) | nullISO-8601 timestamp (UTC)
validationrequireddata.validationobject | nullThe last validation result; null before the deck is validated
checkedAtrequireddata.validation.checkedAtstring-
rowsrequireddata.validation.rowsinteger-
destinationsrequireddata.validation.destinationsinteger-
errorsrequireddata.validation.errorsobject[]-
warningsrequireddata.validation.warningsobject[]-
maxIncreasePctdata.validation.maxIncreasePctnumber-
supersedesIdrequireddata.supersedesIdstring (uuid) | null-
rolledBackAtrequireddata.rolledBackAtstring (date-time) | nullISO-8601 timestamp (UTC)
notesrequireddata.notesstring | null-
createdAtrequireddata.createdAtstring (date-time)ISO-8601 timestamp (UTC)
updatedAtrequireddata.updatedAtstring (date-time)ISO-8601 timestamp (UTC)
rowCountrequireddata.rowCountinteger-
trunksrequireddata.trunksobject[]Supplier trunks the deck prices
idrequireddata.trunks[].idstring (uuid)-
labelrequireddata.trunks[].labelstring-
mutablerequireddata.mutablebooleanWhether rows can still be edited
restoredDeckIdrequireddata.restoredDeckIdstring (uuid) | null-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.
  • AlsoSTALE_WRITE

Show what a blank rating or limit field inherits

GET/api/v1/switch/inherited-defaults

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Your operator defaults, the platform fallbacks, and the inheritance chain for each field in plain words.

Response 200

FieldTypeDescription
datarequiredobject-
operatorrequireddata.operatorobject-
markupPctrequireddata.operator.markupPctnumber | null-
dailySpendCaprequireddata.operator.dailySpendCapnumber | nullUSD, a JSON number
maxConcurrentCallsrequireddata.operator.maxConcurrentCallsnumber | null-
billingIncrementrequireddata.operator.billingIncrementstring | null-
platformrequireddata.platformobject-
billingIncrementrequireddata.platform.billingIncrementstring-One of 1/1
maxConcurrentCallsrequireddata.platform.maxConcurrentCallsenum | null-One of null
maxCpsrequireddata.platform.maxCpsenum | null-One of null
chainsrequireddata.chainsobjectField name -> how a blank resolves

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

List sell decks

GET/api/v1/switch/sell-decks

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Every version of every sell deck, with how many customers and trunks each one reaches.

Parameters

NameInTypeDescription
statusquerystring-One of draft, active, superseded, archived

Response 200

FieldTypeDescription
datarequiredobject-
decksrequireddata.decksobject[]-
idrequireddata.decks[].idstring (uuid)-
namerequireddata.decks[].namestring-
versionrequireddata.decks[].versioninteger-
statusrequireddata.decks[].statusstring-One of draft, active, superseded, archived
currencyrequireddata.decks[].currencystring-max 3 chars
isSystemDefaultrequireddata.decks[].isSystemDefaultboolean-
defaultRatePerUnitrequireddata.decks[].defaultRatePerUnitnumber | nullCatch-all price for destinations the deck does not list (a JSON number)
chargingrequireddata.decks[].chargingobject-
minimumDurationSecondsrequireddata.decks[].charging.minimumDurationSecondsinteger | null-
firstIntervalSecondsrequireddata.decks[].charging.firstIntervalSecondsinteger | null-
subsequentIntervalSecondsrequireddata.decks[].charging.subsequentIntervalSecondsinteger | null-
setupFeerequireddata.decks[].charging.setupFeenumber | nullPer-call setup fee (a JSON number)
graceSecondsrequireddata.decks[].charging.graceSecondsinteger | null-
roundingrequireddata.decks[].charging.roundingstring | null-One of up, nearest, down
effectiveFromrequireddata.decks[].effectiveFromstring (date-time) | nullISO-8601 timestamp (UTC)
notesrequireddata.decks[].notesstring | null-
updatedAtrequireddata.decks[].updatedAtstring (date-time)ISO-8601 timestamp (UTC)
activeRatesrequireddata.decks[].activeRatesintegerRows in the deck
customersOnItrequireddata.decks[].customersOnItintegerCustomers whose default deck this is
trunksNamingItrequireddata.decks[].trunksNamingItintegerTrunks that name this deck directly

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Create a sell deck

POST/api/v1/switch/sell-decks

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Creates a draft (version 1, or the next version of an existing name). Load prices, then publish.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (application/json)

FieldTypeDescription
namerequiredstring-max 160 chars
currencystring-max 3 chars
defaultRatePerUnitnumber | string | nullCatch-all price; null or "" clears it
minimumDurationSecondsinteger | null-0 to 3600
firstIntervalSecondsinteger | nullSet together with subsequentIntervalSeconds, or neither1 to 3600
subsequentIntervalSecondsinteger | null-1 to 3600
setupFeenumber | string | null-
graceSecondsinteger | null-0 to 120
roundingstring | null-One of up, nearest, down
notesstring | null-
effectiveFromstring | nullISO timestamp

Response 201

FieldTypeDescription
datarequiredobject-
idrequireddata.idstring (uuid)-
namerequireddata.namestring-
versionrequireddata.versioninteger-
statusrequireddata.statusstring-One of draft, active, superseded, archived
currencyrequireddata.currencystring-max 3 chars
isSystemDefaultrequireddata.isSystemDefaultboolean-
defaultRatePerUnitrequireddata.defaultRatePerUnitnumber | nullCatch-all price for destinations the deck does not list (a JSON number)
chargingrequireddata.chargingobject-
minimumDurationSecondsrequireddata.charging.minimumDurationSecondsinteger | null-
firstIntervalSecondsrequireddata.charging.firstIntervalSecondsinteger | null-
subsequentIntervalSecondsrequireddata.charging.subsequentIntervalSecondsinteger | null-
setupFeerequireddata.charging.setupFeenumber | nullPer-call setup fee (a JSON number)
graceSecondsrequireddata.charging.graceSecondsinteger | null-
roundingrequireddata.charging.roundingstring | null-One of up, nearest, down

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Get a sell deck with its reach and versions

GET/api/v1/switch/sell-decks/{deckId}

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Parameters

NameInTypeDescription
deckIdrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobject-
idrequireddata.idstring (uuid)-
namerequireddata.namestring-
versionrequireddata.versioninteger-
statusrequireddata.statusstring-One of draft, active, superseded, archived
currencyrequireddata.currencystring-max 3 chars
isSystemDefaultrequireddata.isSystemDefaultboolean-
defaultRatePerUnitrequireddata.defaultRatePerUnitnumber | nullCatch-all price for destinations the deck does not list (a JSON number)
chargingrequireddata.chargingobject-
minimumDurationSecondsrequireddata.charging.minimumDurationSecondsinteger | null-
firstIntervalSecondsrequireddata.charging.firstIntervalSecondsinteger | null-
subsequentIntervalSecondsrequireddata.charging.subsequentIntervalSecondsinteger | null-
setupFeerequireddata.charging.setupFeenumber | nullPer-call setup fee (a JSON number)
graceSecondsrequireddata.charging.graceSecondsinteger | null-
roundingrequireddata.charging.roundingstring | null-One of up, nearest, down
effectiveFromrequireddata.effectiveFromstring (date-time) | nullISO-8601 timestamp (UTC)
notesrequireddata.notesstring | null-
supersedesIdrequireddata.supersedesIdstring (uuid) | null-
approvedAtrequireddata.approvedAtstring (date-time) | nullISO-8601 timestamp (UTC)
createdAtrequireddata.createdAtstring (date-time)ISO-8601 timestamp (UTC)
updatedAtrequireddata.updatedAtstring (date-time)ISO-8601 timestamp (UTC)
activeRatesrequireddata.activeRatesinteger-
customersDefaultingToItrequireddata.customersDefaultingToItobject[]-
idrequireddata.customersDefaultingToIt[].idstring (uuid)-
labelrequireddata.customersDefaultingToIt[].labelstring | null-
trunksNamingItrequireddata.trunksNamingItobject[]-
idrequireddata.trunksNamingIt[].idstring (uuid)-
labelrequireddata.trunksNamingIt[].labelstring | null-
subAccountIdrequireddata.trunksNamingIt[].subAccountIdstring (uuid)-
versionsrequireddata.versionsobject[]-
idrequireddata.versions[].idstring (uuid)-
versionrequireddata.versions[].versioninteger-
statusrequireddata.versions[].statusstring-One of draft, active, superseded, archived
effectiveFromrequireddata.versions[].effectiveFromstring (date-time) | nullISO-8601 timestamp (UTC)
createdAtrequireddata.versions[].createdAtstring (date-time)ISO-8601 timestamp (UTC)

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Update a sell deck's name, notes or charging profile

PATCH/api/v1/switch/sell-decks/{deckId}

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Superseded and archived decks cannot change. Changing the charging profile of an ACTIVE deck reprices every trunk on it from the next call, and is logged as a warning.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
deckIdrequiredpathstring-

Request body (application/json)

FieldTypeDescription
namestring-max 160 chars
currencystring-max 3 chars
defaultRatePerUnitnumber | string | nullCatch-all price; null or "" clears it
minimumDurationSecondsinteger | null-0 to 3600
firstIntervalSecondsinteger | nullSet together with subsequentIntervalSeconds, or neither1 to 3600
subsequentIntervalSecondsinteger | null-1 to 3600
setupFeenumber | string | null-
graceSecondsinteger | null-0 to 120
roundingstring | null-One of up, nearest, down
notesstring | null-
effectiveFromstring | nullISO timestamp

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchSellDeck, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

List the prices in a sell deck

GET/api/v1/switch/sell-decks/{deckId}/rates

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Parameters

NameInTypeDescription
deckIdrequiredpathstring-
searchquerystringPrefix search (digits)
limitqueryintegerDefault 100, max 1000
offsetqueryinteger-

Response 200

FieldTypeDescription
datarequiredobject-
rowsrequireddata.rowsobject[]-
idrequireddata.rows[].idstring (uuid)-
deckIdrequireddata.rows[].deckIdstring (uuid)-
prefixrequireddata.rows[].prefixstring-
originPrefixrequireddata.rows[].originPrefixstring"" = any origin
ratePerUnitrequireddata.rows[].ratePerUnitmoneyUSD as a decimal string with exactly 6 places, e.g. "0.012500".
billingIncrementrequireddata.rows[].billingIncrementstring | nullnull = inherit the trunk or customer default
destinationNamerequireddata.rows[].destinationNamestring | null-
createdAtrequireddata.rows[].createdAtstring (date-time)ISO-8601 timestamp (UTC)
updatedAtrequireddata.rows[].updatedAtstring (date-time)ISO-8601 timestamp (UTC)
totalrequireddata.totalinteger-
limitrequireddata.limitinteger-
offsetrequireddata.offsetinteger-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Replace the prices in a draft sell deck

POST/api/v1/switch/sell-decks/{deckId}/rates

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Up to 200,000 rows, replacing whatever the draft held (last row wins per prefix and origin). Published decks are never overwritten; open a new version instead.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
deckIdrequiredpathstring-

Request body (application/json)

FieldTypeDescription
rowsrequiredobject[]-
prefixrequiredrows[].prefixstring-max 24 chars
raterequiredrows[].ratenumber | stringA blank is refused; 0 is a real price
originrows[].originstring | null-max 24 chars
billingIncrementrows[].billingIncrementstring | null"first/subsequent", e.g. 60/60; anything else is stored as inherit

Response 200

FieldTypeDescription
datarequiredobject-
loadedrequireddata.loadedinteger-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Open a new draft version of a sell deck

POST/api/v1/switch/sell-decks/{deckId}/versions

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Copies the deck's charging profile and prices into version n+1 as a draft. Publishing it is what moves prices.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
deckIdrequiredpathstring-

Response 201

FieldTypeDescription
datarequiredobject-
idrequireddata.idstring (uuid)-
namerequireddata.namestring-
versionrequireddata.versioninteger-
statusrequireddata.statusstring-One of draft, active, superseded, archived
currencyrequireddata.currencystring-max 3 chars
isSystemDefaultrequireddata.isSystemDefaultboolean-
defaultRatePerUnitrequireddata.defaultRatePerUnitnumber | nullCatch-all price for destinations the deck does not list (a JSON number)
chargingrequireddata.chargingobject-
minimumDurationSecondsrequireddata.charging.minimumDurationSecondsinteger | null-
firstIntervalSecondsrequireddata.charging.firstIntervalSecondsinteger | null-
subsequentIntervalSecondsrequireddata.charging.subsequentIntervalSecondsinteger | null-
setupFeerequireddata.charging.setupFeenumber | nullPer-call setup fee (a JSON number)
graceSecondsrequireddata.charging.graceSecondsinteger | null-
roundingrequireddata.charging.roundingstring | null-One of up, nearest, down
copiedRatesrequireddata.copiedRatesinteger-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Publish a sell deck (preview first, then confirm)

POST/api/v1/switch/sell-decks/{deckId}/publish

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Without confirm: true this only reports whose prices would change and writes nothing. With it, the deck becomes active, the previous version is superseded, and its prices are written onto every trunk that resolves to it, from the next call onward.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
deckIdrequiredpathstring-

Request body (application/json)

FieldTypeDescription
confirmboolean-

Response 200

FieldTypeDescription
datarequiredobject-
publisheddata.publishedboolean-One of true
wouldChangedata.wouldChangeobject-
ratesrequireddata.wouldChange.ratesinteger-
trunksrequireddata.wouldChange.trunksinteger-
messagerequireddata.wouldChange.messagestring-
trunksdata.trunksinteger-
rowsWrittendata.rowsWritteninteger-
rowsSupersededdata.rowsSupersededinteger-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Set or clear the system default sell deck

POST/api/v1/switch/sell-decks/system-default

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

The deck used by trunks set to "system default". Only an active deck qualifies; send deckId: null to clear it.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (application/json)

FieldTypeDescription
deckIdstring (uuid) | null-

Response 200

FieldTypeDescription
datarequiredobject-
systemDefaultDeckIdrequireddata.systemDefaultDeckIdstring (uuid) | null-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Look up the buy and sell price for a destination

GET/api/v1/switch/rate-lookup

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Read-only. The buy side needs a supplier trunkId; the sell side is resolved for the customer or customer trunk named (or your own sell rates). Each side is a rating outcome, so "no matching rate" is distinguishable from a price of 0. margin is present only when both sides are rated.

Parameters

NameInTypeDescription
destinationrequiredquerystring-
trunkIdquerystring (uuid)Supplier trunk for the buy side
customerIdquerystring (uuid)-
customerTrunkIdquerystring (uuid)-
originquerystringCaller number, for origin-based rates

Response 200

FieldTypeDescription
datarequiredobject-
destinationrequireddata.destinationstring-
originrequireddata.originstring | null-
buyrequireddata.buyobject | nullnull when no trunkId was givenSame fields as SwitchRatingOutcome, shown earlier on this page.
sellrequireddata.sellobjectA price, or the reason there is none. Only kind = rated carries a rate.Same fields as SwitchRatingOutcome, shown earlier on this page.
marginrequireddata.marginnumber | nullsell minus buy per minute, a JSON number; null unless both are rated
atrequireddata.atstring (date-time)ISO-8601 timestamp (UTC)

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

List your operator sell rates

GET/api/v1/switch/sell-rates

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

The operator-wide A-Z sell rates, by prefix.

Parameters

NameInTypeDescription
searchquerystringPrefix search (digits)
limitqueryintegerDefault 100, max 1000
offsetqueryinteger-

Response 200

FieldTypeDescription
datarequiredobject-
rowsrequireddata.rowsobject[]-
idrequireddata.rows[].idstring (uuid)-
prefixrequireddata.rows[].prefixstring-
originPrefixrequireddata.rows[].originPrefixstring"" = any origin
ratePerUnitrequireddata.rows[].ratePerUnitmoneyUSD as a decimal string with exactly 6 places, e.g. "0.012500".
billingIncrementrequireddata.rows[].billingIncrementstring | nullnull = inherit the trunk default
createdAtrequireddata.rows[].createdAtstring (date-time)ISO-8601 timestamp (UTC)
updatedAtrequireddata.rows[].updatedAtstring (date-time)ISO-8601 timestamp (UTC)
totalrequireddata.totalinteger-
limitrequireddata.limitinteger-
offsetrequireddata.offsetinteger-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Add or update one operator sell rate

POST/api/v1/switch/sell-rates

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Upserts by prefix and origin. Emits the sell_rate.changed webhook.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (application/json)

FieldTypeDescription
prefixrequiredstring-max 24 chars
raterequirednumberPrice per minute, as a JSON numbermin 0
originstring-max 24 chars
billingIncrementstringe.g. 60/60 or 1/1; omit to inherit the trunk defaultmax 10 chars

Response 201

FieldTypeDescription
datarequiredobjectSame fields as SwitchSellRate, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Add or update operator sell rates in bulk

POST/api/v1/switch/sell-rates/bulk

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Up to 50,000 rows in one transaction; the last row wins per prefix and origin. Emits one sell_rate.changed webhook.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (application/json)

FieldTypeDescription
rowsrequiredobject[]-
prefixrequiredrows[].prefixstring-max 24 chars
raterequiredrows[].ratenumberPrice per minute, as a JSON numbermin 0
originrows[].originstring-max 24 chars
billingIncrementrows[].billingIncrementstringe.g. 60/60 or 1/1; omit to inherit the trunk defaultmax 10 chars

Response 200

FieldTypeDescription
datarequiredobject-
appliedrequireddata.appliedinteger-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Delete an operator sell rate

DELETE/api/v1/switch/sell-rates/{id}

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Parameters

NameInTypeDescription
idrequiredpathstring-

Response 200

FieldTypeDescription
datarequiredobject-
deletedrequireddata.deletedboolean-One of true

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 404NOT_FOUND: no such resource on your account.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Clear operator sell rates

POST/api/v1/switch/sell-rates/clear

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Deletes the listed prefixes, or EVERY operator sell rate when prefixes is omitted.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (application/json)

FieldTypeDescription
prefixesstring[]-

Response 200

FieldTypeDescription
datarequiredobject-
deletedrequireddata.deletedinteger-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Read a rate sheet and propose a column mapping

POST/api/v1/switch/rate-decks/parse

Access
API key. Scoped keys need switch:manage.
Rate limit
10 requests per minute

Step 1 of the guided import into any switch deck (your own sell deck, a supplier trunk or a customer trunk). Returns the detected columns, a sample and warnings. Writes nothing.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (multipart/form-data)

FieldTypeDescription
targetKindrequiredstring-One of operator, supplier, customer
targetIdstring (uuid)-
targetTrunkIdstring (uuid)-
defaultIncrementstring-
changeModestring-One of amendment, full_replacement
effectiveFromstring (date-time)-
timezonestring-max 64 chars
fxRatestringUnits of USD per 1 unit of the sheet currency; required to apply a non-USD sheet
replacestringLegacy form of changeMode=full_replacementOne of true, false
mappingstringThe confirmed column mapping from the parse step, as JSON text
filerequiredstringThe rate sheet (CSV or XLSX), sent LAST

Response 200

FieldTypeDescription
datarequiredobject-
targetLabelrequireddata.targetLabelstring-
mappingrequireddata.mappingobjectDetected column mapping; send it back (as JSON) on diff and apply
rawSamplerequireddata.rawSampleany[][]The first 8 raw rows
previewRowsrequireddata.previewRowsobject[]Up to 50 parsed rows
rowCountrequireddata.rowCountinteger-
warningsrequireddata.warningsobject[]-
currencyrequireddata.currencystring-
summaryrequireddata.summaryobject-
overLimitrequireddata.overLimitboolean-
maxRowsrequireddata.maxRowsinteger-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Preview what a rate sheet would change

POST/api/v1/switch/rate-decks/diff

Access
API key. Scoped keys need switch:manage.
Rate limit
100 requests per second (the default)

Dry run: compares the sheet with the target deck's live rows and reports added, changed and removed prefixes. changeMode decides whether omitted prefixes stop pricing. Writes nothing.

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (multipart/form-data)

FieldTypeDescription
targetKindrequiredstring-One of operator, supplier, customer
targetIdstring (uuid)-
targetTrunkIdstring (uuid)-
defaultIncrementstring-
changeModestring-One of amendment, full_replacement
effectiveFromstring (date-time)-
timezonestring-max 64 chars
fxRatestringUnits of USD per 1 unit of the sheet currency; required to apply a non-USD sheet
replacestringLegacy form of changeMode=full_replacementOne of true, false
mappingstringThe confirmed column mapping from the parse step, as JSON text
filerequiredstringThe rate sheet (CSV or XLSX), sent LAST

Response 200

FieldTypeDescription
datarequiredobject-
targetLabelrequireddata.targetLabelstring-
rowCountdata.rowCountinteger-
currencyrequireddata.currencystring-
warningsrequireddata.warningsobject[]-
diffdata.diffobjectWhat a change does to live pricing, with the biggest moversSame fields as SwitchRateDeckDiff, shown earlier on this page.
applieddata.appliedintegerRows written (apply) or queued (scheduled apply)
replaceddata.replacedboolean-
scheduleddata.scheduledbooleanPresent when a future effectiveFrom queued the sheetOne of true
effectiveFromdata.effectiveFromstring-
originScopeddata.originScopedintegerOrigin-scoped live rows a sheet cannot express, counted not changed
overLimitdata.overLimitboolean-
maxRowsdata.maxRowsinteger-

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.

Apply a rate sheet to a switch deck

POST/api/v1/switch/rate-decks/apply

Access
API key. Scoped keys need switch:manage.
Rate limit
20 requests per minute

Writes the sheet in one transaction and reports what landed. A non-USD sheet needs fxRate. For supplier decks a future effectiveFrom queues the change for that moment instead (the result then has scheduled: true).

Test keys: refused with 403 TEST_KEY_NOT_ALLOWED. The Switch has no test mode, so a change always applies to your live configuration. Test keys can still read Switch data.

Request body (multipart/form-data)

FieldTypeDescription
targetKindrequiredstring-One of operator, supplier, customer
targetIdstring (uuid)-
targetTrunkIdstring (uuid)-
defaultIncrementstring-
changeModestring-One of amendment, full_replacement
effectiveFromstring (date-time)-
timezonestring-max 64 chars
fxRatestringUnits of USD per 1 unit of the sheet currency; required to apply a non-USD sheet
replacestringLegacy form of changeMode=full_replacementOne of true, false
mappingstringThe confirmed column mapping from the parse step, as JSON text
filerequiredstringThe rate sheet (CSV or XLSX), sent LAST

Response 200

FieldTypeDescription
datarequiredobjectSame fields as SwitchDeckSheetResult, shown earlier on this page.

Response 202

FieldTypeDescription
datarequiredobject-
approvalRequireddata.approvalRequiredboolean-One of true
approvalRequestIddata.approvalRequestIdstring (uuid) | null-
permissiondata.permissionstring-
expiresAtdata.expiresAtstring (date-time)-
messagedata.messagestring-

Errors

  • 400VALIDATION_ERROR, INVALID_INPUT or BAD_REQUEST. For VALIDATION_ERROR, error.details is an array of { path, message }.
  • 401UNAUTHORIZED: missing, invalid, expired or revoked credential.
  • 402SWITCH_SUBSCRIPTION_REQUIRED: the account has no active Switch plan or trial.
  • 403FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only.
  • 409CONFLICT (or a code-specific 409): the change clashes with existing state.
  • 429RATE_LIMITED: slow down and retry after the Retry-After seconds.
  • 500INTERNAL_ERROR: unexpected failure. Quote X-Request-Id to support.