From 5b5ee82f4079f111531aed196dc4a6cbcad0548c Mon Sep 17 00:00:00 2001 From: Nicolas Asanov Date: Tue, 20 Oct 2026 17:10:21 -0400 Subject: [PATCH 1/2] feat(VAPI-3321): add attestation_level and identity to BXML Transfer --- .../models/bxml/verbs/transfer.rb | 2 ++ spec/unit/models/bxml/verbs/transfer_spec.rb | 18 +++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb b/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb index 419968d2..2d11eca8 100644 --- a/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb +++ b/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb @@ -23,6 +23,8 @@ def initialize(transfer_to = [], attributes = {}) tag: 'tag', # Optional [String]: A custom string that will be sent with this and all future callbacks unless overwritten by a future tag attribute or cleared. May be cleared by setting tag="" Max length 256 characters. Defaults to None. diversion_treatment: 'diversionTreatment', # Optional [String]: Can be any of the following: - none: No diversion headers are sent on the outbound leg of the transferred call. - propagate: Copy the Diversion header from the inbound leg to the outbound leg. Ignored if there is no Diversion header present on the inbound leg. - stack: After propagating any Diversion header from the inbound leg to the outbound leg, stack on top another Diversion header based on the Request-URI of the inbound call. If diversionTreatment is not specified, no diversion header will be included for the transfer even if one came with the inbound call. Defaults to None. diversion_reason: 'diversionReason', # Optional [String]: Can be any of the following values: unknown, user-busy, no-answer, unavailable, unconditional, time-of-day, do-not-disturb, deflection, follow-me, out-of-service, away. This parameter is considered only when diversionTreatment is set to stack. Defaults to None. + attestation_level: 'attestationLevel', # Optional [String]: STIR/SHAKEN attestation level Bandwidth signs the outbound leg with: A, B, or C. US outbound only; applies only to accounts using the Hosted Signing Service, otherwise ignored. If omitted, the account-level attestation policy applies. Cannot be combined with identity. Defaults to None. + identity: 'identity', # Optional [String]: A SIP Identity header value (PASSporT) signed off-platform, passed through unmodified. Bandwidth does not sign or verify it. Max 2000 characters from [A-Za-z0-9-_.+/=;:<>" ]. Cannot be combined with attestationLevel. Defaults to None. } end diff --git a/spec/unit/models/bxml/verbs/transfer_spec.rb b/spec/unit/models/bxml/verbs/transfer_spec.rb index 69832f2d..a20df586 100644 --- a/spec/unit/models/bxml/verbs/transfer_spec.rb +++ b/spec/unit/models/bxml/verbs/transfer_spec.rb @@ -16,7 +16,9 @@ fallback_password: 'initial_fallback_password', tag: 'initial_tag', diversion_treatment: 'propagate', - diversion_reason: 'user-busy' + diversion_reason: 'user-busy', + attestation_level: 'A', + identity: 'initial_identity' } } @@ -36,7 +38,9 @@ fallback_password: 'new_fallback_password', tag: 'new_tag', diversion_treatment: 'stack', - diversion_reason: 'no-answer' + diversion_reason: 'no-answer', + attestation_level: 'B', + identity: 'new_identity' } } @@ -53,13 +57,13 @@ end it 'tests the to_bxml method of the Transfer instance' do - expected = "\n\n" + expected = "\n\n" expect(instance.to_bxml).to eq(expected) end it 'tests the set_attributes method of the Transfer instance' do instance.set_attributes(new_attributes) - expected = "\n\n" + expected = "\n\n" expect(instance.to_bxml).to eq(expected) end end @@ -71,16 +75,16 @@ end it 'tests the to_bxml method of the nested Transfer instance' do - expected = "\n\n +19195551234\n\n" + expected = "\n\n +19195551234\n\n" expect(instance_nested.to_bxml).to eq(expected) end it 'tests the add_verb method of the nested Transfer instance' do - expected_single = "\n\n +19195551234\n sip:1-999-123-4567@voip-provider.example.net\n\n" + expected_single = "\n\n +19195551234\n sip:1-999-123-4567@voip-provider.example.net\n\n" instance_nested.add_transfer_recipients(sip_uri) expect(instance_nested.to_bxml).to eq(expected_single) - expected_multiple = "\n\n +19195551234\n sip:1-999-123-4567@voip-provider.example.net\n sip:1-999-123-4567@voip-provider.example.net\n +19195551234\n\n" + expected_multiple = "\n\n +19195551234\n sip:1-999-123-4567@voip-provider.example.net\n sip:1-999-123-4567@voip-provider.example.net\n +19195551234\n\n" instance_nested.add_transfer_recipients([sip_uri, phone_number]) expect(instance_nested.to_bxml).to eq(expected_multiple) end From f79b5733064415d9cf95f00cb695db59edc03153 Mon Sep 17 00:00:00 2001 From: Nicolas Asanov Date: Tue, 3 Nov 2026 12:10:47 -0500 Subject: [PATCH 2/2] VAPI-4422 Tighten Attestation Level and Identity Docs --- lib/bandwidth-sdk/models/bxml/verbs/transfer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb b/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb index 2d11eca8..345c4de1 100644 --- a/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb +++ b/lib/bandwidth-sdk/models/bxml/verbs/transfer.rb @@ -23,8 +23,8 @@ def initialize(transfer_to = [], attributes = {}) tag: 'tag', # Optional [String]: A custom string that will be sent with this and all future callbacks unless overwritten by a future tag attribute or cleared. May be cleared by setting tag="" Max length 256 characters. Defaults to None. diversion_treatment: 'diversionTreatment', # Optional [String]: Can be any of the following: - none: No diversion headers are sent on the outbound leg of the transferred call. - propagate: Copy the Diversion header from the inbound leg to the outbound leg. Ignored if there is no Diversion header present on the inbound leg. - stack: After propagating any Diversion header from the inbound leg to the outbound leg, stack on top another Diversion header based on the Request-URI of the inbound call. If diversionTreatment is not specified, no diversion header will be included for the transfer even if one came with the inbound call. Defaults to None. diversion_reason: 'diversionReason', # Optional [String]: Can be any of the following values: unknown, user-busy, no-answer, unavailable, unconditional, time-of-day, do-not-disturb, deflection, follow-me, out-of-service, away. This parameter is considered only when diversionTreatment is set to stack. Defaults to None. - attestation_level: 'attestationLevel', # Optional [String]: STIR/SHAKEN attestation level Bandwidth signs the outbound leg with: A, B, or C. US outbound only; applies only to accounts using the Hosted Signing Service, otherwise ignored. If omitted, the account-level attestation policy applies. Cannot be combined with identity. Defaults to None. - identity: 'identity', # Optional [String]: A SIP Identity header value (PASSporT) signed off-platform, passed through unmodified. Bandwidth does not sign or verify it. Max 2000 characters from [A-Za-z0-9-_.+/=;:<>" ]. Cannot be combined with attestationLevel. Defaults to None. + attestation_level: 'attestationLevel', # Optional [String]: The STIR/SHAKEN attestation level to sign the transferred call with. Can be A, B, or C. Only applies to accounts using the Hosted Signing Service. Cannot be combined with identity. Defaults to None. + identity: 'identity', # Optional [String]: A SIP Identity header value (PASSporT) signed by you, sent unmodified on the transferred call. Max length 2000 characters. Cannot be combined with attestationLevel. Defaults to None. } end