Using the API

Three endpoints cover forward geocoding, autocomplete, and reverse geocoding for US addresses. Browser apps are authorized by your whitelisted domains; backends and scripts use a secret API key.

Authentication

There are two ways to authorize requests, depending on where your code runs:

From a website (browser): no credentials needed. The browser sends your site's Origin header automatically, and requests are authorized against your whitelisted domains (add them in the dashboard). Strict CORS headers ensure pages on other domains can't read the responses.

From a server, script, or curl: create an API key in the dashboard and send it with each request. Keys are secret — never embed them in browser code or public repositories.

curl -H "X-API-Key: por_your_key_here" \
  "https://pinorient.com/api/geocoder/search?q=1600+Amphitheatre+Parkway"

# Authorization: Bearer por_... works too

Endpoints

GET /api/geocoder/search?q={query} — full-text address & place search GET /api/geocoder/autocomplete?q={query} — fast prefix suggestions as the user types GET /api/geocoder/reverse?lat={lat}&lon={lon} — nearest address for a coordinate

All three return a JSON object with a results array. Useful optional parameters: limit (max results) and bbox (minLng,minLat,maxLng,maxLat) to restrict results to an area — e.g. the continental US: -125,24,-66,49.

Example queries

curl -H "X-API-Key: por_your_key_here" \
  "https://pinorient.com/api/geocoder/search?q=1600+Amphitheatre+Parkway"

curl -H "X-API-Key: por_your_key_here" \
  "https://pinorient.com/api/geocoder/autocomplete?q=1600+Amphi&limit=6&bbox=-125,24,-66,49"

curl -H "X-API-Key: por_your_key_here" \
  "https://pinorient.com/api/geocoder/reverse?lat=37.4224&lon=-122.0842"

Response shape

{
  "results": [
    {
      "name": "Googleplex",
      "address": "1600 Amphitheatre Parkway",
      "city": "Mountain View",
      "state": "CA",
      "postcode": "94043",
      "lat": 37.4224,
      "lon": -122.0842
    }
  ]
}

JavaScript

Fetch results in the browser and format them for display. From a whitelisted domain, no credentials are needed — the browser sends your Origin automatically.

async function searchAddress(query) {
  const url = new URL('https://pinorient.com/api/geocoder/search');
  url.searchParams.set('q', query);

  const res = await fetch(url);
  if (!res.ok) throw new Error(`Geocoding failed: ${res.status}`);
  const { results = [] } = await res.json();

  // Format each result as a single-line address.
  return results.map(p => ({
    label: [p.address || p.name, p.city, p.state, p.postcode]
      .filter(Boolean)
      .join(', '),
    lat: p.lat,
    lon: p.lon,
  }));
}

const places = await searchAddress('1600 Amphitheatre Parkway');
// [{ label: '1600 Amphitheatre Parkway, Mountain View, CA, 94043', lat: 37.4224, lon: -122.0842 }]

Go

The same lookup server-side with the standard library. Backends authenticate with an API key — keep it in an environment variable or secret store, never in browser code.

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

type Place struct {
	Name     string  `json:"name"`
	Address  string  `json:"address"`
	City     string  `json:"city"`
	State    string  `json:"state"`
	Postcode string  `json:"postcode"`
	Lat      float64 `json:"lat"`
	Lon      float64 `json:"lon"`
}

func searchAddress(query string) ([]Place, error) {
	u := "https://pinorient.com/api/geocoder/search?q=" + url.QueryEscape(query)
	req, _ := http.NewRequest("GET", u, nil)
	req.Header.Set("X-API-Key", os.Getenv("PINORIENT_API_KEY"))

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	var body struct {
		Results []Place `json:"results"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		return nil, err
	}
	return body.Results, nil
}

func main() {
	places, err := searchAddress("1600 Amphitheatre Parkway")
	if err != nil {
		panic(err)
	}
	for _, p := range places {
		fmt.Printf("%s, %s, %s %s (%.4f, %.4f)\n",
			p.Address, p.City, p.State, p.Postcode, p.Lat, p.Lon)
	}
}

Going further

This page covers the basics. For the full API reference, self-hosting instructions, and data import details, see the project README on GitHub — or try the live demo to explore the API interactively.