# Parse an address (/api-reference/parse)

```http
POST https://api.fieldgeist.com/v1/verify/parse
```

Sends one free-text US address to [US-LEX-1](/concepts/model), the Verify model. The response gives the address type, its components in USPS Publication 28 form, the standardized delivery lines, a confidence score and warnings for anything missing, unusual or out of scope.

The parser standardizes what you send (`Avenue` becomes `AVE`, `apt` becomes `APT`); it doesn't correct spelling or check that the address exists. To match the result to a parcel, send it to [Look up a parcel](/api-reference/lookup).

## Authentication [#authentication]

`Authorization: Bearer <key>`. See [Authentication](/authentication).

## Request body [#request-body]

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `line` | string | Yes | The address as one line of text, up to 256 characters. Commas and line breaks are optional. |

## Request example [#request-example]

<Tabs items={["cURL", "JavaScript", "Python"]}>
<Tab value="cURL">

```bash
curl https://api.fieldgeist.com/v1/verify/parse \
  -H "Authorization: Bearer $FIELDGEIST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"line": "350 5th ave apt 21b new york ny 10118"}'
```

</Tab>
<Tab value="JavaScript">

```js
const res = await fetch("https://api.fieldgeist.com/v1/verify/parse", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FIELDGEIST_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ line: "350 5th ave apt 21b new york ny 10118" }),
});
if (!res.ok) {
  const { error, message } = await res.json();
  throw new Error(`${res.status} ${error}: ${message ?? ""}`);
}
const parsed = await res.json();
```

</Tab>
<Tab value="Python">

```python
import os
import requests

res = requests.post(
    "https://api.fieldgeist.com/v1/verify/parse",
    headers={"Authorization": f"Bearer {os.environ['FIELDGEIST_API_KEY']}"},
    json={"line": "350 5th ave apt 21b new york ny 10118"},
    timeout=10,
)
res.raise_for_status()
parsed = res.json()
```

</Tab>
</Tabs>

## Response [#response]

### 200 OK [#200-ok]

```json
{
  "input": "350 5th ave apt 21b new york ny 10118",
  "type": "street",
  "components": {
    "city": "NEW YORK",
    "addressNumber": "350",
    "streetSuffix": "AVE",
    "streetName": "5TH",
    "occupancyType": "APT",
    "occupancyId": "21B",
    "state": "NY",
    "zip5": "10118"
  },
  "lines": ["350 5TH AVE APT 21B", "NEW YORK NY  10118"],
  "warnings": [],
  "confidence": 0.9999020747368791,
  "model": { "name": "us-lex-1", "version": "0.1.0", "backend": "model" }
}
```

| Field | Type | Description |
| --- | --- | --- |
| `input` | string | The `line` you sent, unchanged. |
| `type` | string | Address type: `street`, `po_box`, `rural_route`, `military`, `general_delivery`, `dual` (a street address and a PO box in one line) or `ambiguous` (the type couldn't be determined). Only `street` addresses can be [looked up](/api-reference/lookup). |
| `components` | object | The address components found, in Publication 28 form. Components that weren't found are left out. See [Components](#components). |
| `lines` | string[] | The standardized address as delivery lines: the delivery line(s) first, then `CITY ST  ZIP` (two spaces before the ZIP, as Publication 28 prefers). |
| `warnings` | object[] | Anything missing, unusual or out of scope. Empty when the parse is clean. See [Warnings](#warnings). |
| `confidence` | number | 0 to 1. How sure the model is of the labels it assigned. See [Confidence and warnings](/concepts/confidence-and-warnings). |
| `model` | object | Which model read the line: `name` (`us-lex-1`), `version`, and `backend`: `model`, or `heuristic` when the rule-based fallback (`us-lex-rules`) answered instead. Store `version` with results you keep. See [Versions](/concepts/model#versions). |

### Components [#components]

All values are uppercase strings.

| Component | Example | Description |
| --- | --- | --- |
| `addressNumber` | `350` | Primary house number. |
| `addressNumberSuffix` | `1/2` | Suffix after the house number, such as a fraction. |
| `predirectional` | `W` | Direction before the street name. |
| `streetName` | `5TH` | Street name. |
| `streetSuffix` | `AVE` | Street type, abbreviated per Publication 28 (`ST`, `AVE`, `BLVD`). |
| `postdirectional` | `NW` | Direction after the street name. |
| `occupancyType` | `APT` | Secondary unit designator (`APT`, `STE`, `UNIT`, `#`). |
| `occupancyId` | `21B` | Secondary unit number. |
| `secondaryUnits` | `[{"type":"BLDG","id":"A"},{"type":"APT","id":"4"}]` | Present only when the address has two or more units, in input order. `occupancyType` and `occupancyId` then hold the last one. |
| `poBoxType`, `poBoxId` | `PO BOX`, `1234` | PO box designator and number. |
| `ruralRouteType`, `ruralRouteId` | `RR`, `2 BOX 15` | Rural route designator, and the route and box number. |
| `firm` | | A business or recipient name in the line. |
| `urbanization` | | Puerto Rico urbanization name. |
| `city` | `NEW YORK` | City. |
| `state` | `NY` | Two-letter state or territory code. |
| `zip5` | `10118` | 5-digit ZIP Code. |
| `zip4` | `0003` | ZIP+4 add-on. |
| `other` | | Tokens the model couldn't place. Kept for inspection, never rendered into `lines`. |

### Warnings [#warnings]

Each warning has a `code` and a `message`. Warnings about one part of the input also carry `start` and `end`, character offsets into `input`. Branch on `code`; the `message` wording may change.

| `code` | Meaning |
| --- | --- |
| `missing_address_number` | A street name was found without a house number. |
| `missing_street_name` | No street name was found (for example, a suffix with no street name before it). |
| `missing_city` | No city. |
| `missing_state` | No state. |
| `missing_zip` | No ZIP Code. |
| `invalid_zip` | The ZIP Code doesn't have 5 digits, or the ZIP+4 add-on doesn't have 4. |
| `invalid_state` | The state isn't a Publication 28 state or possession abbreviation. |
| `unit_without_id` | A unit designator (`APT`) with no unit number. |
| `unit_id_without_type` | A unit number with no designator. `occupancyType` is set to `#`. |
| `unknown_suffix` | The street suffix isn't a Publication 28 suffix. |
| `unknown_unit_designator` | The unit designator isn't a Publication 28 designator; it's kept as typed. |
| `unknown_tokens` | Some words couldn't be placed in any component. They're listed in `components.other`. |
| `discontiguous_component` | One component appeared in separate parts of the line; the parts were joined with a space. |
| `leading_zero_removed` | Leading zeros were removed from a PO box number. |
| `line_overflow` | A line in `lines` is longer than 40 characters, the Publication 28 maximum. |
| `dual_address` | The line has both a street address and a PO box or rural route. |
| `ambiguous_type` | The address type couldn't be determined, or a word read as the street suffix isn't a Publication 28 suffix, so the street/city boundary is a guess. |
| `ambiguous_city_street` | A word could belong to the street name or the city; the boundary between them is a guess. |
| `unsupported_intersection` | The line looks like a street intersection, not a delivery address. |
| `possibly_foreign` | The line looks like a non-US address. |
| `low_confidence` | `confidence` is below 0.6. |
| `empty_input` | `line` was empty or only whitespace. |
| `model_unavailable` | The model couldn't run, so the rule-based fallback answered. |
| `model_output_invalid` | The model's labels were inconsistent, so the rule-based fallback's parse was used. |

### A parse with warnings [#a-parse-with-warnings]

An intersection parses, but the answer says it isn't a delivery address:

```json
{
  "input": "Main St and 5th Ave, Springfield IL",
  "type": "ambiguous",
  "components": {
    "firm": "MAIN ST AND",
    "city": "SPRINGFIELD",
    "streetSuffix": "AVE",
    "streetName": "5TH",
    "state": "IL"
  },
  "lines": ["MAIN ST AND", "5TH AVE", "SPRINGFIELD IL"],
  "warnings": [
    {
      "code": "unsupported_intersection",
      "message": "\"Main St and 5th Ave\" looks like a street intersection, not a delivery address",
      "start": 0,
      "end": 19
    },
    { "code": "ambiguous_type", "message": "address type could not be determined: the input looks like a street intersection" },
    { "code": "missing_address_number", "message": "street name found without a primary address number" },
    { "code": "missing_zip", "message": "no ZIP Code" },
    { "code": "low_confidence", "message": "confidence 0.50 < 0.6" }
  ],
  "confidence": 0.5,
  "model": { "name": "us-lex-1", "version": "0.1.0", "backend": "model" }
}
```

An empty line is answered with `200`, `type: "ambiguous"` and an `empty_input` warning, not an error. It is billed.

### Errors [#errors]

| Status | `error` | Cause |
| --- | --- | --- |
| `400` | `invalid_json` | The body isn't valid JSON. |
| `400` | `line_required` | The body has no `line` string. |
| `413` | `line_too_long` | `line` is longer than 256 characters. The response includes `"max": 256`. |
| `401`, `402`, `403`, `429`, `5xx` | | See [Errors](/api-reference/errors). |

```json
{ "error": "line_too_long", "max": 256 }
```
