YardCode Address Picker

One script tag on your own form. Your user types their address, drags a pin onto their roof, and you receive a YardCode you can trust.

What you get back

{
  "yardcode":              "GQ9 U88 vowu",      // the pin they confirmed
  "lat": 7.3731041, "lng": 3.8678222,
  "accuracy_m":            12,                   // only when it came from GPS
  "method":                "pin",                // address | coordinates | yardcode | gps | pin
  "typed_address":         "20 Oba Adesida Road, Iyaganku GRA, Ibadan",
  "street_address":        "Oba Adesida Rd, Ibadan, Oyo",   // if a geocoder knew it
  "unit":                  "Block C, 3rd floor, Flat 2",    // from the separate fields
  "landmark":              "Behind the big church",
  "house_number":          "16",
  "street":                "Oba Adesida Road",
  "estate":                "Iyaganku GRA",
  "town":                  "Ibadan",
  "address_yardcode":      "GQ9 U87 pumi",       // where the WORDS alone pointed
  "address_uncertainty_m": 140,                  // how precisely the words placed it
  "ward": "Alesinloye", "lga": "Ibadan South West", "state": "Oyo State",

  "what_is_here": {                              // what is at the spot
    "checked": true, "category": "building",
    "label": "Building", "detail": "Residential building",
    "confidence": "mapped",
    "near": { "road": { "name": "Iwo Road", "m": 9.0 } }
  },
  "building": {                                  // only when it is a building
    "yardcode": "GQ9 U88 teza", "type": "Residential building",
    "spans_yards": 2,
    "split": [ { "yard": "GQ9 U88", "pct": 59.5 },
               { "yard": "GQ9 U89", "pct": 40.5 } ]
  },
  "street_address": {                            // the national register
    "text": "Plot 7, Block C, 12 Bodija Estate Road, Ibadan South West LGA, Oyo State",
    "plot": "7", "block": "C", "unit": "",       // empty strings when unknown
    "house_number": "12", "side": "R",
    "street": "Bodija Estate Road", "street_id": "OY-ISW-S0042",
    "street_status": "named",
    "provisional": false, "confidence": "high",
    "ward": "Alesinloye", "lga": "Ibadan South West", "state": "Oyo"
  },
  "building_yardcode":     "GQ9 U88 teza",
  "place_category":        "building",
  "address_yardcode":      "GQ9 U88 teza",       // STORE THIS as the address

  "token":                 "wid_….1790000000.a1b2…"
}

The street address

Where the national register covers the state, a building also comes with its own street address. street_status says how firm the street name is: named from the map, approved by the local government, awaiting_name for a placeholder, name_proposed while a name awaits approval, or no_road where no mapped road reaches the building. provisional: true means the number or the street was worked out from the map and is not yet confirmed, so show it as a suggestion rather than a fact. The field is absent where the register does not yet cover that state, which is not an error. Re-fetch it when you show it, or refresh it monthly: local governments name streets between the register's quarterly rebuilds.

Where OpenStreetMap has no building, the outline can come from satellite imagery. what_is_here.detail then says so, and the building carries source: "Google Open Buildings" with an imagery_confidence. Treat it as a building like any other, and credit Google Open Buildings (CC BY 4.0) wherever you show one. A building’s YardCode may differ by a spot from an older answer, so always use the address_yardcode you were returned and never cache one for more than a day.

What is at the spot

Every answer says what is there, in one of four categories, and the widget shows it as a coloured chip above the code.

CategoryMeansWhat to do
building The pin is inside a building outline. Store address_yardcode: it is the building’s own code.
road The pin is on a road or a bridge. Nobody lives on a road. Ask them to move the pin onto the building.
waterbody A river, lake, lagoon or swamp. The same: ask for the pin to be moved.
open_land Farmland, school grounds, an empty plot. No mapped building here. Worth a second look, but much of Nigeria is simply unmapped.

The building rule. A building can straddle two yards. It belongs to the yard holding the largest share of its footprint, and its YardCode is the spot at the middle of that share — the centre of the roof, in practice. So two people tapping different corners of one roof file the same address. When it crosses yards, split shows the shares.

Two honest caveats. confidence: "low" means little is mapped nearby, so treat the verdict as a best guess. checked: false means the map service could not be reached — the YardCode is still exact, and nothing else about the answer changes.

Two codes, deliberately. address_yardcode is where the typed address alone resolved, with an honest radius. yardcode is the point the person actually pinned on their roof. When they differ, the pin is the answer and the difference is worth keeping.

The address is collected in separate fields, not as one free-text line: house or plot number, street, block or floor, estate or community, town, landmark, state and local government. A line somebody typed however they liked is what makes an address unusable later — the block and flat disappear into it and nothing can be matched on. You get every field back, and the block, floor and flat matter most, because no pin on a map can show which flat somebody lives in.

1. Put it on your form

<input id="address" name="address" placeholder="Tap to find your address">

<script src="https://addver.yardcode.ng/widget/v1/yardcode-picker.js"></script>
<script>
  YardCodePicker.attach('#address', {
    key: 'pk_live_xxxxxxxxxxxx',
    onSelect: function (result) {
      document.getElementById('yardcode').value = result.yardcode;
      document.getElementById('lat').value      = result.lat;
      document.getElementById('lng').value      = result.lng;
      document.getElementById('yc_token').value = result.token;
    }
  });
</script>

Or let it fill the fields for you

YardCodePicker.attach('#address', {
  key: 'pk_live_xxxxxxxxxxxx',
  fields: {
    yardcode:       '#yardcode',
    lat:            '#lat',
    lng:            '#lng',
    street_address: '#street_address',
    token:          '#yc_token'
  }
});

The publishable key is meant to be visible. It can ask about places and nothing else, and it only works on the websites you register.

2. Check the token on your server

Anything a browser sends you is a claim. Redeem the token with your secret key and use what comes back, not what was posted.

import requests
from flask import request

YARDCODE_SECRET = os.environ["YARDCODE_SECRET_KEY"]   # sk_live_…

def confirm_address(token):
    """Returns what YardCode recorded, or None."""
    reply = requests.post(
        "https://addver.yardcode.ng/widget/v1/verify",
        json={"token": token},
        headers={"Authorization": f"Bearer {YARDCODE_SECRET}"},
        timeout=10,
    )
    if reply.status_code != 200:
        return None
    return reply.json()


@app.route("/register", methods=["POST"])
def register():
    trusted = confirm_address(request.form.get("yc_token"))
    if not trusted:
        flash("Please choose your address again.")
        return redirect(url_for("register"))

    student.yardcode       = trusted["yardcode"]        # not request.form
    student.latitude       = trusted["lat"]
    student.longitude      = trusted["lng"]
    student.street_address = trusted.get("street_address") or trusted.get("typed_address")
    student.lga            = trusted.get("lga")
    student.state          = trusted.get("state")
    db.session.commit()

A token lasts 30 minutes and may be redeemed more than once, so a resubmitted form still works.

Before you go live

Try the demo Stuck? Reach a person

Endpoints, if you would rather build your own

CallKeyWhat it does
POST /widget/v1/searchpublishable A typed address in; a coordinate, a YardCode and an honest radius out.
POST /widget/v1/lookuppublishable A coordinate in; the YardCode, ward, LGA and state out.
POST /widget/v1/validatepublishable Is this a YardCode, and where is it?
POST /widget/v1/finalisepublishable Record the chosen address and return a token. This is the billed call.
POST /widget/v1/verifysecret Redeem a token, from your server.