API Reference

Complete documentation for The Bunch Partner API endpoints, parameters, and responses for household bill management.

POST /Auth/token Obtain an access token from Auth0 for API authentication

Overview

Obtain an access token from Auth0 for API authentication. This endpoint requires your Auth0 client credentials and returns a JWT token that must be included in the Authorization header of all subsequent API requests.

Prerequisites

  • Valid Auth0 client credentials (client_id and client_secret)
  • Auth0 application configured with the correct audience
  • Client credentials grant type enabled in Auth0

Flow

  1. Send POST request to Auth0 token endpoint with client credentials
  2. Auth0 validates credentials and returns access token
  3. Use the access token in Authorization header for API requests
  4. Token expires after 24 hours and must be refreshed

Best Practices

⚠️ Important Security Notes

  • Never expose your client secret in client-side code or public repositories
  • Store credentials securely on your server using environment variables
  • Always use HTTPS for all API communications
  • Implement proper token refresh logic to avoid expired token errors
  • Monitor token usage and implement rate limiting

Request Fields

client_id
string required
The client ID to use for authentication
"your-auth0-client-id-here"
client_secret
string required
The client secret to use for authentication
"your-auth0-client-secret-here"
audience
string required
The API audience identifier
"https://api.the-bunch.co.uk"
grant_type
string required
The grant type, should be "client_credentials"
"client_credentials"

Request Body

{
  "client_id": "your_client_id",
  "client_secret": "your_client_secret",
  "audience": "https://api.the-bunch.co.uk",
  "grant_type": "client_credentials"
}

Response Fields

access_token
string
The JWT access token to use for API requests
token_type
string
The token type, typically "Bearer"
expires_in
integer
Token expiration time in seconds (86400 = 24 hours)

Response Body

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1yNS1BVWliZkJpaTdOZDFqQmViYXhib1hXMCJ9...",
  "token_type": "Bearer",
  "expires_in": 86400
}

Example Code

cURL
curl -X POST 'https://your-auth0-domain.auth0.com/oauth/token' \
  -H 'Content-Type: application/json' \
  -d '{
    "client_id": "your_client_id",
    "client_secret": "your_client_secret",
    "audience": "https://api.the-bunch.co.uk",
    "grant_type": "client_credentials"
  }'
JavaScript
const response = await fetch('https://your-auth0-domain.auth0.com/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    client_id: 'your_client_id',
    client_secret: 'your_client_secret',
    audience: 'https://api.the-bunch.co.uk',
    grant_type: 'client_credentials'
  })
});

const data = await response.json();
const accessToken = data.access_token;
Python
import requests

response = requests.post('https://your-auth0-domain.auth0.com/oauth/token', json={
    'client_id': 'your_client_id',
    'client_secret': 'your_client_secret',
    'audience': 'https://api.the-bunch.co.uk',
    'grant_type': 'client_credentials'
})

data = response.json()
access_token = data['access_token']
.NET
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;

var client = new HttpClient();
var requestBody = new {
    client_id = "your_client_id",
    client_secret = "your_client_secret",
    audience = "https://api.the-bunch.co.uk",
    grant_type = "client_credentials"
};

var json = JsonConvert.SerializeObject(requestBody);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://your-auth0-domain.auth0.com/oauth/token", content);
var responseContent = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<dynamic>(responseContent);
var accessToken = data.access_token;

Error Responses

400 Bad Request

Invalid request parameters or missing required fields.

{
  "error": "invalid_request",
  "error_description": "Missing required parameter: client_id"
}

401 Unauthorized

Invalid client credentials.

{
  "error": "invalid_client",
  "error_description": "Invalid client credentials"
}
GET /Addresses/lookup Lookup addresses by postcode to find available properties for quotes

Overview

Retrieves a list of all available addresses at a given postcode. This endpoint is essential for the quote creation process as it provides the address information needed to create quotes.

Prerequisites

  • Valid authentication token
  • Valid UK postcode format

Flow

  1. Call this endpoint with a valid postcode
  2. Present the returned addresses to the customer
  3. Customer selects their address
  4. Use the selected address in quote creation

Best Practices

⚠️ Important Notes

  • Use the AddressUid from the response when creating quotes
  • Do not manually construct address objects - always use lookup results
  • Address availability may change over time
  • Some postcodes may not have any available addresses

Request Fields

postcode string Required
The postcode to lookup addresses for

Request Body

This endpoint uses query parameters, no request body required.

Response Fields

addressLine1
string
Primary address line (e.g., "Apartment 1", "Flat 2")
addressLine2
string
Secondary address line (e.g., building name, street)
city
string
City or town name
county
string
County name (may be empty)
country
string
Country name (typically "United Kingdom")
postCode
string
Postal code
uprn
string
Unique Property Reference Number for the address
addressUid
string
Unique identifier for the address (used in quote creation and required for broadband)

Response Body

[
  {
    "addressLine1": "Apartment 1",
    "addressLine2": "Chimes Apartments 99-105 Horseferry Road",
    "city": "London",
    "country": "United Kingdom",
    "county": "",
    "postCode": "SW1P 2DX",
    "uprn": "100023123456",
    "mpan": null,
    "mprn": null,
    "addressUid": "4b61cc99-63a7-4639-aa4b-bc06988d4388"
  },
  {
    "addressLine1": "Flat 2",
    "addressLine2": "Chimes Apartments 99-105 Horseferry Road",
    "city": "London",
    "country": "United Kingdom",
    "county": "",
    "postCode": "SW1P 2DX",
    "uprn": "100023123456",
    "mpan": null,
    "mprn": null,
    "addressUid": "45n6cc99-63a7-4639-aa4b-bc06988d4388"
  }
]

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Addresses/lookup?postcode=SW1P%202DX" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json"
JavaScript
const response = await fetch('https://api.the-bunch.co.uk/partner-api/Addresses/lookup?postcode=SW1P%202DX', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  }
});

const addresses = await response.json();
console.log(addresses);
Python
import requests

url = "https://api.the-bunch.co.uk/partner-api/Addresses/lookup"
params = {"postcode": "SW1P 2DX"}
headers = {
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "Content-Type": "application/json"
}

response = requests.get(url, params=params, headers=headers)
addresses = response.json()
print(addresses)
.NET
using System;
using System.Net.Http;
using System.Threading.Tasks;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");
client.DefaultRequestHeaders.Add("Content-Type", "application/json");

var response = await client.GetAsync("https://api.the-bunch.co.uk/partner-api/Addresses/lookup?postcode=SW1P%202DX");
var addresses = await response.Content.ReadAsStringAsync();
Console.WriteLine(addresses);
GET /Quotes/quoting-tool-versions Retrieve available quoting tool versions for creating quotes

Overview

Retrieves a list of available quoting tool versions that can be used when creating quotes. This endpoint is optional if you already know which version to use.

Prerequisites

  • Valid authentication token

Version Selection Flow

  1. Fetch: Call this endpoint to get available versions
  2. Select: Choose the appropriate version (usually the default)
  3. Use: Include the version ID when creating quotes

Best Practices

⚠️ Important Notes

  • Always use the latest stable version unless you have specific requirements
  • Cache version information to reduce API calls
  • Handle version changes gracefully in your application

Request Fields

No request parameters required for this endpoint.

Request Body

No request body required for this GET endpoint.

Response Fields

versions
array
Array of available quoting tool versions
id
string
Unique identifier for the version
name
string
Human-readable version name
isDefault
boolean
Whether this is the default version

Response Body

{
  "versions": [
    {
      "id": "v1.0",
      "name": "Standard Quoting Tool",
      "isDefault": true
    },
    {
      "id": "v1.1",
      "name": "Enhanced Quoting Tool",
      "isDefault": false
    }
  ]
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Quotes/quoting-tool-versions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"
JavaScript
const response = await fetch('https://api.the-bunch.co.uk/partner-api/Quotes/quoting-tool-versions', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  }
});

const versions = await response.json();
console.log(versions);
Python
import requests

headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

response = requests.get('https://api.the-bunch.co.uk/partner-api/Quotes/quoting-tool-versions', headers=headers)
versions = response.json()
print(versions)
.NET
using System.Net.Http;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");
client.DefaultRequestHeaders.Add("Content-Type", "application/json");

var response = await client.GetAsync("https://api.the-bunch.co.uk/partner-api/Quotes/quoting-tool-versions");
var versions = await response.Content.ReadAsStringAsync();
Console.WriteLine(versions);
POST /Quotes Create a new quote

Overview

Creates a new quote for household bill services at a specific address. This is the first step in the quote creation process.

💡 Quick Start

Provide an address UID from the address lookup endpoint to create a new quote. The quote will be created in draft status with available packages.

Prerequisites

  • Valid authentication token
  • Valid address UID from address lookup

Quote Creation Flow

  1. Lookup: Get address UID from address lookup
  2. Create: Call this endpoint to create the quote
  3. Configure: Add packages, tenants, and broadband products
  4. Finalize: Complete the quote setup

Best Practices

⚠️ Important Notes

  • Always validate address UID before creating quotes
  • Handle quote creation failures gracefully
  • Implement proper error handling for invalid addresses
  • Consider rate limiting for quote creation requests

Request Fields

addressUid string Required
Unique identifier for the address (obtained from address lookup)
quotingToolVersionId string Optional
Version of the quoting tool to use (defaults to latest if not specified)

Request Body

{
  "addressUid": "addr_123456789",
  "quotingToolVersionId": "v1.0"
}

Response Fields

quoteId
string
Unique identifier for the created quote
status
string
Current status of the quote (draft, active, completed)
address
object
Address details for the quote
availablePackages
array
Available service packages for this address

Response Body

{
  "quoteId": "quote_987654321",
  "status": "draft",
  "address": {
    "addressUid": "addr_123456789",
    "addressLine1": "123 Main Street",
    "city": "London",
    "postCode": "SW1A 1AA"
  },
  "availablePackages": [
    {
      "packageId": "pkg_energy",
      "name": "Energy Package",
      "description": "Gas and electricity services"
    }
  ]
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Quotes" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "addressUid": "addr_123456789",
  "quotingToolVersionId": "v1.0"
}'
JavaScript
const response = await fetch('https://api.the-bunch.co.uk/partner-api/Quotes', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    addressUid: 'addr_123456789',
    quotingToolVersionId: 'v1.0'
  })
});

const quote = await response.json();
console.log(quote);
Python
import requests
import json

headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

data = {
    'addressUid': 'addr_123456789',
    'quotingToolVersionId': 'v1.0'
}

response = requests.post('https://api.the-bunch.co.uk/partner-api/Quotes', 
                        headers=headers, 
                        data=json.dumps(data))
quote = response.json()
print(quote)
.NET
using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var data = new {
    addressUid = "addr_123456789",
    quotingToolVersionId = "v1.0"
};

var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.the-bunch.co.uk/partner-api/Quotes", content);
var quote = await response.Content.ReadAsStringAsync();
Console.WriteLine(quote);
GET /Quotes/{id} Get quote details with all tenants and available products

Overview

Retrieve a specific quote with all tenants and available products. Use this to check quote status and tenant progress.

💡 Quick Start

Provide a quote ID to retrieve complete quote details including all tenants, packages, and available products.

Prerequisites

  • Valid authentication token
  • Valid quote ID

Quote Retrieval Flow

  1. Identify: Use the quote ID from quote creation
  2. Retrieve: Call this endpoint to get quote details
  3. Process: Handle the returned quote data
  4. Display: Show quote information to users

Best Practices

⚠️ Important Notes

  • Validate quote ID format before making requests
  • Handle quote not found errors gracefully
  • Implement proper access controls for quote data
  • Cache quote data appropriately to reduce API calls

Request Fields

id string Required
Unique identifier for the quote (path parameter)

Request Body

No request body required for this GET endpoint.

Response Fields

quoteId
string
Unique identifier for the quote
status
string
Current status of the quote
tenants
array
List of tenants associated with the quote
packages
array
Available service packages

Response Body

{
  "quoteId": "quote_987654321",
  "status": "draft",
  "address": {
    "addressUid": "addr_123456789",
    "addressLine1": "123 Main Street",
    "city": "London",
    "postCode": "SW1A 1AA"
  },
  "tenants": [
    {
      "tenantId": "tenant_001",
      "name": "John Doe",
      "email": "john@example.com",
      "status": "active"
    }
  ],
  "packages": [
    {
      "packageId": "pkg_energy",
      "name": "Energy Package",
      "status": "available"
    }
  ]
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Quotes/quote_987654321" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"
JavaScript
const quoteId = 'quote_987654321';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/${quoteId}`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  }
});

const quote = await response.json();
console.log(quote);
Python
import requests

quote_id = 'quote_987654321'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Quotes/{quote_id}', headers=headers)
quote = response.json()
print(quote)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");
client.DefaultRequestHeaders.Add("Content-Type", "application/json");

var quoteId = "quote_987654321";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/{quoteId}");
var quote = await response.Content.ReadAsStringAsync();
Console.WriteLine(quote);
POST /Quotes/{id}/add-packages Add selected packages to an existing quote

Overview

Add selected packages to an existing quote. Use package IDs from the quote response to specify which services to include.

Prerequisites

  • Valid authentication token
  • Valid quote ID
  • Quote must be in "Draft" or "PackagesSelected" state
  • Quote must not be expired

Package Selection Flow

  1. Retrieve: Get quote details to see available packages
  2. Select: Choose packages to add to the quote
  3. Add: Call this endpoint with selected package IDs
  4. Verify: Check updated quote with selected packages

Best Practices

⚠️ Important Notes

  • Validate package IDs before making requests
  • Handle package selection failures gracefully
  • Implement proper error handling for invalid packages
  • Consider rate limiting for package selection requests

Request Fields

id string Required
Unique identifier for the quote (path parameter)
packageIds array Required
Array of package IDs to add to the quote

Request Body

{
  "packageIds": ["pkg_energy", "pkg_broadband"]
}

Response Fields

quoteId
string
Unique identifier for the quote
status
string
Updated status of the quote
selectedPackages
array
List of selected packages

Response Body

{
  "quoteId": "quote_987654321",
  "status": "PackagesSelected",
  "selectedPackages": [
    {
      "packageId": "pkg_energy",
      "name": "Energy Package",
      "status": "selected"
    },
    {
      "packageId": "pkg_broadband",
      "name": "Broadband Package",
      "status": "selected"
    }
  ]
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Quotes/quote_987654321/add-packages" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "packageIds": ["pkg_energy", "pkg_broadband"]
}'
JavaScript
const quoteId = 'quote_987654321';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/${quoteId}/add-packages`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    packageIds: ['pkg_energy', 'pkg_broadband']
  })
});

const result = await response.json();
console.log(result);
Python
import requests
import json

quote_id = 'quote_987654321'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

data = {
    'packageIds': ['pkg_energy', 'pkg_broadband']
}

response = requests.post(f'https://api.the-bunch.co.uk/partner-api/Quotes/{quote_id}/add-packages', 
                        headers=headers, 
                        data=json.dumps(data))
result = response.json()
print(result)
.NET
using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var quoteId = "quote_987654321";
var data = new {
    packageIds = new[] { "pkg_energy", "pkg_broadband" }
};

var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/{quoteId}/add-packages", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
POST /Quotes/{id}/add-tenants Add tenants to an existing quote

Overview

Add tenant information to an existing quote. This can be done before or after adding packages.

Prerequisites

  • Valid authentication token
  • Valid quote ID
  • Quote must be in "Draft" or "PackagesSelected" state
  • Must be completed before payment schedules can be generated for each tenant
  • Quote must not be expired

Tenant Addition Flow

  1. Prepare: Gather tenant information (name, email, contact details)
  2. Add: Call this endpoint with tenant data
  3. Verify: Check updated quote with tenant information
  4. Continue: Proceed with package selection or broadband addition

Best Practices

⚠️ Important Notes

  • Validate tenant email addresses before submission
  • Ensure all required tenant information is provided
  • Handle tenant addition failures gracefully
  • Consider data privacy requirements for tenant information

Request Fields

id string Required
Unique identifier for the quote (path parameter)
tenants array Required
Array of tenant objects to add to the quote
name string Required
Full name of the tenant
email string Required
Email address of the tenant

Request Body

{
  "tenants": [
    {
      "name": "John Doe",
      "email": "john.doe@example.com"
    },
    {
      "name": "Jane Smith",
      "email": "jane.smith@example.com"
    }
  ]
}

Response Fields

quoteId
string
Unique identifier for the quote
status
string
Updated status of the quote
tenants
array
List of added tenants

Response Body

{
  "quoteId": "quote_987654321",
  "status": "TenantsAdded",
  "tenants": [
    {
      "tenantId": "tenant_001",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "status": "active"
    },
    {
      "tenantId": "tenant_002",
      "name": "Jane Smith",
      "email": "jane.smith@example.com",
      "status": "active"
    }
  ]
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Quotes/quote_987654321/add-tenants" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "tenants": [
    {
      "name": "John Doe",
      "email": "john.doe@example.com"
    },
    {
      "name": "Jane Smith",
      "email": "jane.smith@example.com"
    }
  ]
}'
JavaScript
const quoteId = 'quote_987654321';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/${quoteId}/add-tenants`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    tenants: [
      {
        name: 'John Doe',
        email: 'john.doe@example.com'
      },
      {
        name: 'Jane Smith',
        email: 'jane.smith@example.com'
      }
    ]
  })
});

const result = await response.json();
console.log(result);
Python
import requests
import json

quote_id = 'quote_987654321'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

data = {
    'tenants': [
        {
            'name': 'John Doe',
            'email': 'john.doe@example.com'
        },
        {
            'name': 'Jane Smith',
            'email': 'jane.smith@example.com'
        }
    ]
}

response = requests.post(f'https://api.the-bunch.co.uk/partner-api/Quotes/{quote_id}/add-tenants', 
                        headers=headers, 
                        data=json.dumps(data))
result = response.json()
print(result)
.NET
using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var quoteId = "quote_987654321";
var data = new {
    tenants = new[] {
        new { name = "John Doe", email = "john.doe@example.com" },
        new { name = "Jane Smith", email = "jane.smith@example.com" }
    }
};

var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/{quoteId}/add-tenants", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
POST /Quotes/{id}/update-packages Update packages on an existing quote

Overview

Update or replace packages on an existing quote. Products can be replaced provided no customer has started payment or been completed yet.

Prerequisites

  • Valid authentication token
  • Valid quote ID
  • Quote must be in "Draft" or "PackagesSelected" state
  • No customer payments must have been started

Package Update Flow

  1. Verify: Check quote status and payment state
  2. Select: Choose new packages to replace existing ones
  3. Update: Call this endpoint with new package IDs
  4. Confirm: Verify the updated quote details

Best Practices

⚠️ Important Notes

  • Only update packages before customer payment begins
  • Validate new package IDs before making requests
  • Handle package update failures gracefully
  • Consider impact on existing tenant configurations

Request Fields

id string Required
Unique identifier for the quote (path parameter)
packageIds array Required
Array of new package IDs to replace existing ones

Request Body

{
  "packageIds": ["pkg_energy_v2", "pkg_broadband_premium"]
}

Response Fields

quoteId
string
Unique identifier for the quote
status
string
Updated status of the quote
updatedPackages
array
List of updated packages

Response Body

{
  "quoteId": "quote_987654321",
  "status": "PackagesUpdated",
  "updatedPackages": [
    {
      "packageId": "pkg_energy_v2",
      "name": "Energy Package V2",
      "status": "selected"
    },
    {
      "packageId": "pkg_broadband_premium",
      "name": "Premium Broadband Package",
      "status": "selected"
    }
  ]
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Quotes/quote_987654321/update-packages" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "packageIds": ["pkg_energy_v2", "pkg_broadband_premium"]
}'
JavaScript
const quoteId = 'quote_987654321';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/${quoteId}/update-packages`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    packageIds: ['pkg_energy_v2', 'pkg_broadband_premium']
  })
});

const result = await response.json();
console.log(result);
Python
import requests
import json

quote_id = 'quote_987654321'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

data = {
    'packageIds': ['pkg_energy_v2', 'pkg_broadband_premium']
}

response = requests.post(f'https://api.the-bunch.co.uk/partner-api/Quotes/{quote_id}/update-packages', 
                        headers=headers, 
                        data=json.dumps(data))
result = response.json()
print(result)
.NET
using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var quoteId = "quote_987654321";
var data = new {
    packageIds = new[] { "pkg_energy_v2", "pkg_broadband_premium" }
};

var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/{quoteId}/update-packages", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
POST /Quotes/{id}/add-broadband-products Add broadband products to quote

Overview

Add broadband products to an existing quote after checking availability.

Prerequisites

  • Valid authentication token
  • Valid quote ID
  • Broadband availability must be checked first
  • Products must be available at the address

Broadband Addition Flow

  1. Check: Verify broadband availability at the address
  2. Select: Choose available broadband products
  3. Add: Call this endpoint with selected products
  4. Schedule: Get installation dates for the products

Best Practices

⚠️ Important Notes

  • Always check broadband availability before adding products
  • Validate product availability at the specific address
  • Handle broadband addition failures gracefully
  • Consider installation date availability

Request Fields

id string Required
Unique identifier for the quote (path parameter)
broadbandProducts array Required
Array of broadband product IDs to add

Request Body

{
  "broadbandProducts": ["bb_fiber_100", "bb_fiber_500"]
}

Response Fields

quoteId
string
Unique identifier for the quote
status
string
Updated status of the quote
broadbandProducts
array
List of added broadband products

Response Body

{
  "quoteId": "quote_987654321",
  "status": "BroadbandAdded",
  "broadbandProducts": [
    {
      "productId": "bb_fiber_100",
      "name": "Fiber 100 Mbps",
      "status": "added"
    },
    {
      "productId": "bb_fiber_500",
      "name": "Fiber 500 Mbps",
      "status": "added"
    }
  ]
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Quotes/quote_987654321/add-broadband-products" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "broadbandProducts": ["bb_fiber_100", "bb_fiber_500"]
}'
JavaScript
const quoteId = 'quote_987654321';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/${quoteId}/add-broadband-products`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    broadbandProducts: ['bb_fiber_100', 'bb_fiber_500']
  })
});

const result = await response.json();
console.log(result);
Python
import requests
import json

quote_id = 'quote_987654321'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

data = {
    'broadbandProducts': ['bb_fiber_100', 'bb_fiber_500']
}

response = requests.post(f'https://api.the-bunch.co.uk/partner-api/Quotes/{quote_id}/add-broadband-products', 
                        headers=headers, 
                        data=json.dumps(data))
result = response.json()
print(result)
.NET
using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var quoteId = "quote_987654321";
var data = new {
    broadbandProducts = new[] { "bb_fiber_100", "bb_fiber_500" }
};

var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/{quoteId}/add-broadband-products", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Quotes/{id}/get-bb-install-dates Get broadband installation dates

Overview

Retrieve available installation dates for broadband products in the quote.

Prerequisites

  • Valid authentication token
  • Valid quote ID
  • Broadband products must be added to the quote

Installation Date Flow

  1. Add: Ensure broadband products are added to quote
  2. Request: Call this endpoint to get available dates
  3. Select: Choose preferred installation date
  4. Schedule: Confirm installation appointment

Best Practices

⚠️ Important Notes

  • Check installation dates before finalizing quote
  • Consider customer availability when selecting dates
  • Handle date conflicts gracefully
  • Provide alternative dates if preferred unavailable

Request Fields

id string Required
Unique identifier for the quote (path parameter)

Request Body

No request body required for GET request

Response Fields

quoteId
string
Unique identifier for the quote
availableDates
array
List of available installation dates
earliestDate
string
Earliest available installation date

Response Body

{
  "quoteId": "quote_987654321",
  "availableDates": [
    "2025-01-15",
    "2025-01-16",
    "2025-01-17",
    "2025-01-20",
    "2025-01-21"
  ],
  "earliestDate": "2025-01-15"
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Quotes/quote_987654321/get-bb-install-dates" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const quoteId = 'quote_987654321';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/${quoteId}/get-bb-install-dates`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

quote_id = 'quote_987654321'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Quotes/{quote_id}/get-bb-install-dates', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var quoteId = "quote_987654321";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/{quoteId}/get-bb-install-dates");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Quotes/{id}/total-cost Get total cost breakdown for quote

Overview

Retrieve the total cost breakdown for a quote, showing how costs are split among all tenants.

Prerequisites

  • Valid authentication token
  • Valid quote ID
  • Quote must have packages and tenants added

Cost Calculation Flow

  1. Add: Ensure packages and tenants are added to quote
  2. Calculate: System calculates total costs and splits
  3. Retrieve: Call this endpoint to get cost breakdown
  4. Display: Show costs to customer for approval

Best Practices

⚠️ Important Notes

  • Always show cost breakdown before finalizing quote
  • Handle cost calculation errors gracefully
  • Validate cost splits are fair and accurate
  • Consider tax implications in cost display

Request Fields

id string Required
Unique identifier for the quote (path parameter)

Request Body

No request body required for GET request

Response Fields

quoteId
string
Unique identifier for the quote
totalCost
number
Total cost for the entire quote
costBreakdown
array
Detailed cost breakdown by tenant
monthlyCost
number
Monthly recurring cost per tenant

Response Body

{
  "quoteId": "quote_987654321",
  "totalCost": 1250.00,
  "monthlyCost": 104.17,
  "costBreakdown": [
    {
      "tenantId": "tenant_001",
      "tenantName": "John Smith",
      "monthlyCost": 52.08,
      "setupCost": 125.00,
      "products": ["energy_basic", "broadband_standard"]
    },
    {
      "tenantId": "tenant_002", 
      "tenantName": "Jane Doe",
      "monthlyCost": 52.09,
      "setupCost": 125.00,
      "products": ["energy_basic", "broadband_standard"]
    }
  ]
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Quotes/quote_987654321/total-cost" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const quoteId = 'quote_987654321';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/${quoteId}/total-cost`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

quote_id = 'quote_987654321'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Quotes/{quote_id}/total-cost', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var quoteId = "quote_987654321";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/{quoteId}/total-cost");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Quotes/run-broadband-availability-check/{uid} Check broadband availability

Overview

Check broadband availability for a specific address using the broadband availability request UID.

Prerequisites

  • Valid authentication token
  • Valid broadband availability request UID
  • Address must be validated

Broadband Check Flow

  1. Validate: Ensure address is valid and UID exists
  2. Check: System checks broadband availability
  3. Retrieve: Call this endpoint to get results
  4. Display: Show available broadband options

Best Practices

⚠️ Important Notes

  • Always validate UID before making requests
  • Handle availability check failures gracefully
  • Cache results to avoid repeated checks
  • Provide fallback options if no broadband available

Request Fields

uid string Required
Broadband availability request UID (path parameter)

Request Body

No request body required for GET request

Response Fields

uid
string
Broadband availability request UID
available
boolean
Whether broadband is available at the address
products
array
List of available broadband products
maxSpeed
number
Maximum available speed in Mbps

Response Body

{
  "uid": "bb_check_123456789",
  "available": true,
  "maxSpeed": 1000,
  "products": [
    {
      "productId": "bb_fiber_100",
      "name": "Fiber 100 Mbps",
      "speed": 100,
      "price": 25.00
    },
    {
      "productId": "bb_fiber_500",
      "name": "Fiber 500 Mbps", 
      "speed": 500,
      "price": 45.00
    },
    {
      "productId": "bb_fiber_1000",
      "name": "Fiber 1000 Mbps",
      "speed": 1000,
      "price": 65.00
    }
  ]
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Quotes/run-broadband-availability-check/bb_check_123456789" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const uid = 'bb_check_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Quotes/run-broadband-availability-check/${uid}`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

uid = 'bb_check_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Quotes/run-broadband-availability-check/{uid}', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var uid = "bb_check_123456789";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Quotes/run-broadband-availability-check/{uid}");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Customers/{id} Get customer details and information

Overview

Retrieve customer details and current status information including personal details, payment status, and service subscriptions.

Prerequisites

  • Valid authentication token
  • Valid customer ID

Customer Retrieval Flow

  1. Identify: Use the customer ID from tenant creation
  2. Retrieve: Call this endpoint to get customer details
  3. Process: Handle the returned customer data
  4. Display: Show customer information to users

Best Practices

⚠️ Important Notes

  • Always validate customer ID before making requests
  • Handle customer not found errors gracefully
  • Cache customer data to reduce API calls
  • Respect customer privacy and data protection

Request Fields

id string Required
Unique identifier for the customer (path parameter)

Request Body

No request body required for GET request

Response Fields

customerId
string
Unique identifier for the customer
status
string
Current customer status
personalDetails
object
Customer's personal information
paymentStatus
string
Current payment status
services
array
List of active services

Response Body

{
  "customerId": "customer_123456789",
  "status": "active",
  "personalDetails": {
    "firstName": "John",
    "lastName": "Smith",
    "email": "john.smith@example.com",
    "phone": "+44 7123 456789"
  },
  "paymentStatus": "paid",
  "services": [
    {
      "serviceId": "energy_basic",
      "name": "Basic Energy Package",
      "status": "active",
      "startDate": "2025-01-01"
    },
    {
      "serviceId": "broadband_standard",
      "name": "Standard Broadband",
      "status": "active", 
      "startDate": "2025-01-01"
    }
  ]
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Customers/{id}/total-cost Get cost breakdown for specific customer

Overview

Returns the packages selected and total cost of the quote as split for the specific customer.

Prerequisites

  • Valid authentication token
  • Valid customer/tenant ID
  • Customer must have packages assigned

Cost Retrieval Flow

  1. Identify: Use the customer/tenant ID
  2. Calculate: System calculates cost split for this customer
  3. Retrieve: Call this endpoint to get cost breakdown
  4. Display: Show customer-specific costs

Best Practices

⚠️ Important Notes

  • Always validate customer ID before making requests
  • Handle cost calculation errors gracefully
  • Ensure cost splits are fair and accurate
  • Consider tax implications in cost display

Request Fields

id string Required
Customer/Tenant ID (path parameter)

Request Body

No request body required for GET request

Response Fields

customerId
string
Customer/Tenant ID
totalCost
number
Total cost for this customer
monthlyCost
number
Monthly recurring cost
packages
array
List of packages assigned to this customer

Response Body

{
  "customerId": "customer_123456789",
  "totalCost": 625.00,
  "monthlyCost": 52.08,
  "packages": [
    {
      "packageId": "energy_basic",
      "name": "Basic Energy Package",
      "monthlyCost": 30.00,
      "setupCost": 75.00
    },
    {
      "packageId": "broadband_standard",
      "name": "Standard Broadband",
      "monthlyCost": 22.08,
      "setupCost": 50.00
    }
  ]
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789/total-cost" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}/total-cost`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}/total-cost', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}/total-cost");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
POST /Customers/{id}/finalise-personal-information Add personal information and PSR (Priority Services Register) details

Overview

Add complete personal information for a tenant including PSR (Priority Services Register) details and contract dates. This must be submitted for every tenant, even if no PSR information is required.

Prerequisites

  • Valid authentication token
  • Valid customer ID
  • Required before payment intent creation
  • Customer must be over 18 years of age
  • If PSR (Priority Services Register) information is specified, authorised contact details are required

Personal Information Flow

  1. Prepare: Gather all required personal information
  2. Validate: Ensure all required fields are complete
  3. Submit: Call this endpoint with personal details
  4. Verify: Confirm information was accepted

Best Practices

⚠️ Important Notes

  • Always validate personal information before submission
  • Handle PSR (Priority Services Register) information securely and in compliance with regulations
  • Implement proper data validation for all fields
  • Protect sensitive personal data in transit and at rest

Request Fields

id string Required
Customer ID (path parameter)
firstName string Required
Customer's first name
lastName string Required
Customer's last name
email string Required
Customer's email address
phone string Required
Customer's phone number
dateOfBirth string Required
Customer's date of birth (YYYY-MM-DD)
psrDetails object Optional
PSR (Priority Services Register) details if applicable

Request Body

{
  "firstName": "John",
  "lastName": "Smith",
  "email": "john.smith@example.com",
  "phone": "+44 7123 456789",
  "dateOfBirth": "1990-05-15",
  "psrDetails": {
    "hasPsr": false
  }
}

Response Fields

customerId
string
Customer ID
status
string
Updated customer status
personalInfoComplete
boolean
Whether personal information is complete

Response Body

{
  "customerId": "customer_123456789",
  "status": "PersonalInfoComplete",
  "personalInfoComplete": true
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789/finalise-personal-information" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "firstName": "John",
  "lastName": "Smith",
  "email": "john.smith@example.com",
  "phone": "+44 7123 456789",
  "dateOfBirth": "1990-05-15",
  "psrDetails": {
    "hasPsr": false
  }
}'
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}/finalise-personal-information`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    firstName: 'John',
    lastName: 'Smith',
    email: 'john.smith@example.com',
    phone: '+44 7123 456789',
    dateOfBirth: '1990-05-15',
    psrDetails: {
      hasPsr: false
    }
  })
});

const result = await response.json();
console.log(result);
Python
import requests
import json

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

data = {
    'firstName': 'John',
    'lastName': 'Smith',
    'email': 'john.smith@example.com',
    'phone': '+44 7123 456789',
    'dateOfBirth': '1990-05-15',
    'psrDetails': {
        'hasPsr': False
    }
}

response = requests.post(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}/finalise-personal-information', 
                        headers=headers, 
                        data=json.dumps(data))
result = response.json()
print(result)
.NET
using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var data = new {
    firstName = "John",
    lastName = "Smith",
    email = "john.smith@example.com",
    phone = "+44 7123 456789",
    dateOfBirth = "1990-05-15",
    psrDetails = new {
        hasPsr = false
    }
};

var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}/finalise-personal-information", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Customers/{id}/payment-schedules Get payment schedule information

Overview

Retrieve payment schedules amounts for a tenant. Payment amounts may differ between primary and secondary tenants due to pro rata monthly billing.

Prerequisites

  • Valid authentication token
  • Valid customer ID
  • Quote must be in "PackagesSelected" state
  • Customer must have personal information completed

Payment Schedule Flow

  1. Complete: Ensure personal information is finalized
  2. Calculate: System calculates payment schedules
  3. Retrieve: Call this endpoint to get payment details
  4. Display: Show payment schedule to customer

Best Practices

⚠️ Important Notes

  • Always validate customer status before retrieving schedules
  • Handle pro rata billing calculations correctly
  • Display payment amounts clearly to customers
  • Consider different billing cycles for tenants

Request Fields

id string Required
Customer ID (path parameter)

Request Body

No request body required for GET request

Response Fields

customerId
string
Customer ID
paymentSchedule
object
Payment schedule details
monthlyAmount
number
Monthly payment amount
setupAmount
number
One-time setup payment amount

Response Body

{
  "customerId": "customer_123456789",
  "paymentSchedule": {
    "monthlyAmount": 52.08,
    "setupAmount": 125.00,
    "billingCycle": "monthly",
    "nextPaymentDate": "2025-02-01"
  },
  "monthlyAmount": 52.08,
  "setupAmount": 125.00
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789/payment-schedules" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}/payment-schedules`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}/payment-schedules', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}/payment-schedules");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
POST /Customers/{id}/create-setup-intent Create Stripe setup intent for payment collection

Overview

Create a Stripe setup intent for payment method collection. This creates the customer in Stripe and associates their payment card to the account only. Payments will be collected shortly after.

Prerequisites

  • Valid authentication token
  • Valid customer ID
  • Quote must be in "PackagesSelected" state
  • Customer must have personal information completed
  • Customer should be shown their payment schedule before this setup intent is generated

Setup Intent Flow

  1. Prepare: Ensure customer has completed personal information
  2. Create: Call this endpoint to create Stripe setup intent
  3. Collect: Use Stripe Elements to collect payment details
  4. Confirm: Complete setup intent with Stripe

Best Practices

⚠️ Important Notes

  • Always use Stripe Elements library for secure payment collection
  • Handle setup intent failures gracefully
  • Validate customer status before creating setup intent
  • Ensure PCI (Payment Card Industry) compliance when handling payment data

Request Fields

id string Required
Customer ID (path parameter)

Request Body

No request body required for this endpoint

Response Fields

customerId
string
Customer ID
setupIntentId
string
Stripe setup intent ID
clientSecret
string
Client secret for Stripe Elements
stripeCustomerId
string
Stripe customer ID

Response Body

{
  "customerId": "customer_123456789",
  "setupIntentId": "seti_1234567890",
  "clientSecret": "seti_1234567890_secret_abcdef",
  "stripeCustomerId": "cus_1234567890"
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789/create-setup-intent" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}/create-setup-intent`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);

// Use with Stripe Elements
const stripe = Stripe('pk_test_...');
const elements = stripe.elements();
const cardElement = elements.create('card');
cardElement.mount('#card-element');
Python
import requests

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.post(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}/create-setup-intent', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var response = await client.PostAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}/create-setup-intent", null);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
POST /Customers/{id}/accept-terms Complete tenant onboarding by accepting terms

Overview

Complete the tenant onboarding by accepting terms and conditions. This will finalise the journey for this customer.

Prerequisites

  • Valid authentication token
  • Valid customer ID
  • Payment details must be provided via setup intent
  • Setup intent must have had a successful response

Terms Acceptance Flow

  1. Complete: Ensure payment setup is successful
  2. Present: Show terms and conditions to customer
  3. Accept: Call this endpoint when customer accepts
  4. Finalize: Complete customer onboarding

Best Practices

⚠️ Important Notes

  • Always ensure payment setup is complete before accepting terms
  • Present terms clearly and ensure customer understands
  • Handle terms acceptance failures gracefully
  • Maintain audit trail of terms acceptance

Request Fields

id string Required
Customer ID (path parameter)

Request Body

No request body required for this endpoint

Response Fields

customerId
string
Customer ID
status
string
Updated customer status
onboardingComplete
boolean
Whether onboarding is complete
termsAcceptedAt
string
Timestamp of terms acceptance

Response Body

{
  "customerId": "customer_123456789",
  "status": "OnboardingComplete",
  "onboardingComplete": true,
  "termsAcceptedAt": "2025-01-15T10:30:00Z"
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789/accept-terms" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}/accept-terms`, {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.post(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}/accept-terms', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var response = await client.PostAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}/accept-terms", null);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Customers/{id}/pci-contract-url-html Get HTML contract URL for PCI (Pre-Contract Information) compliance

Overview

Generate HTML contract URL for PCI (Pre-Contract Information) compliance purposes.

Prerequisites

  • Valid authentication token
  • Valid customer ID
  • Customer must have completed onboarding

Contract URL Flow

  1. Complete: Ensure customer onboarding is finished
  2. Generate: Call this endpoint to create contract URL
  3. Access: Use the returned URL to access contract
  4. Comply: Ensure PCI (Pre-Contract Information) compliance requirements are met

Best Practices

⚠️ Important Notes

  • Always validate customer status before generating URLs
  • Handle URL generation failures gracefully
  • Ensure URLs are accessible for PCI (Pre-Contract Information) compliance
  • Maintain security when handling contract URLs

Request Fields

id string Required
Customer ID (path parameter)

Request Body

No request body required for GET request

Response Fields

customerId
string
Customer ID
contractUrl
string
HTML contract URL
expiresAt
string
URL expiration timestamp

Response Body

{
  "customerId": "customer_123456789",
  "contractUrl": "https://contracts.the-bunch.co.uk/html/customer_123456789?token=abc123",
  "expiresAt": "2025-02-15T10:30:00Z"
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789/pci-contract-url-html" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}/pci-contract-url-html`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}/pci-contract-url-html', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}/pci-contract-url-html");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Customers/{id}/pci-contract-url-pdf Get PDF contract URL for PCI (Pre-Contract Information) compliance

Overview

Generate PDF contract URL for PCI (Pre-Contract Information) compliance purposes.

Prerequisites

  • Valid authentication token
  • Valid customer ID
  • Customer must have completed onboarding

Contract URL Flow

  1. Complete: Ensure customer onboarding is finished
  2. Generate: Call this endpoint to create PDF contract URL
  3. Access: Use the returned URL to access PDF contract
  4. Comply: Ensure PCI (Pre-Contract Information) compliance requirements are met

Best Practices

⚠️ Important Notes

  • Always validate customer status before generating URLs
  • Handle URL generation failures gracefully
  • Ensure PDF URLs are accessible for PCI (Pre-Contract Information) compliance
  • Maintain security when handling contract URLs

Request Fields

id string Required
Customer ID (path parameter)

Request Body

No request body required for GET request

Response Fields

customerId
string
Customer ID
contractUrl
string
PDF contract URL
expiresAt
string
URL expiration timestamp

Response Body

{
  "customerId": "customer_123456789",
  "contractUrl": "https://contracts.the-bunch.co.uk/pdf/customer_123456789?token=abc123",
  "expiresAt": "2025-02-15T10:30:00Z"
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Customers/customer_123456789/pci-contract-url-pdf" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const customerId = 'customer_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Customers/${customerId}/pci-contract-url-pdf`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

customer_id = 'customer_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Customers/{customer_id}/pci-contract-url-pdf', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var customerId = "customer_123456789";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Customers/{customerId}/pci-contract-url-pdf");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
POST /Webhooks Create webhook endpoint

Overview

Create a webhook endpoint to receive notifications about quote and customer events such as payment updates, service changes, and status updates.

Prerequisites

  • Valid authentication token
  • Publicly accessible webhook URL
  • HTTPS endpoint (required for security)

Webhook Setup Flow

  1. Prepare: Set up a webhook endpoint on your server
  2. Create: Call this endpoint to register your webhook
  3. Verify: Handle webhook verification requests
  4. Process: Handle incoming webhook events

Best Practices

⚠️ Important Notes

  • Always use HTTPS for webhook endpoints
  • Implement webhook signature verification
  • Handle webhook failures gracefully with retries
  • Implement idempotency for webhook processing

Request Fields

url string Required
Webhook endpoint URL (must be HTTPS)
events array Required
Array of events to subscribe to

Request Body

{
  "url": "https://your-domain.com/webhooks/bunch",
  "events": [
    "quote.status.changed",
    "customer.payment.updated",
    "customer.status.changed"
  ]
}

Response Fields

webhookId
string
Unique webhook identifier
url
string
Webhook endpoint URL
events
array
Subscribed events
status
string
Webhook status

Response Body

{
  "webhookId": "webhook_123456789",
  "url": "https://your-domain.com/webhooks/bunch",
  "events": [
    "quote.status.changed",
    "customer.payment.updated",
    "customer.status.changed"
  ],
  "status": "active"
}

Example Code

cURL
curl -X POST "https://api.the-bunch.co.uk/partner-api/Webhooks" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "url": "https://your-domain.com/webhooks/bunch",
  "events": [
    "quote.status.changed",
    "customer.payment.updated",
    "customer.status.changed"
  ]
}'
JavaScript
const response = await fetch('https://api.the-bunch.co.uk/partner-api/Webhooks', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    url: 'https://your-domain.com/webhooks/bunch',
    events: [
      'quote.status.changed',
      'customer.payment.updated',
      'customer.status.changed'
    ]
  })
});

const result = await response.json();
console.log(result);
Python
import requests
import json

headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
    'Content-Type': 'application/json'
}

data = {
    'url': 'https://your-domain.com/webhooks/bunch',
    'events': [
        'quote.status.changed',
        'customer.payment.updated',
        'customer.status.changed'
    ]
}

response = requests.post('https://api.the-bunch.co.uk/partner-api/Webhooks', 
                        headers=headers, 
                        data=json.dumps(data))
result = response.json()
print(result)
.NET
using System.Net.Http;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var data = new {
    url = "https://your-domain.com/webhooks/bunch",
    events = new[] {
        "quote.status.changed",
        "customer.payment.updated",
        "customer.status.changed"
    }
};

var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.the-bunch.co.uk/partner-api/Webhooks", content);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
GET /Webhooks/{id} Get webhook endpoint details

Overview

Retrieve details of a specific webhook endpoint.

Prerequisites

  • Valid authentication token
  • Valid webhook ID

Webhook Retrieval Flow

  1. Identify: Use the webhook ID from creation
  2. Retrieve: Call this endpoint to get webhook details
  3. Process: Handle the returned webhook information
  4. Display: Show webhook configuration to users

Best Practices

⚠️ Important Notes

  • Always validate webhook ID before making requests
  • Handle webhook not found errors gracefully
  • Cache webhook data to reduce API calls
  • Monitor webhook status and health

Request Fields

id string Required
Webhook endpoint ID (path parameter)

Request Body

No request body required for GET request

Response Fields

webhookId
string
Unique webhook identifier
url
string
Webhook endpoint URL
events
array
Subscribed events
status
string
Webhook status
createdAt
string
Webhook creation timestamp

Response Body

{
  "webhookId": "webhook_123456789",
  "url": "https://your-domain.com/webhooks/bunch",
  "events": [
    "quote.status.changed",
    "customer.payment.updated",
    "customer.status.changed"
  ],
  "status": "active",
  "createdAt": "2025-01-15T10:30:00Z"
}

Example Code

cURL
curl -X GET "https://api.the-bunch.co.uk/partner-api/Webhooks/webhook_123456789" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
JavaScript
const webhookId = 'webhook_123456789';
const response = await fetch(`https://api.the-bunch.co.uk/partner-api/Webhooks/${webhookId}`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
  }
});

const result = await response.json();
console.log(result);
Python
import requests

webhook_id = 'webhook_123456789'
headers = {
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}

response = requests.get(f'https://api.the-bunch.co.uk/partner-api/Webhooks/{webhook_id}', 
                       headers=headers)
result = response.json()
print(result)
.NET
using System.Net.Http;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN");

var webhookId = "webhook_123456789";
var response = await client.GetAsync($"https://api.the-bunch.co.uk/partner-api/Webhooks/{webhookId}");
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);