Cookie

We use cookies to improve your experience on our site, and to provide a live chat feature. To find out more please read our privacy policy.

Sample code for address lookup

This page provides sample code to help you set up Postcoder address lookup and autocomplete.

Copy any example below and then insert your own API key to make it work. Sign up to get an API key.

Address lookup using JavaScript

This example uses the address endpoint to provide UK postcode lookup, Irish Eircode lookup and global address lookup in a single form. It can be customised using the config settings at the end of the HTML.

.
Ireland and Eircode: Enable access on your API key using the Data Options page or by contacting us.
class PostcoderAddress{
  
  constructor(config) {
    this.config = config
    this.init()
  }

  init = () => {

    this.endpoint = 'https://ws.postcoder.com/pcw/' + this.config.apikey + '/address/'
    this.addresses = {}

    this.searchbutton = document.querySelector(this.config.searchbutton)
    this.searchterminput = document.querySelector(this.config.searchterm)

    //hide the no result message
    this.noresultmessage = document.querySelector(this.config.noresultmessage)
    this.noresultmessage.style.display = 'none'

    // create an empty select and place it hidden in the page
    this.select = document.createElement('select')
    this.select.style.display = 'none'
    document.querySelector(this.config.addressselectioncontainer).appendChild(this.select)

    // create and append the top 'select an address' option.
    let option = document.createElement('option')
    option.text = 'Select an address'
    this.select.appendChild(option)

    // add select change event listener to the dropdown
    this.select.addEventListener('change', this.handleSelectChange )

    // add click event listener to the search button, to call the search function
    this.searchbutton.addEventListener('click', this.search)

    // add 'enter' event listener to the search input, to call the search function
    this.searchterminput.addEventListener('keyup', event =>{
      if (event.keyCode === 13) {
        event.preventDefault()
        this.search()
      }
    })

    // determine the number of addresslines required
    this.addresslines = 0
    for (let i = 1; i <= 4; i++) {
      if( this.config['addressline'+i] !== ''){
        this.addresslines ++
      }
    }    

  }

  handleSelectChange = event => {

      // check to see if this selection was to load the next page of results
      if( this.select.value.charAt(0) === 'p'){
      
        // search the next page of results
        let page = this.select.value.substring(1)
        this.search(event, page)

      }else{   

        this.selectAddress( this.select.value )

      }     
  }

  search = (event, page = 0) => {

    let searchterm = encodeURIComponent(this.searchterminput.value)

    //hide the no result message
    this.noresultmessage.style.display = 'none'

    // hide the select
    this.select.style.display = 'none'

    //determine the country
    if(typeof this.config.countrycode !== 'undefined' && this.config.countrycode !== ''){
      // defined in config
      var country = this.config.countrycode
    }else{
      // get from dropdown
      var country = document.querySelector(this.config.country).value
    }

    // if page 0, remove any previous options
    if(page === 0){
      while (this.select.options.length > 1) {                
        this.select.remove(1)
      }
    }else{
      // remove the bottom 'next page' option
      this.select.remove(this.select.options.length - 1)
    }

    // fetch the json formatted result from Postcoder and pass it to processResult
    fetch(this.endpoint + country + '/' + searchterm + '?lines='+this.addresslines + '&exclude=organisation,country&page=' + page)
      .then( response => {
        if (!response.ok) { 
          throw response 
        }
        return response.json()
      })
      .then( json => {
        this.processResult(json)
      })
      .catch( err => {

        if(typeof err.text === 'function'){
          err.text().then( errorMessage => {
            console.log('Postcoder request error ' + err.status + ' : ' + errorMessage)
          })
        }else{
          console.log(err)
        }
    })
  }

  processResult = addresses =>{

    this.addresses = addresses

    //if zero results, ask for manual address entry
    if( addresses.length === 0 ){
      
      //show the no result message
      this.noresultmessage.style.display = 'block'

    }
    // if one result, populate the form
    else if(addresses.length === 1){

      this.selectAddress(0)

    }
    // multiple addresses, show drop down to select from
    else{

      // create and append the address options, using the summaryline of the returned addresses
      for (let i = 0; i < addresses.length; i++) {
        let option = document.createElement('option')
        option.value = i
        option.text = addresses[i].summaryline
        this.select.appendChild(option)
      }

      // if there are morevalues, add paging
      if(this.addresses[this.addresses.length - 1]['morevalues'] === 'true'){

        // add a 'load next page' option
        let option = document.createElement('option')
        option.value = 'p' + this.addresses[this.addresses.length - 1]['nextpage']

        // last address contains total number of results, show the user how many are remaining
        let remainingresults = this.addresses[this.addresses.length - 1]['totalresults'] - this.select.options.length + 1

        option.text = 'Load more results, ' + remainingresults + ' of ' + this.addresses[this.addresses.length - 1]['totalresults'] + ' remaining'
        this.select.appendChild(option)

      }
      
      // ensure the select is visible
      this.select.style.display = 'block'

    }
  }

  selectAddress = i =>{

    // get the selected address
    let address = this.addresses[i]

    let fields = ['organisation','addressline1','addressline2','addressline3','addressline4','posttown','county','postcode']

    //populate the address form  
    for (let i = 0; i < fields.length; i++) {
      let field_selector = this.config[fields[i]]
      if(typeof field_selector !== 'undefined' && field_selector !== ''){
        document.querySelector(field_selector).value = (typeof address[fields[i]] !== 'undefined') ? address[fields[i]] : ''
      }
    }

  }

}
<!doctype html>
<html lang="en">
  <head>
      <link rel="stylesheet" href="postcoder.css" >   
      <script src="postcoder_address.js"></script>
  </head>
  <body>

    <form>
            
      <label for="txt_country">Country</label>
      <select id="txt_country">
        <option value="AU">Australia</option>
        <option value="AT">Austria</option>
        <option value="BE">Belgium</option>
        <option value="BZ">Belize</option>
        <option value="BJ">Benin</option>
        <option value="BM">Bermuda</option>
        <option value="BT">Bhutan</option>
        <option value="BO">Bolivia (Plurinational State of)</option>
        <option value="BQ">Bonaire, Sint Eustatius and Saba</option>
        <option value="BA">Bosnia and Herzegovina</option>
        <option value="BW">Botswana</option>
        <option value="BV">Bouvet Island</option>
        <option value="BR">Brazil</option>
        <option value="IO">British Indian Ocean Territory</option>
        <option value="BN">Brunei Darussalam</option>
        <option value="BG">Bulgaria</option>
        <option value="BF">Burkina Faso</option>
        <option value="BI">Burundi</option>
        <option value="CV">Cabo Verde</option>
        <option value="KH">Cambodia</option>
        <option value="CM">Cameroon</option>
        <option value="CA">Canada</option>
        <option value="KY">Cayman Islands</option>
        <option value="CF">Central African Republic</option>
        <option value="TD">Chad</option>
        <option value="CL">Chile</option>
        <option value="CN">China</option>
        <option value="CX">Christmas Island</option>
        <option value="CC">Cocos (Keeling) Islands</option>
        <option value="CO">Colombia</option>
        <option value="KM">Comoros</option>
        <option value="CD">Congo (the Democratic Republic of the)</option>
        <option value="CG">Congo</option>
        <option value="CK">Cook Islands</option>
        <option value="CR">Costa Rica</option>
        <option value="HR">Croatia</option>
        <option value="CU">Cuba</option>
        <option value="CW">Curaçao</option>
        <option value="CY">Cyprus</option>
        <option value="CZ">Czechia</option>
        <option value="CI">Côte d'Ivoire</option>
        <option value="DK">Denmark</option>
        <option value="DJ">Djibouti</option>
        <option value="DM">Dominica</option>
        <option value="DO">Dominican Republic</option>
        <option value="EC">Ecuador</option>
        <option value="EG">Egypt</option>
        <option value="SV">El Salvador</option>
        <option value="GQ">Equatorial Guinea</option>
        <option value="ER">Eritrea</option>
        <option value="EE">Estonia</option>
        <option value="SZ">Eswatini</option>
        <option value="ET">Ethiopia</option>
        <option value="FK">Falkland Islands [Malvinas]</option>
        <option value="FO">Faroe Islands</option>
        <option value="FJ">Fiji</option>
        <option value="FI">Finland</option>
        <option value="FR">France</option>
        <option value="GF">French Guiana</option>
        <option value="PF">French Polynesia</option>
        <option value="TF">French Southern Territories</option>
        <option value="GA">Gabon</option>
        <option value="GM">Gambia</option>
        <option value="GE">Georgia</option>
        <option value="DE">Germany</option>
        <option value="GH">Ghana</option>
        <option value="GI">Gibraltar</option>
        <option value="GR">Greece</option>
        <option value="GL">Greenland</option>
        <option value="GD">Grenada</option>
        <option value="GP">Guadeloupe</option>
        <option value="GU">Guam</option>
        <option value="GT">Guatemala</option>
        <option value="GG">Guernsey</option>
        <option value="GN">Guinea</option>
        <option value="GW">Guinea-Bissau</option>
        <option value="GY">Guyana</option>
        <option value="HT">Haiti</option>
        <option value="HM">Heard Island and McDonald Islands</option>
        <option value="VA">Holy See</option>
        <option value="HN">Honduras</option>
        <option value="HK">Hong Kong</option>
        <option value="HU">Hungary</option>
        <option value="IS">Iceland</option>
        <option value="IN">India</option>
        <option value="ID">Indonesia</option>
        <option value="IR">Iran (Islamic Republic of)</option>
        <option value="IQ">Iraq</option>
        <option value="IE">Ireland</option>
        <option value="IM">Isle of Man</option>
        <option value="IL">Israel</option>
        <option value="IT">Italy</option>
        <option value="JM">Jamaica</option>
        <option value="JP">Japan</option>
        <option value="JE">Jersey</option>
        <option value="JO">Jordan</option>
        <option value="KZ">Kazakhstan</option>
        <option value="KE">Kenya</option>
        <option value="KI">Kiribati</option>
        <option value="KP">Korea (the Democratic People's Republic of)</option>
        <option value="KR">Korea (the Republic of)</option>
        <option value="KW">Kuwait</option>
        <option value="KG">Kyrgyzstan</option>
        <option value="LA">Lao People's Democratic Republic</option>
        <option value="LV">Latvia</option>
        <option value="LB">Lebanon</option>
        <option value="LS">Lesotho</option>
        <option value="LR">Liberia</option>
        <option value="LY">Libya</option>
        <option value="LI">Liechtenstein</option>
        <option value="LT">Lithuania</option>
        <option value="LU">Luxembourg</option>
        <option value="MO">Macao</option>
        <option value="MG">Madagascar</option>
        <option value="MW">Malawi</option>
        <option value="MY">Malaysia</option>
        <option value="MV">Maldives</option>
        <option value="ML">Mali</option>
        <option value="MT">Malta</option>
        <option value="MH">Marshall Islands</option>
        <option value="MQ">Martinique</option>
        <option value="MR">Mauritania</option>
        <option value="MU">Mauritius</option>
        <option value="YT">Mayotte</option>
        <option value="MX">Mexico</option>
        <option value="FM">Micronesia (Federated States of)</option>
        <option value="MD">Moldova (the Republic of)</option>
        <option value="MC">Monaco</option>
        <option value="MN">Mongolia</option>
        <option value="ME">Montenegro</option>
        <option value="MS">Montserrat</option>
        <option value="MA">Morocco</option>
        <option value="MZ">Mozambique</option>
        <option value="MM">Myanmar</option>
        <option value="NA">Namibia</option>
        <option value="NR">Nauru</option>
        <option value="NP">Nepal</option>
        <option value="NL">Netherlands</option>
        <option value="NC">New Caledonia</option>
        <option value="NZ">New Zealand</option>
        <option value="NI">Nicaragua</option>
        <option value="NE">Niger</option>
        <option value="NG">Nigeria</option>
        <option value="NU">Niue</option>
        <option value="NF">Norfolk Island</option>
        <option value="MP">Northern Mariana Islands</option>
        <option value="NO">Norway</option>
        <option value="OM">Oman</option>
        <option value="PK">Pakistan</option>
        <option value="PW">Palau</option>
        <option value="PS">Palestine, State of</option>
        <option value="PA">Panama</option>
        <option value="PG">Papua New Guinea</option>
        <option value="PY">Paraguay</option>
        <option value="PE">Peru</option>
        <option value="PH">Philippines</option>
        <option value="PN">Pitcairn</option>
        <option value="PL">Poland</option>
        <option value="PT">Portugal</option>
        <option value="PR">Puerto Rico</option>
        <option value="QA">Qatar</option>
        <option value="MK">Republic of North Macedonia</option>
        <option value="RO">Romania</option>
        <option value="RU">Russian Federation</option>
        <option value="RW">Rwanda</option>
        <option value="RE">Réunion</option>
        <option value="BL">Saint Barthélemy</option>
        <option value="SH">Saint Helena, Ascension and Tristan da Cunha</option>
        <option value="KN">Saint Kitts and Nevis</option>
        <option value="LC">Saint Lucia</option>
        <option value="MF">Saint Martin (French part)</option>
        <option value="PM">Saint Pierre and Miquelon</option>
        <option value="VC">Saint Vincent and the Grenadines</option>
        <option value="WS">Samoa</option>
        <option value="SM">San Marino</option>
        <option value="ST">Sao Tome and Principe</option>
        <option value="SA">Saudi Arabia</option>
        <option value="SN">Senegal</option>
        <option value="RS">Serbia</option>
        <option value="SC">Seychelles</option>
        <option value="SL">Sierra Leone</option>
        <option value="SG">Singapore</option>
        <option value="SX">Sint Maarten (Dutch part)</option>
        <option value="SK">Slovakia</option>
        <option value="SI">Slovenia</option>
        <option value="SB">Solomon Islands</option>
        <option value="SO">Somalia</option>
        <option value="ZA">South Africa</option>
        <option value="GS">South Georgia and the South Sandwich Islands</option>
        <option value="SS">South Sudan</option>
        <option value="ES">Spain</option>
        <option value="LK">Sri Lanka</option>
        <option value="SD">Sudan</option>
        <option value="SR">Suriname</option>
        <option value="SJ">Svalbard and Jan Mayen</option>
        <option value="SE">Sweden</option>
        <option value="CH">Switzerland</option>
        <option value="SY">Syrian Arab Republic</option>
        <option value="TW">Taiwan (Province of China)</option>
        <option value="TJ">Tajikistan</option>
        <option value="TZ">Tanzania, United Republic of</option>
        <option value="TH">Thailand</option>
        <option value="TL">Timor-Leste</option>
        <option value="TG">Togo</option>
        <option value="TK">Tokelau</option>
        <option value="TO">Tonga</option>
        <option value="TT">Trinidad and Tobago</option>
        <option value="TN">Tunisia</option>
        <option value="TR">Turkey</option>
        <option value="TM">Turkmenistan</option>
        <option value="TC">Turks and Caicos Islands</option>
        <option value="TV">Tuvalu</option>
        <option value="UG">Uganda</option>
        <option value="UA">Ukraine</option>
        <option value="AE">United Arab Emirates</option>
        <option value="GB" selected>United Kingdom</option>
        <option value="UM">United States Minor Outlying Islands</option>
        <option value="US">United States of America</option>
        <option value="UY">Uruguay</option>
        <option value="UZ">Uzbekistan</option>
        <option value="VU">Vanuatu</option>
        <option value="VE">Venezuela (Bolivarian Republic of)</option>
        <option value="VN">Viet Nam</option>
        <option value="VG">Virgin Islands (British)</option>
        <option value="VI">Virgin Islands (U.S.)</option>
        <option value="WF">Wallis and Futuna</option>
        <option value="EH">Western Sahara</option>
        <option value="YE">Yemen</option>
        <option value="ZM">Zambia</option>
        <option value="ZW">Zimbabwe</option>
      </select>


      <label for="txt_search">Search for an address or postcode</label>
      <button type="button" id="btn_search">
          Search
      </button>
      <div class="search_wrap">
          <input type="text" id="txt_search">
      </div>

      <div id="address_selection_container"></div>

      <div id="no_result_message">
          Address not found, please enter manually.
      </div>

      <label for="txt_organsation">Organisation</label>
      <input type="text" id="txt_organsation">


      <label for="txt_addressline1">Address</label>
      <input type="text" id="txt_addressline1">
      <input type="text" id="txt_addressline2">
      <input type="text" id="txt_addressline3">


      <label for="txt_posttown">Town</label>
      <input type="text" id="txt_posttown">


      <label for="txt_postcode">Postcode</label>
      <input type="text" id="txt_postcode">
      
    </form>


    <script>
        
        new PostcoderAddress({
            apikey: 'PCW45-12345-12345-1234X', 
            searchterm: '#txt_search', // query selector of the searchterm input field
            addressselectioncontainer: '#address_selection_container', // container for the address selection drop down
            noresultmessage: '#no_result_message',
            country: '#txt_country',  // Country select list; leave blank if not using a country select list 
            countrycode: '', // Hard code if not using a country select list; leave blank otherwise 
            searchbutton: '#btn_search', 
            organisation: '#txt_organsation',  // Leave blank if form does not have a separate organisation field 
            addressline1: '#txt_addressline1', 
            addressline2: '#txt_addressline2',  // Leave blank if form does not have an addressline2 
            addressline3: '#txt_addressline3',  // Leave blank if form does not have an addressline3 
            //addressline4: '',  // Leave blank if form does not have an addressline4
            county: '', // Leave blank if form does not have a county
            posttown: '#txt_posttown', 
            postcode: '#txt_postcode' 
        })

    </script>


  </body>
</html>
input, select {
	display: block;
	box-sizing: border-box;
	width: 100%;
	padding: 10px;
	height: 40px;
	margin-bottom: 0.5em;
	border-width: 1px;
	border-style: solid;
	border-color: lightgray;
}

.search_wrap {
	overflow: hidden;
}

.search_wrap div {
	font-size: 0.75em;
}

button {
	padding: 8px;
	margin-left: 0.5em;
	float:  right;
	font-family: sans-serif;
}

label {
	display: block;
	margin-top: 1.25em;
	margin-bottom: 0.25em;
}
select {
	position: relative;
	z-index: 1;
	padding-right: 40px;
}

.isvalid:after {
	content: '\2713';
	color: green;
}

.notvalid:after {
	content: '\2717';
    color: red;
}   

#successindicator {
	float:  right;
	margin-left: 0.5em;
	display: flex;
  	justify-content: center;
  	align-content: center;
  	flex-direction: column;
  	height: 40px;
}

#json_result_container {
	margin: 5em 0 0;
    background-color: #eee;
	color: #333;
    /* border: solid lightgrey 1px; */
	padding: 1em;
	overflow: auto;
}

#autocomplete_wrap{
	position: relative;
}

#suggestion_list{
	position:  absolute;
	background-color: #fff;
	outline: -webkit-focus-ring-color auto 1px;
	list-style-type: none;
  	margin: 0;
  	padding: 0;
  	max-height:  400px;
  	overflow-y: auto;
}

#suggestion_list li{
	cursor: pointer;
	padding: 10px 5px;
}

#suggestion_list li.header{
	border-bottom: 2px solid #ddd;
}

#suggestion_list li:hover, #suggestion_list li.selected{
	background-color: #ddd;
}

#suggestion_list li span.location{
	font-size: 0.75em;
	color: #666;
}

.arrow {
 	border: solid black;
	border-width: 0 3px 3px 0;
	display: inline-block;
	padding: 3px;
}

.left {
	margin-left: 3px;
	transform: rotate(135deg);
	-webkit-transform: rotate(135deg);
}

.address{
	height: 140px;
	margin: 8px;
}

.map {
	height: 300px;
	width: 100%;
}

body {
	font-family: sans-serif;
	padding: 0;
	margin: 0;
}
Download this example

Address autocomplete using JavaScript

This example uses the autocomplete/find endpoint to provide real-time suggestions as a user types in a UK or Irish address, and the autocomplete/retrieve endpoint to lookup the full version of a selected address.

Ireland and Eircode: Enable access on your API key using the Data Options page or by contacting us.
class PostcoderAutocomplete{
  
  constructor(config) {
    this.config = config
    this.init()
  }

  init = () => {

    this.suggestionendpoint = 'https://ws.postcoder.com/pcw/autocomplete/find?apikey=' + this.config.apikey
    this.retrieveendpoint = 'https://ws.postcoder.com/pcw/autocomplete/retrieve?apikey=' + this.config.apikey
    this.cache = []
    this.suggestionhierarchy = []
    this.suggestions = []
    this.searchterm = ''
    this.selectedoptiontext = ''
    this.pathfilter = ''
    this.selectedIndex = -1
    this.no_results_message = 'No addresses found'
    this.inputdelay = 300

    this.suggestionlist = document.querySelector(this.config.suggestions)
    this.input = document.querySelector(this.config.searchterm)

    this.input.setAttribute('type', 'search')
    this.input.setAttribute('autocomplete', 'off')
    this.input.setAttribute('autocapitalize', 'off')
    this.input.setAttribute('autocorrect', 'off')
    this.input.setAttribute('spellcheck', 'false')

    this.input.addEventListener('input', this.handleInput)
    this.input.addEventListener('focus', this.handleFocus)
    this.input.addEventListener('keydown', this.handleKeyDown)

    this.suggestionlist.addEventListener('click', this.handleSuggestionClick)

    // add click event listener to the document, to hide the suggestions when clicked away
    document.body.addEventListener('click', this.handleDocumentClick)

    // determine the number of addresslines required
    this.addresslines = 0
    for (let i = 1; i <= 4; i++) {
      if( this.config['addressline'+i] !== ''){
        this.addresslines ++
      }
    }    

  }

  getSuggestions = event =>{

    this.searchterm = encodeURIComponent(this.input.value.trim())

    // require a minimum of three characters
    if(this.searchterm.length < 3){
      this.hideSuggestions()
      return
    }

    let url = this.suggestionendpoint + '&country=' + this.getCountry() + '&query=' + this.searchterm

    if(this.pathfilter){
      url += '&pathfilter=' + this.pathfilter
    }else{
      this.selectedoptiontext = this.searchterm
    }

    let index = this.cache.findIndex(c => c.url === url)

    if( index >= 0){

      // use cached data
      this.suggestions = this.cache[index].suggestions
      this.addSuggestionHierarchy(index)
      this.showSuggestions()

    }else{

      fetch(url)
        .then( response => {
          if (!response.ok) { 
            throw response 
          }
          return response.json()
        })
        .then( json => {
          this.suggestions = json
          this.addCache(url)
          this.addSuggestionHierarchy(this.cache.length - 1)          
          this.showSuggestions()
        })
        .catch( err => {

          if(typeof err.text === 'function'){
            err.text().then( errorMessage => {
              console.log('Postcoder request error ' + err.status + ' : ' + errorMessage)
            })
          }else{
            console.log(err)
          }

      })

    }
  }

  addCache = url => {

    let obj = {}
    obj.url = url
    obj.suggestions = this.suggestions
    obj.label = this.selectedoptiontext
    this.cache.push(obj)

  }

  newSuggestionsReset = () => {

    // remove previous options
    this.hideSuggestions()
    this.pathfilter = ''

    this.suggestionlist.scrollTop = 0
    this.selectedIndex = -1

  }

  suggestionsHierarchyReset = () => {
    //reset suggestionHierarchy
    this.suggestionhierarchy = []
  }

  addSuggestionHierarchy = index => {

    // store the cache entry index for each suggestion level selected
    this.suggestionhierarchy.push(index)

  }

  handleSuggestionClick = event => {

    event.stopPropagation()

    let target = event.target

    // if click was not directly on the <li>, but a child, find the <li> in parent
    while(target.tagName.toLowerCase() !== 'li' ){
      target = target.parentNode
    }

    this.selectSuggestion(target)

  }

  selectSuggestion = target => {

    this.selectedoptiontext = target.innerHTML

    if(target.getAttribute('data-type') == 'CACHE'){
      // back to previous results using cached suggestions
      this.suggestions = this.cache[target.getAttribute('data-id')].suggestions
      this.suggestionhierarchy.pop()
      this.showSuggestions()

    }else if(target.getAttribute('data-type') == 'ADD'){  
      // if the type is an address, retrieve it using the id
      this.retrieve(target.getAttribute('data-id'))
    }else{
      // get more suggestions, using the id
      this.pathfilter = target.getAttribute('data-id')
      this.getSuggestions()
    }    
        
  }

  retrieve = id => {

    var url = this.retrieveendpoint + '&country=' + this.getCountry() + '&query=' + this.searchterm + '&id=' + id + '&lines='+this.addresslines + '&exclude=organisation,country'

    // fetch the json formatted result from Postcoder and pass it to processResult
    fetch(url)
      .then( response => {
        if (!response.ok) { 
          throw response 
        }
        return response.json()
      })
      .then( addresses => {
        // always one result, use the first array item
        this.cache[url] = addresses[0]
        this.processResult(addresses[0])
      })
      .catch( err => {

        if(typeof err.text === 'function'){
          err.text().then( errorMessage => {
            console.log('Postcoder request error ' + err.status + ' : ' + errorMessage)
          })
        }else{
          console.log(err)
        }
    })
  }

  showSuggestions = () => {

    this.newSuggestionsReset()

    if( this.suggestions.length === 0 ){
      // show no results message in ul
      let option = document.createElement('li')
      option.innerHTML = this.no_results_message
      this.suggestionlist.appendChild(option)

    }
    else{

      if(this.suggestionhierarchy.length > 1){
        // a suggestion was selected so show previous option
        let cacheid = this.suggestionhierarchy[this.suggestionhierarchy.length - 2] // .length -1 is current suggestions
        let option = document.createElement('li')   
        option.classList.add('header')     
        option.innerHTML = '<i class="arrow left"></i> ' + unescape(this.cache[cacheid].label)
        option.setAttribute('data-id', cacheid)
        option.setAttribute('data-type', 'CACHE')
        this.suggestionlist.appendChild(option)

      }

      for (let i = 0; i < this.suggestions.length; i++) {

        let option = document.createElement('li')

        let suggestiontext = this.suggestions[i].summaryline + ' ' + '<span class="location">' + this.suggestions[i].locationsummary + '</span>'

        if(this.suggestions[i].count > 1){

          let count = this.suggestions[i].count > 100 ? '100+' : this.suggestions[i].count
          suggestiontext += ' <span class="count">(' + count + ' addresses)</span>'

        }

        option.innerHTML = suggestiontext 

        // add the id and type attibutes to the option
        option.setAttribute('data-id', this.suggestions[i].id)
        option.setAttribute('data-type', this.suggestions[i].type)

        this.suggestionlist.appendChild(option)

      }
    }
  }

  getCountry = () => {

    return (typeof this.config.countrycode !== 'undefined' && this.config.countrycode !== '') 
      ? this.config.countrycode 
      : document.querySelector(this.config.country).value
    
  }

  processResult = address => {

    this.hideSuggestions()

    let fields = ['organisation','addressline1','addressline2','addressline3','addressline4','posttown','county','postcode']

    //populate the address form  
    for (let i = 0; i < fields.length; i++) {
      let field_selector = this.config[fields[i]]
      if(typeof field_selector !== 'undefined' && field_selector !== ''){
        document.querySelector(field_selector).value = (typeof address[fields[i]] !== 'undefined') ? address[fields[i]] : ''
      }
    }
  }

  handleDocumentClick = event => {

    if (this.suggestionlist.contains(event.target) || this.input.contains(event.target)) {
      return
    }

    this.hideSuggestions()

  }

  hideSuggestions = () => {

    // clear the ul list
    this.suggestionlist.innerHTML = ''

  }

  handleKeyDown = event => {

    const { key } = event

    switch (key) {
      case 'Up':
      case 'Down':
      case 'ArrowUp':
      case 'ArrowDown': {
        const selectedIndex =
          key === 'ArrowUp' || key === 'Up'
            ? this.selectedIndex - 1
            : this.selectedIndex + 1
        event.preventDefault()
        this.handleArrows(selectedIndex)
        break
      }
      case 'Tab': {
        this.handleTab(event)
        break
      }
      case 'Enter': {
        this.selectSuggestion( this.suggestionlist.querySelectorAll('li')[this.selectedIndex] )
        break
      }
      case 'Esc':
      case 'Escape': {
        this.hideSuggestions()
        this.setValue()
        break
      }
      default:
        return
    }
  }

  handleArrows = selectedIndex => {

    // Loop selectedIndex back to first or last result if out of bounds
    let suggestionsCount = this.suggestions.length

    if(this.suggestionhierarchy.length > 1){
      // add previous suggestion
      suggestionsCount++
    }

    if(this.suggestionlist.querySelectorAll('li').length > 0){

      if(this.selectedIndex >= 0){
        // clear the previously selected class
        this.suggestionlist.querySelectorAll('li')[this.selectedIndex].classList.remove('selected')
      }

      this.selectedIndex = ((selectedIndex % suggestionsCount) + suggestionsCount) % suggestionsCount

      // set the selected class
      this.suggestionlist.querySelectorAll('li')[this.selectedIndex].classList.add('selected')

      // scroll into view
      this.suggestionlist.querySelectorAll('li')[this.selectedIndex].scrollIntoView(false)

    }
  }

  handleTab = event => {
    if(this.selectedIndex >= 0){
      event.preventDefault()
      this.selectSuggestion( this.suggestionlist.querySelectorAll('li')[this.selectedIndex] )
    }else{
      this.hideSuggestions()
    }
  }

  handleInput = () => {
    this.suggestionsHierarchyReset()
    clearTimeout(this.debounce);
    this.debounce = setTimeout(() => this.getSuggestions(), this.inputdelay)
  }

  handleFocus = () => {
    if(this.suggestions.length > 0){
      this.showSuggestions()
    }else{
      this.getSuggestions()
    }
  }

}
<!doctype html>
<html lang="en">
  <head>
      <link rel="stylesheet" href="postcoder.css" >   
      <script src="postcoder_autocomplete.js"></script>
  </head>
  <body>

    <form>
            
      <label for="txt_country">Country</label>
      <select id="txt_country">
        <option value="IE">Ireland</option>
        <option value="GB" selected>United Kingdom</option>
      </select>


      <div class="autocomplete_wrap">
        <label for="txt_search">Search for an address or postcode</label>
        <input id="txt_search">
        <ul id="suggestion_list"></ul>
      </div>

      <label for="txt_organsation">Organisation</label>
      <input type="text" id="txt_organsation">


      <label for="txt_addressline1">Address</label>
      <input type="text" id="txt_addressline1">
      <input type="text" id="txt_addressline2">
      <input type="text" id="txt_addressline3">


      <label for="txt_posttown">Town</label>
      <input type="text" id="txt_posttown">


      <label for="txt_postcode">Postcode</label>
      <input type="text" id="txt_postcode">
      
    </form>


    <script>
        
        new PostcoderAutocomplete({
            apikey: 'PCW45-12345-12345-1234X', 
            searchterm: '#txt_search', // query selector of the searchterm input field
            suggestions: '#suggestion_list', // query selector for preview datalist
            country: '#txt_country',  // Country select list; leave blank if not using a country select list 
            countrycode: '', // Hard code if not using a country select list; leave blank otherwise 
            organisation: '#txt_organsation',  // Leave blank if form does not have a separate organisation field 
            addressline1: '#txt_addressline1', 
            addressline2: '#txt_addressline2',  // Leave blank if form does not have an addressline2 
            addressline3: '#txt_addressline3',  // Leave blank if form does not have an addressline3 
            //addressline4: '',  // Leave blank if form does not have an addressline4
            county: '', // Leave blank if form does not have a county
            posttown: '#txt_posttown', 
            postcode: '#txt_postcode' 
        })

    </script>


  </body>
</html>
input, select {
	display: block;
	box-sizing: border-box;
	width: 100%;
	padding: 10px;
	height: 40px;
	margin-bottom: 0.5em;
	border-width: 1px;
	border-style: solid;
	border-color: lightgray;
}

.search_wrap {
	overflow: hidden;
}

.search_wrap div {
	font-size: 0.75em;
}

button {
	padding: 8px;
	margin-left: 0.5em;
	float:  right;
	font-family: sans-serif;
}

label {
	display: block;
	margin-top: 1.25em;
	margin-bottom: 0.25em;
}
select {
	position: relative;
	z-index: 1;
	padding-right: 40px;
}

.isvalid:after {
	content: '\2713';
	color: green;
}

.notvalid:after {
	content: '\2717';
    color: red;
}   

#successindicator {
	float:  right;
	margin-left: 0.5em;
	display: flex;
  	justify-content: center;
  	align-content: center;
  	flex-direction: column;
  	height: 40px;
}

#json_result_container {
	margin: 5em 0 0;
    background-color: #eee;
	color: #333;
    /* border: solid lightgrey 1px; */
	padding: 1em;
	overflow: auto;
}

#autocomplete_wrap{
	position: relative;
}

#suggestion_list{
	position:  absolute;
	background-color: #fff;
	outline: -webkit-focus-ring-color auto 1px;
	list-style-type: none;
  	margin: 0;
  	padding: 0;
  	max-height:  400px;
  	overflow-y: auto;
}

#suggestion_list li{
	cursor: pointer;
	padding: 10px 5px;
}

#suggestion_list li.header{
	border-bottom: 2px solid #ddd;
}

#suggestion_list li:hover, #suggestion_list li.selected{
	background-color: #ddd;
}

#suggestion_list li span.location{
	font-size: 0.75em;
	color: #666;
}

.arrow {
 	border: solid black;
	border-width: 0 3px 3px 0;
	display: inline-block;
	padding: 3px;
}

.left {
	margin-left: 3px;
	transform: rotate(135deg);
	-webkit-transform: rotate(135deg);
}

.address{
	height: 140px;
	margin: 8px;
}

.map {
	height: 300px;
	width: 100%;
}

body {
	font-family: sans-serif;
	padding: 0;
	margin: 0;
}
Download this example

Address lookup using Python, PHP or C#

These examples show how to make a request to the address endpoint to look up a UK address.

from urllib.parse import quote
import requests
import json

# Request parameters
api_key = "PCW45-12345-12345-1234X"
country_code = "UK"
search_term = "NR14 7PZ"

# Prepare request and encode user-entered parameters with %xx encoding
request_url = f"https://ws.postcoder.com/pcw/{api_key}/address/{country_code}/{quote(search_term, safe='')}"

# Send request
response = requests.get(request_url)

# Process response
if response.status_code == 200:
    json = response.json()
    if len(json) > 0:
        for address in json:
            print(address["summaryline"])
    else:
        print("No results")
else:
    print(f"Request error: {response.content.decode()}")
// Request parameters
$api_key = "PCW45-12345-12345-1234X";
$country_code = "UK";
$search_term = "NR14 7PZ";

// Prepare request and encode user-entered parameters with %xx encoding
$request_url = "https://ws.postcoder.com/pcw/$api_key/address/$country_code/" . urlencode($search_term);

// Send request
$result = file_get_contents($request_url, false, stream_context_create(["http" => ["ignore_errors" => true]]));

// Process response
$status_line = $http_response_header[0];
preg_match("{HTTP\/\S*\s(\d{3})}", $status_line, $match);
$status_code = $match[1];

if ($status_code == 200) {
    $json = json_decode($result);
    if (count($json) > 0) {
      foreach ($json as $address) {
        echo($address->summaryline . "<br>");
      }
    } else {
      echo("No results");
    }
} else {
    echo("Request error");
}
using System;
using System.Threading.Tasks;
using System.Web;
using System.Net.Http;
using Newtonsoft.Json.Linq;
					
public class Program
{
	public static async Task Main()
	{
		// Request parameters
		string apiKey = "PCW45-12345-12345-1234X";
		string countryCode = "UK";
		string searchTerm = "NR14 7PZ";

		// Prepare request and encode user-entered parameters with %xx encoding
		string requestUrl = $"https://ws.postcoder.com/pcw/{apiKey}/address/{countryCode}/{HttpUtility.UrlEncode(searchTerm)}";

		using (HttpClient client = new HttpClient())
		{
			// Send request
			var response = await client.GetAsync(requestUrl);
			var responseContent = await response.Content.ReadAsStringAsync();

			// Process response
			if (response.IsSuccessStatusCode)
			{
				JArray responseJson = JArray.Parse(responseContent);
				
				if (responseJson.Count > 0)
				{
					foreach (JObject address in responseJson)
					{
						Console.WriteLine($"{address["summaryline"]}");	
					}
				}
				else
				{
					Console.WriteLine("No results");
				}
			}
			else
			{
				Console.WriteLine($"Request error: {responseContent}");
			}
		}
	}
}

Community examples