This guide provides step-by-step instructions and payload examples for generating a quote for Wholesale Ethernet E-LAN. This product provides any-to-any connectivity, allowing multiple sites to communicate within a private network mesh.
The process flows from defining the common quote "envelope" to building the composite product payload, and finally interpreting the multi-term pricing results.
While this tutorial uses a NAD Key (NadKeySite) for simplicity, the API supports various identifiers including Postcodes and UPRNs. Before building your integration, please review the Key concepts guide. This resource provides a full Site compatibility matrix, along with essential details on pricing, Sandbox testing, and request batching best practices to avoid rate limits.
Generating a quote is optional. The generated Quote ID cannot be used for product ordering. The prices obtained through the Quote Management API are indicative, not firm prices.
Logical structure of an E-LAN quote
In an E-LAN configuration, each location connects independently to the network mesh. To quote a mesh, you submit multiple flat quoteItem objects, each structured as follows.
- Root: Wholesale E-LAN Container
-
The top-level envelope for a single site within the mesh network.
{ "externalId": "my quote id", "expectedFulfillmentStartDate": "2026-02-23", "quoteItem": [ { "action": "add", "product": { "@type": "WholesaleEthernetElan", "productSpecification": { "id": "WholesaleEthernetElan" },- Site address (identified with a NadKey)
-
"place": [ { "@type": "NadKeySite", "nadKey": "A00007815341" } ],
- Physical access with nested CPE and virtual path
-
"product": [ { /* Physical access (Etherway) */ "@type": "EtherwayFibreService", "productSpecification": { "id": "EtherwayFibreService" }, "bandwidth": "1 Gbit/s", "resilience": "Standard", "product": [ { /* Optional CPE nested inside Etherway */ "@type": "EtherwayFirewallCpe", "productSpecification": { "id": "EtherwayFirewallCpe" }, "bandwidth": "10 Mbit/s, 10 Users", "bundle": "Firewall, Maintenance, Configuration, Installation, Managed CPE" }, { "@type": "EtherwayRouterCpe", "productSpecification": { "id": "EtherwayRouterCpe" }, "bandwidth": "1 Gbit/s", "bundle": "Router" } ] }, { /* Virtual path (Etherflow Dynamic) - peer to Etherway */ "@type": "EtherflowDynamicService", "productSpecification": { "id": "EtherflowDynamicService" }, "bandwidth": "0.2 Mbit/s", "cos": "Default CoS (Standard)" } ]
} } ] }
Prerequisites
To complete this guide, ensure you meet the prerequisites listed in the Quick start guide.
Step 1: Define the root attributes
Define the JSON root attributes: externalId and expectedFulfillmentStartDate, create the common quoteItem[] "envelope", and define the parent product type (WholesaleEthernetElan).
| Property | Format / Value | Details |
|---|---|---|
| externalId | String | Required. The root attribute for your internal reference ID. |
| expectedFulfillmentStartDate | "YYYY-MM-DD" | Required. The root attribute for the target start date. |
| action | "add" | Fixed value. Indicates a new quote line item. |
| product.@type | "WholesaleEthernetElan" | Required. The parent product bundle name. |
| product.productSpecification.id | "WholesaleEthernetElan" | Required. The parent product bundle id. |
- View payload after step 1
-
{
"externalId": "my quote id",
"expectedFulfillmentStartDate": "2026-02-23",
"quoteItem": [
{
"action": "add",
"product": {
"@type": "WholesaleEthernetElan",
"productSpecification": {
"id": "WholesaleEthernetElan"
},
"place": [],
"product": []
}
Step 2: Define the site address
| Property | Format / Value | Details |
|---|---|---|
| place[].@type | "NadKeySite" | Fixed value if you are using a NadKey. Specifies you are using an Address ID. |
| place[].nadKey | String |
Required if you are using a NadKey. The unique Gold Address ID from your Address Management step. Example value: A00007815344 |
- View payload after step 2.1
-
{
"externalId": "my quote id",
"expectedFulfillmentStartDate": "2026-02-23",
"quoteItem": [
{
"action": "add",
"product": {
"@type": "WholesaleEthernetElan",
"productSpecification": {
"id": "WholesaleEthernetElan"
},
"place": [
{
"@type": "NadKeySite",
"nadKey": "A00007815344"
}
],
"product": []
}
}
]
}
Step 3: Add sub-products
Create a product array with two mandatory and an optional sub-products:
- the physical access,
- the virtual path, and
- optional, BT-managed CPE (Customer Premises Equipment).
3.1: Define the physical access (Etherway)
This represents the physical fiber and CPE (Customer Premises Equipment) port at the site.
| Property | Value | Details |
|---|---|---|
| @type | "EtherwayFibreService" | Fixed value. Identifies the physical access component. |
|
productSpecification.id
|
“EtherwayFibreService” | Fixed value. Identifies the physical access component. |
| bandwidth | "1 Gbit/s" |
Required.The physical port capacity. Allowed values:
|
| resilience | "Standard" | Required. Defines whether the site uses a single fibre path or diverse, independent fibre paths to ensure service continuity in the event of a physical link failure. |
3.2: (Optional) Add BT-managed CPE (Customer Premises Equipment)
If your customer requires BT-managed equipment, include the Router or Firewall specifications as children nested within the Etherway product array.
Notes:
- Adding CPE here ensures your indicative quote includes the necessary one-off installation and monthly rental fees for the devices.
- Make sure that the CPE bandwidth matches the physical bearer speed.
| Property | Example value | Details |
|---|---|---|
| @type | "EtherwayRouterCpe" | Defines the component as a Managed Router. |
| @type | "EtherwayFirewallCpe" | Defines the component as a Managed Firewall. |
| bundle | "Firewall, Maintenance..." | Specifies the service level (e.g., Installation, Managed CPE). |
- Example CPE (Customer Premises Equipment) nesting payload
-
- Example CPE (Customer Premises Equipment) nesting payload
-
{
"externalId": "my quote id",
"expectedFulfillmentStartDate": "2026-02-23",
"quoteItem": [
{
"action": "add",
"product": {
"@type": "WholesaleEthernetElan",
"productSpecification": {
"id": "WholesaleEthernetElan"
},
"place": [
{
"@type": "NadKeySite",
"nadKey": "A00007815344"
}
],
"product": [
{
/* Physical access */
"product": [
{
/* Optional CPE nested inside physical access */
"@type": "EtherwayRouterCpe",
"productSpecification": {
"id": "EtherwayRouterCpe"
},
"bandwidth": "1 Gbit/s",
"bundle": "Router"
}
]
},
{
/* Virtual path - peer to the Etherway */
}
]
}
}
]
}
3.3: Define the virtual path (Etherflow Dynamic)
This provides the any-to-any connectivity capability and Class of Service (CoS) offerings.
| Property | Value | Details |
|---|---|---|
| @type | "EtherflowDynamicService" | Fixed value . Identifies the dynamic virtual path. |
| productSpecification.id | "EtherflowDynamicService" | Fixed value . Identifies the dynamic virtual path. |
| bandwidth | "0.2 Mbit/s" | Required.The committed data speed for this site within the mesh. Etherflow bandwidth cannot exceed the Etherway bandwidth. |
| cos | "Default CoS (Standard)" | Required. The traffic priority (Class of Service). |
- View payload after step 3.3. (with a hardware placeholder)
-
{
"externalId": "my quote id",
"expectedFulfillmentStartDate": "2026-02-23",
"quoteItem": [
{
"action": "add",
"product": {
"@type": "WholesaleEthernetElan",
"productSpecification": {
"id": "WholesaleEthernetElan"
},
"place": [
{
"@type": "NadKeySite",
"nadKey": "A00007815344"
}
],
"product": [
{
/* Physical access */
"@type": "EtherwayFibreService",
"productSpecification": {
"id": "EtherwayFibreService"
},
"bandwidth": "1 Gbit/s",
"resilience": "Standard",
"product": [
{
/* Optional CPE nested inside physical access */
}
]
},
{
/* Virtual path - peer to the Etherway */
"@type": "EtherflowDynamicService",
"productSpecification": {
"id": "EtherflowDynamicService"
},
"bandwidth": "0.2 Mbit/s",
"cos": "Default CoS (Standard)"
}
]
}
}
]
}
Step 4: Send the request
Set the required headers, then send your chosen JSON payload in the body of a POST request to the /tmf-api/quoteManagement/v4/quote endpoint.
- For more information, see the Send the request section in the Quick start guide.
- Need help? Browse the Common API-specific errors & Troubleshooting reference table.
Step 5: Interpret the response
The API returns a 201 Created status with the quote details. You must parse the response for the key pieces of information: Quote ID, Excess Construction Charges (ECCs), indicative pricing, and Option B variations.
For a detailed breakdown of these fields, see the Interpret the response section in the Quick start guide.
- Example response payload
-
{
"id": "820dec09-3e31-4d1d-934f-334e6fc315d8",
"@baseType": "Quote",
"@type": "BtwQuote",
"externalId": "",
"href": "https://api.wholesale.bt.com:443/tmf-api/quoteManagement/v4/quote/820de…",
"system": "Dev",
"category": "Wholesale",
"product": "WholesaleEthernetElan",
"description": "This quote is indicative and non-binding.",
"quoteDate": "2026-02-21T16:46:41.104Z",
"effectiveQuoteCompletionDate": "2026-02-21",
"expectedFulfillmentStartDate": "2026-02-23",
"version": "v1",
"state": "approved",
"validFor": {
"startDateTime": "2026-02-21",
"endDateTime": "2026-02-21"
},
"quoteItem": [
{
"@baseType": "QuoteItem",
"@type": "BtwQuoteItem",
"state": "approved",
"action": "add",
"product": {
"@baseType": "Product",
"@type": "WholesaleEthernetElan",
"productSpecification": {
"id": "WholesaleEthernetElan"
},
"place": [
{
"@type": "NadKeySite",
"nadKey": "A00007815341"
}
],
"product": [
{
"@baseType": "Product",
"@type": "EtherwayFibreService",
"productSpecification": {
"id": "EtherwayFibreService"
},
"bandwidth": "1 Gbit/s",
"resilience": "Standard",
"productInformation": {
"accessProvider": "Openreach",
"openreachOnNet": "No",
"servingExchange": {
"code": "THBZ",
"name": "BASINGSTOKE"
},
"ethernetSwitch": [
{
"code": "THBZ",
"name": "BASINGSTOKE",
"exchangeDistance": {
"unit": "Kilometre",
"value": 0
},
"siteDistance": {
"unit": "Kilometre",
"value": 2
}
}
],
"indicativeECCs": {
"circuitDeliveryCategory": "2.1",
"tariff": "In Tariff",
"indicativeExtraECCs": "No extra ECC costs",
"fibrePresent": "Yes",
"tNodeCapacity": "Yes"
}
},
"productPrice": [
{
"name": "1 Year connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 1857
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 2228.4
}
}
},
{
"name": "1 Year rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 1972
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 2366.4
}
}
},
{
"name": "3 Year connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 0
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 0
}
}
},
{
"name": "3 Year rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 1972
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 2366.4
}
}
},
{
"name": "5 Year connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 0
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 0
}
}
},
{
"name": "5 Year rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 1722
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 2066.4
}
}
},
{
"name": "3 Year Option B connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 1500
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 1800
}
}
},
{
"name": "3 Year Option B rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 1472
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 1766.4
}
}
}
]
},
{
"@baseType": "Product",
"@type": "EtherflowDynamicService",
"productSpecification": {
"id": "EtherflowDynamicService"
},
"bandwidth": "0.2 Mbit/s",
"cos": "Default CoS (Standard)",
"productPrice": [
{
"name": "1 Year connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 0
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 0
}
}
},
{
"name": "1 Year rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 475.2
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 570.24
}
}
},
{
"name": "3 Year connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 0
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 0
}
}
},
{
"name": "3 Year rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 475.2
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 570.24
}
}
},
{
"name": "5 Year connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 0
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 0
}
}
},
{
"name": "5 Year rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 475.2
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 570.24
}
}
},
{
"name": "3 Year Option B connection",
"priceType": "nonRecurring",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 0
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 0
}
}
},
{
"name": "3 Year Option B rental",
"priceType": "recurring",
"recurringChargePeriod": "year",
"price": {
"taxRate": 20,
"dutyFreeAmount": {
"unit": "GBP",
"value": 475.2
},
"taxIncludedAmount": {
"unit": "GBP",
"value": 570.24
}
}
}
]
}
]
}
}
]
}
Next steps
- Manage your quotes: See the Managing and interpreting quotes to learn how to retrieve quotes by Id, how list and search quotes, and how to interpret the response headers and quote states.
- Place the order: Submit your final request following the Order Management tutorial.
- Notes:
- The parent-child relationship in the quoting structure differs from the ordering structure, which requires separate orders for each site.
- Creating a quote is entirely optional, and the Quote ID is not required or referenced in the final product order.
- Notes: