diff --git a/README.md b/README.md
index 70cbdf8..3832c32 100644
--- a/README.md
+++ b/README.md
@@ -104,8 +104,6 @@ namespace Example
}
}
}
-```
-
## Documentation for API Endpoints
@@ -374,6 +372,11 @@ Class | Method | HTTP request | Description
- [Model.WebhookSubscriptionsListBody](docs/WebhookSubscriptionsListBody.md)
+
+## Documentation for BXML Verbs
+
+ - [Bxml.Verbs.Refer](docs/Refer.md)
+
## Documentation for Authorization
diff --git a/docs/Refer.md b/docs/Refer.md
new file mode 100644
index 0000000..508c6ad
--- /dev/null
+++ b/docs/Refer.md
@@ -0,0 +1,40 @@
+# Bandwidth.Standard.Model.Bxml.Verbs.Refer
+
+The `` verb is used to hand off a call to a SIP endpoint via a SIP REFER. The call is transferred to the specified SIP URI, and an optional callback is sent when the transfer completes.
+
+For more details, see the [Bandwidth BXML Refer documentation](https://dev.bandwidth.com/docs/voice/bxml/refer.html).
+
+## Properties
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**ReferCompleteUrl** | **string** | URL to receive the `referComplete` callback when the REFER is finished. | [optional]
+**ReferCompleteMethod** | **string** | HTTP method to use for the `referComplete` callback. Must be `GET` or `POST`. | [optional] [default to `POST`]
+**Tag** | **string** | Optional custom string to include in callbacks. Max 4096 characters. | [optional]
+**SipUriElement** | [**Refer.SipUri**](#sipuri-nested-class) | The SIP URI destination for the REFER. Must start with `sip:`. |
+
+## SipUri Nested Class
+
+The `` element specifies the destination SIP URI for the REFER.
+
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**Uri** | **string** | The SIP URI to refer the call to. Must start with `sip:`. |
+
+## Methods
+
+Name | Description
+------------ | -------------
+`WithSipUri(string sipUri)` | Sets the SIP URI destination from a string. Returns the `Refer` instance for chaining.
+`WithSipUri(SipUri sipUri)` | Sets the SIP URI destination from a `SipUri` object. Returns the `Refer` instance for chaining.
+`WithReferCompleteUrl(string referCompleteUrl)` | Sets the `referCompleteUrl` attribute. Returns the `Refer` instance for chaining.
+`WithReferCompleteMethod(string referCompleteMethod)` | Sets the `referCompleteMethod` attribute (`GET` or `POST`). Returns the `Refer` instance for chaining.
+`WithTag(string tag)` | Sets the `tag` attribute. Returns the `Refer` instance for chaining.
+
+## Validation
+
+- `SipUri.Uri` must start with `sip:` (case-insensitive). An `ArgumentException` is thrown if the value does not match.
+- `ReferCompleteMethod` must be either `GET` or `POST`. An `ArgumentException` is thrown for any other value.
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
diff --git a/src/Bandwidth.Standard.Test/Unit/Model/Bxml/TestRefer.cs b/src/Bandwidth.Standard.Test/Unit/Model/Bxml/TestRefer.cs
new file mode 100644
index 0000000..9064e42
--- /dev/null
+++ b/src/Bandwidth.Standard.Test/Unit/Model/Bxml/TestRefer.cs
@@ -0,0 +1,70 @@
+using System;
+using System.IO;
+using System.Xml.Serialization;
+using Bandwidth.Standard.Model.Bxml;
+using Bandwidth.Standard.Model.Bxml.Verbs;
+using Xunit;
+
+namespace Bandwidth.Standard.Test.Unit.Model.Bxml
+{
+ public class TestRefer
+ {
+ [Fact]
+ public void ReferRoundTripTest()
+ {
+ var expected = " sip:alice@atlanta.example.com ";
+
+ var refer = new Refer()
+ .WithSipUri("sip:alice@atlanta.example.com")
+ .WithReferCompleteUrl("https://example.com/handleRefer")
+ .WithReferCompleteMethod("POST")
+ .WithTag("refer-tag");
+
+ var actual = new Response(refer).ToBXML();
+ Assert.Equal(expected, actual.Replace("\n", "").Replace("\r", ""));
+
+ const string referOnlyXml = "sip:alice@atlanta.example.com";
+ var serializer = new XmlSerializer(typeof(Refer), "");
+ Refer deserializedRefer;
+ using (var reader = new StringReader(referOnlyXml))
+ {
+ deserializedRefer = (Refer)serializer.Deserialize(reader);
+ }
+
+ Assert.Equal("sip:alice@atlanta.example.com", deserializedRefer.SipUriElement.Uri);
+ var roundTrip = new Response(deserializedRefer).ToBXML();
+ Assert.Equal(expected, roundTrip.Replace("\n", "").Replace("\r", ""));
+ }
+
+ [Fact]
+ public void ReferSipUriMustStartWithSipScheme()
+ {
+ var refer = new Refer();
+ Assert.Throws(() => refer.WithSipUri("tel:+15551234567"));
+ }
+
+ [Fact]
+ public void ReferInvalidMethodThrows()
+ {
+ var refer = new Refer();
+ Assert.Throws(() => refer.WithReferCompleteMethod("DELETE"));
+ }
+
+ [Fact]
+ public void ReferWithSipUriObjectOverload()
+ {
+ var sipUri = new Refer.SipUri { Uri = "sip:alice@atlanta.example.com" };
+ var refer = new Refer().WithSipUri(sipUri);
+ Assert.Equal("sip:alice@atlanta.example.com", refer.SipUriElement.Uri);
+ }
+
+ [Fact]
+ public void ReferMinimalOnlySipUri()
+ {
+ var refer = new Refer().WithSipUri("sip:bob@biloxi.example.com");
+ var bxml = new Response(refer).ToBXML();
+ Assert.Contains("sip:bob@biloxi.example.com", bxml);
+ Assert.Contains("referCompleteMethod=\"POST\"", bxml);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Bandwidth.Standard/Model/Bxml/Verbs/Refer.cs b/src/Bandwidth.Standard/Model/Bxml/Verbs/Refer.cs
new file mode 100644
index 0000000..a712af8
--- /dev/null
+++ b/src/Bandwidth.Standard/Model/Bxml/Verbs/Refer.cs
@@ -0,0 +1,128 @@
+using Bandwidth.Standard.Model.Bxml;
+using System;
+using System.Xml.Serialization;
+
+namespace Bandwidth.Standard.Model.Bxml.Verbs
+{
+ ///
+ /// The Refer verb is used to hand off a call to a SIP endpoint.
+ ///
+ ///
+ public class Refer : IVerb
+ {
+ private string referCompleteMethod;
+
+ ///
+ /// URL to receive the refer complete callback.
+ ///
+ [XmlAttribute("referCompleteUrl")]
+ public string ReferCompleteUrl { get; set; }
+
+ ///
+ /// HTTP method to send the refer complete callback. GET or POST. Default value is POST.
+ ///
+ [XmlAttribute("referCompleteMethod")]
+ public string ReferCompleteMethod
+ {
+ get { return referCompleteMethod; }
+ set
+ {
+ if (value != null && value != "GET" && value != "POST")
+ {
+ throw new ArgumentException("ReferCompleteMethod must be either 'GET' or 'POST'.");
+ }
+ referCompleteMethod = value;
+ }
+ }
+
+ ///
+ /// Optional custom string to include in callbacks.
+ ///
+ [XmlAttribute("tag")]
+ public string Tag { get; set; }
+
+ ///
+ /// SIP URI destination for the REFER.
+ ///
+ [XmlElement("SipUri")]
+ public SipUri SipUriElement { get; set; }
+
+ ///
+ /// Initializes a new instance of the Refer class.
+ ///
+ public Refer()
+ {
+ ReferCompleteMethod = "POST";
+ }
+
+ ///
+ /// Sets the SIP URI destination from a string.
+ ///
+ public Refer WithSipUri(string sipUri)
+ {
+ SipUriElement = new SipUri { Uri = sipUri };
+ return this;
+ }
+
+ ///
+ /// Sets the SIP URI destination from a SipUri object.
+ ///
+ public Refer WithSipUri(SipUri sipUri)
+ {
+ SipUriElement = sipUri;
+ return this;
+ }
+
+ ///
+ /// Sets referCompleteUrl.
+ ///
+ public Refer WithReferCompleteUrl(string referCompleteUrl)
+ {
+ ReferCompleteUrl = referCompleteUrl;
+ return this;
+ }
+
+ ///
+ /// Sets referCompleteMethod.
+ ///
+ public Refer WithReferCompleteMethod(string referCompleteMethod)
+ {
+ ReferCompleteMethod = referCompleteMethod;
+ return this;
+ }
+
+ ///
+ /// Sets tag.
+ ///
+ public Refer WithTag(string tag)
+ {
+ Tag = tag;
+ return this;
+ }
+
+ ///
+ /// BXML tag to represent a SIP URI for the refer verb.
+ ///
+ public class SipUri : IVerb
+ {
+ private string _uri;
+
+ ///
+ /// SIP URI to refer the call to (must start with sip:).
+ ///
+ [XmlText]
+ public string Uri
+ {
+ get { return _uri; }
+ set
+ {
+ if (value != null && !value.StartsWith("sip:", StringComparison.OrdinalIgnoreCase))
+ {
+ throw new ArgumentException("SipUri must start with 'sip:'.");
+ }
+ _uri = value;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file