# Address autocomplete The address search endpoint provides type-ahead suggestions as the customer types their address. It uses an expand/resolve pattern that handles hierarchical address structures — like UK streets with many buildings — while still working simply for flat address systems. ## Prerequisites - An Ingrid API key - An address form rendered in your checkout (see [rendering the address form](/developer-resources/ingrid-api/guides/address-form)) ## Overview The autocomplete flow follows a tree pattern. Each prediction the API returns has an `action` that tells you what to do next: ```mermaid flowchart TD A[Customer types in address field] --> B[GET /address/search] B --> C{Check action} C -->|resolve| D[GET /address/details/id] D --> E[Populate form fields] C -->|expand| F[GET /address/search with containerId] F --> C ``` - **`resolve`** — this prediction is a specific address. Call the details endpoint to get the full `DeliveryAddress`. - **`expand`** — this prediction is a container (a street, a building, a postal code area). Call search again with `containerId` to drill down into it. ## Step 1: Search for addresses As the customer types, send their input to the search endpoint: ```bash Request curl -X GET "https://api.ingrid.com/v1/delivery/address/search?countryCode=GB&query=10%20Bucking" \ -H "Authorization: Bearer " ``` ```json Response { "predictions": [ { "id": "addr_gbr_10045832", "label": "10 Buckingham Road", "secondaryLabel": "Redcar, TS10 3JQ", "action": "resolve", "type": "streetAddress" }, { "id": "grp_street_882", "label": "10 Buckingham Street", "secondaryLabel": "3 addresses", "action": "expand", "count": 3, "type": "street" }, { "id": "addr_gbr_20091744", "label": "10 Buckingham Gate", "secondaryLabel": "London, SW1E 6LB", "action": "resolve", "type": "streetAddress" } ] } ``` Display the predictions as a dropdown list. Use `label` as the primary text and `secondaryLabel` as secondary context. The `type` field can be used to select an icon (street, building, postal code, etc.). ## Step 2: Handle the action When the customer selects a prediction, check its `action`: ### If `action` is `resolve` The prediction is a specific address. Proceed to [Step 3](#step-3-resolve-to-full-address). ### If `action` is `expand` The prediction is a container with child addresses. Call search again with the prediction's `id` as `containerId`: ```bash Request curl -X GET "https://api.ingrid.com/v1/delivery/address/search?countryCode=GB&containerId=grp_street_882" \ -H "Authorization: Bearer " ``` ```json Response { "predictions": [ { "id": "addr_gbr_30012001", "label": "Flat 1, 10 Buckingham Street", "secondaryLabel": "London, WC2N 6DF", "action": "resolve", "type": "premise" }, { "id": "addr_gbr_30012002", "label": "Flat 2, 10 Buckingham Street", "secondaryLabel": "London, WC2N 6DF", "action": "resolve", "type": "premise" }, { "id": "addr_gbr_30012003", "label": "Flat 3, 10 Buckingham Street", "secondaryLabel": "London, WC2N 6DF", "action": "resolve", "type": "premise" } ] } ``` Display the new predictions. The `count` field on the parent prediction tells you how many children to expect, which you can use to show "3 addresses" in the UI before expanding. Expanding can be recursive — a container may contain more containers — but in practice most lookups resolve within one or two levels. ## Step 3: Resolve to full address When the customer selects a prediction with `action: "resolve"`, call the details endpoint with its `id`: ```bash Request curl -X GET "https://api.ingrid.com/v1/delivery/address/details/addr_gbr_10045832" \ -H "Authorization: Bearer " ``` ```json Response { "deliveryAddress": { "countryCode": "GB", "postalCode": "TS10 3JQ", "addressLines": ["10 Buckingham Road"], "locality": "Redcar" } } ``` ## Step 4: Populate the form Map the returned `DeliveryAddress` fields to your form inputs. The field names in the response match the field names from the [form endpoint](/developer-resources/ingrid-api/guides/address-form), so the mapping is direct. After populating, allow the customer to review and edit the pre-filled values before proceeding. ## The focus parameter The optional `focus` parameter scopes autocomplete behavior to a specific form field. This is useful when the customer is editing an individual field rather than typing a full address: | `focus` value | Behavior | | --- | --- | | `addressLines` | Search street addresses (default behavior) | | `postalCode` | Search by postal code. Useful for postal code lookups (PAF-style) | | `locality` | Search city or town names | | `administrativeArea` | Search states, provinces, or regions | ```bash Example: postal code focused search curl -X GET "https://api.ingrid.com/v1/delivery/address/search?countryCode=GB&query=SW1A&focus=postalCode" \ -H "Authorization: Bearer " ``` ## Debouncing and performance The search endpoint is designed for real-time use, but you should still debounce requests on the client side. A 200-300ms debounce after the last keystroke prevents excessive API calls without hurting perceived responsiveness. Do not call search with fewer than 2-3 characters — the results will be too broad to be useful. ## Error handling | Error | When it occurs | | --- | --- | | `400 Bad Request` | Invalid or missing `countryCode` | | `404 Not Found` | The `id` passed to the details endpoint does not exist or has expired | | `500 Internal Server Error` | Server-side issue — retry with exponential backoff | Prediction IDs are opaque and may expire. If a details call returns `404`, prompt the customer to search again. ## Next steps - [Address validation](/developer-resources/ingrid-api/guides/address-validation) — verify the resolved address before creating an order - [Country reference](/developer-resources/ingrid-api/guides/country-reference) — country-specific addressing rules