# Geocode an address to coordinates with PickPoint's API

PickPoint's geocoding API turns an address into coordinates with `GET https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/geocode/forward` and turns coordinates back into an address with `GET https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/geocode/reverse`, one request each. Each call costs $0.25 per thousand requests and draws on a plan held by the agent credential: the Free trial of $0.625, or Pay as you go credit. Send the request with `Authorization: Bearer <token>`; there is no per-call payment.

## At a glance

- **Forward:** `GET https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/geocode/forward?q=<address>&format=json`
- **Reverse:** `GET https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/geocode/reverse?lat=<lat>&lon=<lon>&format=json`
- **Price:** $0.25 per thousand requests, one request per call. 1,000 requests cost $0.25.
- **Plans:** the Free trial ($0.625, once per human, after a person claims the credential with a verified email) or Pay as you go (from $0.01 by wallet, $0.50 by card)
- **Auth:** a free agent credential, sent as `Authorization: Bearer <token>`. No PickPoint API key is needed.
- **Response:** JSON with `lat` and `lon` as strings, `display_name`, `address`, `importance` and `licence`
- **Charge:** the `zc-billing` response header shows what each call drew from the plan
- **Full purchase flow:** [the buyer skill](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/SKILL.md)

## Geocode an address, then reverse it

Before the first call, hold an access token and a plan. [The buyer skill](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/SKILL.md) and [auth.md](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/auth.md) cover registering the free credential and buying credit at `POST https://agents.pickpoint.io/zcj/c3ns8kl52qiq/plans/{planId}/purchase`, with each plan's URL in `plans[].purchase.url` in [the catalog](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/manifest.json). A Pay as you go purchase answers with a 402, the price quote, which you pay over x402 or MPP (wallet rails settling in USDC) or by card, and retry.

1. Forward geocode a free-text address:

   ```bash
   curl -s "https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/geocode/forward?q=Texas+State+Capitol,+Austin&format=json&limit=1&addressdetails=1" \
     -H "Authorization: Bearer $ACCESS_TOKEN"
   ```

   The response is a list of candidates ranked by `importance`. For this request the list held one result, the Capitol, with its address broken into parts:

   ```json
   [{
     "lat": "30.27469115",
     "lon": "-97.74051712256421",
     "name": "Texas State Capitol",
     "class": "historic",
     "type": "building",
     "place_rank": 30,
     "address": {
       "historic": "Texas State Capitol",
       "house_number": "112",
       "road": "East 11th Street",
       "neighbourhood": "Downtown",
       "city": "Austin",
       "county": "Travis County",
       "state": "Texas",
       "postcode": "78701",
       "country": "United States",
       "country_code": "us"
     },
     "licence": "Data © OpenStreetMap contributors, ODbL 1.0. …"
   }]
   ```

2. To send an address that is already split into parts, use the structured fields instead of `q`:

   ```bash
   curl -s "https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/geocode/forward?city=Berlin&country=Germany&format=json&limit=1" \
     -H "Authorization: Bearer $ACCESS_TOKEN"
   ```

   The example response is the city itself, with `"addresstype": "city"`, `"lat": "52.510885"`, `"lon": "13.3989367"` and `"display_name": "Berlin, Deutschland"`. To choose the language of result names, set `accept-language`, for example `en`.

3. Reverse geocode the coordinates from step 1:

   ```bash
   curl -s "https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/geocode/reverse?lat=30.27469115&lon=-97.74051712256421&format=json&addressdetails=1" \
     -H "Authorization: Bearer $ACCESS_TOKEN"
   ```

   The response is one object for the feature nearest the point. At the Capitol's coordinates, that feature was a footway called Oval Walk and not the Capitol:

   ```json
   {
     "name": "Oval Walk",
     "class": "highway",
     "type": "footway",
     "addresstype": "road",
     "display_name": "Oval Walk, Medical District, Austin, Travis County, Texas, 78778, United States"
   }
   ```

4. Read the `zc-billing` header on each response. On a plan-funded call it carries `fundingSource` and `chargedUsd`. The forward example was charged $0.00025 against the plan's credit. The structured example was charged $0.00025. The reverse example was charged $0.00025.

## Choose the query and the detail

| Need | Set |
| --- | --- |
| Free-text address or place name | `q` |
| Address already in parts | `street`, `city`, `county`, `state`, `country`, `postalcode` (never with `q`) |
| Only the best match | `limit=1` |
| Address parts in the result | `addressdetails=1` |
| Results in given countries only | `countrycodes=us` (ISO 3166-1 alpha-2, comma separated) |
| Reverse at street or city level | `zoom=16` or `zoom=10` (default `18`, building) |
| GeoJSON output | `format=geojson`, with coordinates as [longitude, latitude] |

## Boundaries

- With `format=json`, `lat` and `lon` are strings. Parse them to numbers before you calculate with them or send them on.
- Reverse geocoding returns the mapped feature nearest the point: a road, a footway or a building. To keep a landmark's own address, store the forward result's `address`.
- Each call is one request. A forward query with no match returns `[]`.
- Every call draws on a plan. A plan purchase is charged only when you pay its 402, and a delivered response with no `zc-billing` header billed nothing.
- Results may be stored indefinitely. OpenStreetMap data is licensed under the ODbL and needs attribution when you display it.

## Errors

| Code | Meaning | Action |
| --- | --- | --- |
| `401 bearer_required` | No credential on the call | Register at [auth.md](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/auth.md), then retry with the bearer |
| `401 invalid_token` | The token expired or did not verify | Exchange the stored assertion for a fresh token |
| `403 plan_required` | The credential holds no plan covering geocoding | Buy a plan listed in the body's `plans`, then retry |
| `403 verified_email_required` | The Free trial needs a claimed credential | Have a person claim the credential with a verified email, then retry |
| `usage_exhausted` | The plan's credit is used up | Top up with `POST https://agents.pickpoint.io/zcj/c3ns8kl52qiq/extend` and `{"amountUsd": "<amount>"}` |

## Address search and routing

| Next job | Endpoint | Reference |
| --- | --- | --- |
| Candidates for partial input | `GET https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/address/search?q=<text>` | [Address Search](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/services/address-search) |
| Directions between points | `POST https://agents.pickpoint.io/zcj/c3ns8kl52qiq/v2/route` with `locations` and `costing` | [Routing](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/services/routing) |

Both plans also cover address search, at $0.25 per thousand requests, and routing, at $0.25 per thousand requests.

## Frequently asked questions

### Does PickPoint's geocoding API need an API key?

No. Calls through the storefront use the free agent credential that the storefront issues, sent as `Authorization: Bearer <token>`. No PickPoint API key is involved.

### How much does forward or reverse geocoding cost?

Each forward or reverse call is one request at $0.25 per thousand requests, so 1,000 requests cost $0.25. The Free trial's $0.625 and Pay as you go credit both draw down at that rate.

### Can I pay for one geocoding call without a plan?

No. Every call draws on a plan held by your credential. Claim the Free trial or buy Pay as you go credit first, then call against it.

### Why does reverse geocoding return a street instead of the landmark?

Reverse geocoding returns the feature nearest the coordinates at the requested `zoom`, and that feature can be a road or footway next to the place you searched. Keep the forward result's `address` when you need the landmark itself, or lower `zoom` for a street- or city-level answer.

### Can I store and display the coordinates?

Yes. Results may be stored indefinitely. Each response's `licence` field names the OpenStreetMap ODbL licence, and displaying the data requires attribution.

## Keep reading

- [The buyer skill](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/SKILL.md): the full purchase flow
- [Identity](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/auth.md): registering and claiming the agent credential
- [How to pay](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/payment.md): plans, rails and top-ups
- [Geocoding API reference](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/services/geocoding/openapi.json): every parameter and response field
- [Error reference](https://agents.pickpoint.io/zcj/c3ns8kl52qiq/errors.md): every error code

---

Updated 2026-11-06. All PickPoint guides: https://agents.pickpoint.io/guides.md. Storefront: https://agents.pickpoint.io/zcj/c3ns8kl52qiq/llms.txt.
