CnterDocumentationSign in

Start here

  • What Cnter is
  • Core concepts
  • Quickstart

Platform

  • Authentication
  • Conventions
  • Errors
  • Organization
  • The dashboard

Modules

  • Content Management
  • Online Ordering
  • Restaurant Ordering
  • Promotions
  • Reservations
  • Bookings
  • Contact Form

Payments

  • AgnusPAY
  • Tax

Services

  • Address autocomplete
  • Video
  • Email

Reference

  • API reference

Services

Address autocomplete

Keyless, worldwide address suggestions that come back in the exact shape checkout expects.

A full brief for whoever builds against this.

Four address fields typed by hand is where delivery orders go wrong: transposed postcodes, missing house-number letters, and people who give up halfway. This endpoint replaces them. No key, no account, no billing on your side. Cnter supplies the data and pays for it, and you need a front end and nothing else.

Suggesting#

POST/api/client/v1/{organizationId}/address/searchPublic

Address suggestions for what the buyer has typed so far.

json
{ "q": "damrak 1", "limit": 5 }

A POST that only reads

What the buyer types goes in the body, not in the URL. A query string is part of the request line every platform writes to its logs, and this one is somebody’s home address — so the verb follows where the data ends up rather than what the call does. The older GET …/address/suggest?q= keeps answering for anything already built on it.

json
{
  "success": true,
  "data": {
    "suggestions": [
      {
        "id": "WyJEYW0iLCIxIiw...",
        "label": "Dam 1, 1012 JS Amsterdam, Netherlands",
        "deliverable": true,
        "address": {
          "street": "Dam",
          "house_number": "1",
          "postal_code": "1012 JS",
          "city": "Amsterdam",
          "country": "NLD"
        }
      }
    ]
  }
}

Render label. Debounce at around 250 milliseconds: a request per keystroke is wasted on a list nobody reads. Queries under three characters return an empty list without calling anything.

deliverable is true for a full address and false for a street or a district. It is advisory. Show the difference if you like, but let the buyer pick either and complete the rest by hand.

The shape already matches#

address is exactly what fulfillment.address expects at checkout, so picking a suggestion is an assignment rather than a mapping.

js
function onSuggestionPicked(suggestion) {
  if (!suggestion.address) return          // leave what the buyer typed

  // Same field names as fulfillment.address. Assign across, do not rename.
  const { street, house_number, postal_code, city, country } = suggestion.address
  form.street      = street
  form.houseNumber = house_number
  form.postalCode  = postal_code
  form.city        = city
  form.country     = country
}

Do not rename anything on the way

Remapping by hand is exactly how house_number becomes housenumber, and the checkout rejects that with a 400 naming the key. The names line up for a reason.

The lookup endpoint#

GET/api/public/{organizationId}/address/lookup?id=Public

Returns the full address for a chosen suggestion id.

Optional, and new code should skip it. It returns exactly what suggest already gave you inline, and exists only for integrations built against the earlier two-step flow.

Coverage#

Worldwide, and house-number accurate across Europe, the Americas, most of Asia, the Middle East, Africa and Oceania. Two known gaps:

  • /Mainland China returns nothing at street level, because foreign providers may not serve detailed Chinese map data.
  • /Japanese addresses are block-based rather than street-and-number, so they do not fit these four fields.

Both come back as an empty list, which is exactly why the plain fields have to stay usable. Your customer can bias results towards their own country in the dashboard, which sharpens short queries. You pass nothing for that.

Two rules that keep it robust#

  1. 01

    Keep the plain fields editable

    Fill them from the suggestion, then let the buyer correct them. Addresses exist that no register knows about, and a form that refuses a real address loses a real order.

  2. 02

    Treat failure as cosmetic

    On 502 PROVIDER_UNAVAILABLE, on 429 QUOTA_EXCEEDED, or on an empty list, show the normal inputs and carry on. Autocomplete is a convenience. It must never block a checkout.

In the page. The script knows the address; you know the name.
const cnter = await window.cnter.ready

let timer
function onAddressInput(text) {
  clearTimeout(timer)
  timer = setTimeout(async () => {
    try {
      const res = await cnter.restaurant.suggest({ q: text })
      renderSuggestions(res.data?.suggestions ?? [])
    } catch {
      // Swallowed on purpose: the plain fields below stay editable, so a
      // provider being down costs a convenience, not the order.
      renderSuggestions([])
    }
  }, 250)
}

Safe in the browser#

This is one of the few endpoints meant to be called from a page. It is public, CORS-open and carries no key, because the alternative is proxying every keystroke through your own server for no benefit.

PreviousTaxNextVideo

On this page

  • Suggesting
  • The shape already matches
  • The lookup endpoint
  • Coverage
  • Two rules that keep it robust
  • Safe in the browser