Address search
Address search fills in an address for your checkout. Your customer types a few letters and picks a suggestion, or drops a pin on a map. You get the full address, with the lga and state a quote needs and a place_id that makes the spot exact. Addresses come from Google and are in Nigeria.
Address search is free.
| Endpoint | Library method | What it does |
|---|---|---|
GET /addresses/autocomplete | addresses.autocomplete | Suggestions for what your customer has typed so far |
GET /addresses/details | addresses.details | The full address of the suggestion they chose |
GET /addresses/reverse | addresses.reverse | The address at a map pin |
The Node.js, PHP and Python libraries have these methods from version 0.2.0, on reeds.shipping.addresses. Call them from your server, as you do every live call: your page calls your server, and your server calls Reeds.
Search as your customer types
Make a session token when your customer starts typing an address. A UUID works. Send the same token on every call while they type that address, and on the call that gets the place they pick. The whole search then counts as one. Start a new token for the next address.
- Node.js
- PHP
- Python
- cURL
import { randomUUID } from 'node:crypto';
import Reeds from 'reeds-sdk';
const reeds = new Reeds();
const sessionToken = randomUUID(); // one per address being typed
const { suggestions } = await reeds.shipping.addresses.autocomplete({ query: '23 Allen Avenue', session_token: sessionToken });
for (const suggestion of suggestions) {
console.log(suggestion.place_id, suggestion.main_text, suggestion.secondary_text);
}
$reeds = new Reeds\Reeds();
$sessionToken = bin2hex(random_bytes(16)); // one per address being typed
$found = $reeds->shipping->addresses->autocomplete(['query' => '23 Allen Avenue', 'session_token' => $sessionToken]);
foreach ($found['suggestions'] as $suggestion) {
echo $suggestion['place_id'], ' ', $suggestion['main_text'], ', ', $suggestion['secondary_text'], PHP_EOL;
}
import uuid
from reeds import Reeds
reeds = Reeds()
session_token = str(uuid.uuid4()) # one per address being typed
found = reeds.shipping.addresses.autocomplete(query="23 Allen Avenue", session_token=session_token)
for suggestion in found.suggestions:
print(suggestion.place_id, suggestion.main_text, suggestion.secondary_text)
curl "https://api.getreeds.co/shipping/v1/addresses/autocomplete?query=23%20Allen%20Avenue&session_token=3f2c8d1e-7b4a-4c55-9e0d-2a6b1f9c8e70" \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN"
{
"status": "success",
"data": {
"suggestions": [
{ "place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4", "main_text": "23 Allen Avenue", "secondary_text": "Ikeja, Lagos, Nigeria" },
{ "place_id": "ChIJ8TQy0JKLOxARmZ9bJc2sVkA", "main_text": "Allen Avenue Roundabout", "secondary_text": "Ikeja, Lagos, Nigeria" }
]
}
}
At most 6 suggestions come back, best first. An empty list means nothing matched. Wait until your customer pauses typing (about 300 milliseconds) before each call.
Get the place they chose
Send the suggestion's place_id, with the same session token.
- Node.js
- PHP
- Python
- cURL
const place = await reeds.shipping.addresses.details({ place_id: 'ChIJN1t_tDeuEmsRUsoyG83frY4', session_token: sessionToken });
console.log(place.formatted_address, place.lga, place.state, place.precise);
$place = $reeds->shipping->addresses->details(['place_id' => 'ChIJN1t_tDeuEmsRUsoyG83frY4', 'session_token' => $sessionToken]);
echo $place['formatted_address'], ' ', $place['lga'] ?? 'no LGA', ' ', $place['state'];
place = reeds.shipping.addresses.details(place_id="ChIJN1t_tDeuEmsRUsoyG83frY4", session_token=session_token)
print(place.formatted_address, place.lga, place.state, place.precise)
curl "https://api.getreeds.co/shipping/v1/addresses/details?place_id=ChIJN1t_tDeuEmsRUsoyG83frY4&session_token=3f2c8d1e-7b4a-4c55-9e0d-2a6b1f9c8e70" \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN"
{
"status": "success",
"data": {
"place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
"name": "23 Allen Avenue",
"formatted_address": "23 Allen Ave, Allen, Ikeja 101233, Lagos, Nigeria",
"area": "Ikeja",
"lga": "Ikeja",
"state": "Lagos",
"country": "NG",
"latitude": 6.6018,
"longitude": 3.3515,
"precise": true
}
}
| Field | Use it for |
|---|---|
place_id | The quote's place_id. The spot is then exact. |
formatted_address | The quote's address text, or what you show your customer. |
area, lga, state | The quote's area, lga and state. |
precise | true for a street address, building or business. false for a whole area or road, whose point is only its middle: ask your customer for the street. |
lga is null when Google doesn't name one. Ask your customer for it, because a quote needs it.
place_id is Google's, from a suggestion. The adr_ id on a delivery's pickup and dropoff names that stop's address, and isn't a place id: sending one gets 422 INVALID_REQUEST.
Find the address at a map pin
- Node.js
- PHP
- Python
- cURL
const pin = await reeds.shipping.addresses.reverse({ latitude: 6.6018, longitude: 3.3515 });
console.log(pin.formatted_address, pin.place_id);
$pin = $reeds->shipping->addresses->reverse(['latitude' => 6.6018, 'longitude' => 3.3515]);
echo $pin['formatted_address'], ' ', $pin['place_id'];
pin = reeds.shipping.addresses.reverse(latitude=6.6018, longitude=3.3515)
print(pin.formatted_address, pin.place_id)
curl "https://api.getreeds.co/shipping/v1/addresses/reverse?latitude=6.6018&longitude=3.3515" \
-H "Authorization: Bearer $REEDS_ACCESS_TOKEN"
The answer is a place, the same shape as above: the address Google finds nearest the pin, with its own coordinates. Each pin is one search.
To deliver to the pin itself, send your pin's latitude and longitude in the quote, with this address as the text. To deliver to the address found, send its place_id.
A pin outside Nigeria gets 422 INVALID_REQUEST. A pin with no address near it gets 404 NOT_FOUND.
Use it in a quote
Give the quote the place's address text, lga, state and place_id, and its area when it has one.
- Node.js
- PHP
- Python
- cURL
if (!place.lga) throw new Error('Ask your customer for the LGA.');
const quote = await reeds.shipping.quotes.create({
pickup: {
name: 'Tola Fabrics',
phone: '08051234567',
address: place.formatted_address,
area: place.area ?? undefined,
lga: place.lga,
state: place.state,
place_id: place.place_id,
},
dropoff: { name: 'Chinedu Eze', phone: '08098765432', address: '14 Admiralty Way', area: 'Lekki Phase 1', lga: 'Eti-Osa', state: 'Lagos' },
package: { description: '2 pairs of sneakers', quantity: 1, weight_kg: 1.5 },
});
if ($place['lga'] === null) {
exit('Ask your customer for the LGA.');
}
$pickup = [
'name' => 'Tola Fabrics',
'phone' => '08051234567',
'address' => $place['formatted_address'],
'lga' => $place['lga'],
'state' => $place['state'],
'place_id' => $place['place_id'],
];
if ($place['area'] !== null) {
$pickup['area'] = $place['area'];
}
$quote = $reeds->shipping->quotes->create([
'pickup' => $pickup,
'dropoff' => ['name' => 'Chinedu Eze', 'phone' => '08098765432', 'address' => '14 Admiralty Way', 'area' => 'Lekki Phase 1', 'lga' => 'Eti-Osa', 'state' => 'Lagos'],
'package' => ['description' => '2 pairs of sneakers', 'quantity' => 1, 'weight_kg' => 1.5],
]);
from reeds.shipping import AddressInputParam
if place.lga is None:
raise ValueError("Ask your customer for the LGA.")
pickup: AddressInputParam = {
"name": "Tola Fabrics",
"phone": "08051234567",
"address": place.formatted_address,
"lga": place.lga,
"state": place.state,
"place_id": place.place_id,
}
if place.area:
pickup["area"] = place.area
quote = reeds.shipping.quotes.create(
pickup=pickup,
dropoff={"name": "Chinedu Eze", "phone": "08098765432", "address": "14 Admiralty Way", "area": "Lekki Phase 1", "lga": "Eti-Osa", "state": "Lagos"},
package={"description": "2 pairs of sneakers", "quantity": 1, "weight_kg": 1.5},
)
{
"name": "Tola Fabrics",
"phone": "08051234567",
"address": "23 Allen Ave, Allen, Ikeja 101233, Lagos, Nigeria",
"area": "Ikeja",
"lga": "Ikeja",
"state": "Lagos",
"place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4"
}
Allowance and limits
| Test mode | Live mode | |
|---|---|---|
| Searches | 50 in all to start. Reeds can raise it. | Unlimited, unless Reeds has set a monthly limit for your account |
| Past it | 403 ADDRESS_SEARCH_LIMIT_REACHED | 403 ADDRESS_SEARCH_LIMIT_REACHED until the 1st of the next month |
One search is one typed address (every call with one session token), a place looked up without a session token, or one pin. A search you started can always finish, even when it takes you to the limit.
Reeds can switch address search off for an account in Live. Live searches then get 403 ADDRESS_SEARCH_DISABLED. To raise your test allowance or ask about a limit, email support@getreeds.co with your client id.
The libraries raise both as their permission error (PermissionDeniedError in Node.js and Python, PermissionDeniedException in PHP), with the code on the error. They don't retry it: a retry would get the same answer.
Address search has its own rate limit: 120 requests a minute on business accounts and 600 on platform accounts. See Rate limits.
Show where the addresses come from
The addresses are Google's, so Google's display rules apply:
- Show the Google logo or the words "Powered by Google" next to suggestions that aren't on a Google map.
- Show a pin on a Google map, not another map provider's.
Reeds can switch off address search for an account that doesn't follow them.