> ## Documentation Index
> Fetch the complete documentation index at: https://docs.goshippo.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.goshippo.com/feedback

```json
{
  "path": "/docs/AddressAPI/address_validate",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Address validation

> Validate shipping addresses with the Shippo API to prevent failed deliveries and correction surcharges.

export const AddressValidationDemo = () => {
  const {useState, useCallback} = React;
  const BTN_GREEN = '#97C38E';
  const TAB_ACTIVE = '#30881E';
  const BORDER = '#e0e0e0';
  const CHIP_BLUE = '#0277bd';
  const VALIDATE_URL = 'https://api.goshippo.com/addresses/validate/demo';
  const validationAddresses = [{
    label: 'Complete US address',
    address: {
      name: 'Shawn Ippotle',
      organization: 'Shippo',
      address_line_1: '2261 Market St',
      city_locality: 'San Francisco',
      state_province: 'CA',
      postal_code: '94114-1612',
      country_code: 'US'
    }
  }, {
    label: 'Incomplete US address \u2013 Missing city',
    address: {
      name: 'Seamus Heaney',
      organization: 'Shippo',
      address_line_1: '249 Newark Ave',
      state_province: 'NJ',
      postal_code: '07071',
      country_code: 'US'
    }
  }, {
    label: 'Invalid US address \u2013 Non-existent premise',
    address: {
      name: 'Shawn Ippotle',
      organization: 'Shippo',
      address_line_1: '333 Clayton St.',
      city_locality: 'Los Angeles',
      state_province: 'CA',
      country_code: 'US'
    }
  }, {
    label: 'Complete International address',
    address: {
      name: 'Mario',
      organization: 'Bears against honey',
      address_line_1: '33 Mitchell St.',
      city_locality: 'Putney',
      state_province: 'NSW',
      postal_code: '2112',
      country_code: 'AU'
    }
  }, {
    label: 'Incomplete International address \u2013 Missing postal code',
    address: {
      name: 'Test',
      organization: 'Test Company',
      address_line_1: 'Privada Uni\u00f3n 10',
      city_locality: 'CIUDAD DE M\u00c9XICO',
      state_province: 'CDMEX',
      country_code: 'MX'
    }
  }, {
    label: 'Invalid International address \u2013 Missing address line 2',
    address: {
      name: 'Test',
      organization: 'Test Company',
      address_line_1: 'Privada Uni\u00f3n',
      city_locality: 'CIUDAD DE M\u00c9XICO',
      state_province: 'CDMEX',
      country_code: 'MX'
    }
  }];
  const statusColors = {
    valid: '#2e7d32',
    partially_valid: '#e65100',
    invalid: '#c62828'
  };
  const renderChip = (color, label) => <span key={label} style={{
    display: 'inline-block',
    padding: '2px 10px',
    borderRadius: '16px',
    backgroundColor: color,
    color: '#fff',
    fontSize: '12px',
    fontWeight: 'bold',
    marginRight: '4px'
  }}>
      {label}
    </span>;
  const cardStyle = {
    border: `1px solid ${BORDER}`,
    borderRadius: '8px',
    padding: '16px',
    marginTop: '12px',
    display: 'flex',
    flexDirection: 'column',
    gap: '8px'
  };
  const formatAddress = addr => {
    if (!addr) return '';
    return [addr.address_line_1, addr.address_line_2, addr.city_locality, addr.state_province && addr.postal_code ? `${addr.state_province} ${addr.postal_code}` : addr.state_province || addr.postal_code, addr.country_code].filter(Boolean).join(', ');
  };
  const [result, setResult] = useState(null);
  const [activeTab, setActiveTab] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [selectedIndex, setSelectedIndex] = useState('');
  const [copied, setCopied] = useState(false);
  const handleSubmit = useCallback(async index => {
    setLoading(true);
    setError(null);
    setResult(null);
    try {
      const addr = validationAddresses[index].address;
      const params = new URLSearchParams(Object.fromEntries(Object.entries(addr).filter(([_k, v]) => v)));
      const res = await fetch(`${VALIDATE_URL}?${params}`, {
        headers: {
          'Content-Type': 'application/json',
          'Shippo-Override-Addresses': 'V2'
        }
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      setResult(await res.json());
      setActiveTab(0);
    } catch (_err) {
      setError('Failed to validate address. Please try again.');
    } finally {
      setLoading(false);
    }
  }, []);
  const handleSelect = e => {
    const v = e.target.value;
    setSelectedIndex(v === '' ? '' : Number(v));
  };
  const handleValidate = () => {
    if (selectedIndex !== '') handleSubmit(selectedIndex);
  };
  const handleCopy = () => {
    const text = JSON.stringify(result, null, 2);
    navigator.clipboard?.writeText(text);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };
  const isDisabled = selectedIndex === '' || loading;
  const status = result?.analysis?.validation_result?.value ?? '';
  const statusColor = statusColors[status] ?? '#666';
  return <div>
      {}
      <div style={{
    display: 'flex',
    gap: '12px',
    alignItems: 'center'
  }}>
        <select value={selectedIndex} onChange={handleSelect} style={{
    flex: 1,
    padding: '10px 14px',
    borderRadius: '6px',
    border: `1px solid ${BORDER}`,
    fontSize: '14px',
    backgroundColor: 'var(--bg-color, #fff)',
    color: 'var(--text-color-primary, #1F2D34)'
  }}>
          <option value="">Choose Sample Address</option>
          {validationAddresses.map((opt, i) => <option key={i} value={i}>
              {opt.label}
            </option>)}
        </select>
        <button onClick={handleValidate} disabled={isDisabled} style={{
    padding: '12px 16px',
    backgroundColor: BTN_GREEN,
    color: '#fff',
    border: 'none',
    borderRadius: '8px',
    fontSize: '16px',
    fontWeight: 'bold',
    cursor: isDisabled ? 'default' : 'pointer',
    whiteSpace: 'nowrap',
    transition: 'background-color 0.2s'
  }}>
          {loading ? 'Validating\u2026' : 'Validate'}
        </button>
      </div>

      {error && <p style={{
    color: '#c62828',
    marginTop: '12px'
  }}>{error}</p>}

      {}
      <div style={{
    marginTop: '16px'
  }}>
        <div style={{
    display: 'flex',
    borderBottom: `2px solid ${BORDER}`
  }}>
          {['Validated Address', 'API Response'].map((tab, i) => <button key={tab} onClick={() => setActiveTab(i)} style={{
    padding: '8px 20px',
    border: 'none',
    background: 'none',
    fontSize: '14px',
    fontWeight: activeTab === i ? 500 : 'normal',
    color: activeTab === i ? TAB_ACTIVE : '#666',
    borderBottom: activeTab === i ? `2px solid ${TAB_ACTIVE}` : '2px solid transparent',
    cursor: 'pointer',
    marginBottom: '-2px',
    textTransform: 'uppercase'
  }}>
              {tab}
            </button>)}
        </div>

        {result ? activeTab === 0 ? <div>
              {}
              <div style={cardStyle}>
                <h5 style={{
    margin: 0
  }}>Original Address</h5>
                <div>{formatAddress(result.original_address)}</div>
                <div>
                  <span style={{
    fontWeight: 'bold',
    fontSize: '12px',
    marginRight: '6px'
  }}>
                    RESULT:
                  </span>
                  {renderChip(statusColor, status)}
                </div>
              </div>

              {}
              {status === 'partially_valid' && result.recommended_address && <div style={cardStyle}>
                  <h5 style={{
    margin: 0
  }}>Recommended Address</h5>
                  <div>{formatAddress(result.recommended_address)}</div>
                  {result.recommended_address.confidence_result && <div>
                      <span style={{
    fontWeight: 'bold',
    fontSize: '12px',
    marginRight: '6px'
  }}>
                        CONFIDENCE LEVEL:
                      </span>
                      {renderChip('#2e7d32', result.recommended_address.confidence_result.score)}
                    </div>}
                </div>}

              {}
              <div style={cardStyle}>
                <h5 style={{
    margin: 0
  }}>Analysis</h5>
                {result.analysis?.address_type && <div>
                    <span style={{
    marginRight: '6px'
  }}>Address Type:</span>
                    {renderChip(CHIP_BLUE, result.analysis.address_type)}
                  </div>}
                {result.analysis?.changed_attributes?.length > 0 && <div>
                    <span style={{
    marginRight: '6px'
  }}>Changed Attributes:</span>
                    {result.analysis.changed_attributes.map(attr => renderChip(CHIP_BLUE, attr))}
                  </div>}
                {result.analysis?.validation_result?.reasons?.length > 0 && <div>
                    <span style={{
    marginRight: '6px'
  }}>Reasons:</span>
                    {result.analysis.validation_result.reasons.map(r => renderChip(CHIP_BLUE, r.code))}
                  </div>}
              </div>
            </div> : <div style={{
    position: 'relative',
    marginTop: '12px'
  }}>
              <button onClick={handleCopy} style={{
    position: 'absolute',
    top: '8px',
    right: '8px',
    background: 'rgba(255,255,255,0.15)',
    border: 'none',
    color: '#abb2bf',
    cursor: 'pointer',
    borderRadius: '4px',
    padding: '4px 10px',
    fontSize: '12px'
  }}>
                {copied ? 'Copied!' : 'Copy'}
              </button>
              <pre style={{
    backgroundColor: '#282c34',
    color: '#abb2bf',
    padding: '16px',
    borderRadius: '8px',
    overflowX: 'auto',
    fontSize: '13px',
    margin: 0,
    lineHeight: '1.5'
  }}>
                {JSON.stringify(result, null, 2)}
              </pre>
            </div> : !loading && <p style={{
    marginTop: '16px',
    color: '#666'
  }}>
              Please select an address and click Validate to get started.
            </p>}
      </div>
    </div>;
};

Address validation is a service that tests your address to check if it is valid.
By checking for invalid addresses and instantly correcting them to ensure accurate addresses, this helps prevent failed deliveries and address correction surcharges and allows you to protect your bottom line.
You can have customers validate addresses through the Addresses API during checkout or you can validate addresses while you are creating labels.

The returned results include a `validation_result` that indicates if the address is valid. If the validation identifies changes needed in order to make your address valid, the API response recommends a new address in `recommended_address`.

## Using address validation

If you are interested in using Shippo’s Address Validation API or have any questions about pricing, please [contact our sales team](https://goshippo.com/contact/sales).

## Validate an address

To validate an address, follow this example.

```json cURL theme={null}
curl -i -X GET \
  'https://api.goshippo.com/v2/addresses/validate?address_line_1=320J Outerbelt Street&city_locality=Columbus&state_province=OH&postal_code=43213&country_code=US&organization=Shippo' \
  -H 'Authorization: ShippoToken <API_TOKEN>'
```

```json Validate address response theme={null}
{
    "original_address": {
        "address_line_1": "320J Outerbelt Street",
        "city_locality": "Columbus",
        "state_province": "OH",
        "postal_code": "43213",
        "country_code": "US",
        "organization": "Shippo"
    },
    "recommended_address": {
        "address_line_1": "320 Outerbelt St",
        "address_line_2": "Ste J",
        "city_locality": "Columbus",
        "state_province": "OH",
        "postal_code": "43213",
        "country_code": "US",
        "organization": "Shippo",
        "complete_address": "Shippo; 320 Outerbelt St Ste J; Columbus OH 43213-1537; US",
        "confidence_result": {
            "score": "high",
            "code": "postal_data_match",
            "description": "The address has been completely verified to the most granular level possible."
        }
    },
    "analysis": {
        "validation_result": {
            "value": "partially_valid",
            "reasons": [
                {
                    "code": "address_abbreviation_fixed",
                    "description": "Address inputted was standardized for abbreviations according to postal authority rules."
                }
            ]
        },
        "address_type": "commercial",
        "changed_attributes": [
            "address_line_2",
            "address_line_1"
        ]
    },
    "geo": {
        "latitude": 39.98725,
        "longitude": -82.83042
    }
}
```

<br />

## Try address validation

Try our Address Validation API using any example address from the dropdown below. You can find the breakdown of the address validation result, and the raw API response as a JSON object.

<AddressValidationDemo />

## Migrate address validation

If you use the [legacy Shippo validation](/docs/Addresses/AddressValidation), you may choose to update your integration to use the latest Addresses API. Use this guide to understand what has changed and what you need to do to use the latest version.

The legacy address validation supported two methods for address validation.

1. When [creating a new address object](/docs/Addresses/AddressValidation#how-to-validate-addresses) using the `validate` option.
2. Validating [existing Address objects](/docs/Addresses/AddressValidation#validate-existing-address-objects).

The latest Address API validation does not support validating addresses using the object ID of an address.

The changes are as follows.

<img src="https://mintcdn.com/shippo-f4b7b609/bsljvq9P8Idqx1CE/images/step1.svg?fit=max&auto=format&n=bsljvq9P8Idqx1CE&q=85&s=cf0d2ceaf4419aae89630f9f35a8c70d" alt="step 1 icon" width="44" height="32" data-path="images/step1.svg" /> Address fields are passed as query parameters instead of fields in the body of the request.

```shell Address V2 validation theme={null}
curl -i -X GET \
  'https://api.goshippo.com/v2/addresses/validate?address_line_1=215 Clayton St&city_locality=San Francisco&state_province=CA&postal_code=94117&country_code=US&organization=Shippo' \
  -H 'Authorization: ShippoToken <API_TOKEN>'
```

```shell legacy Address validation theme={null}
curl -i https://api.goshippo.com/addresses/\
    -H "Authorization: ShippoToken <API_TOKEN>"\
    -d company="Shippo"\
    -d street1="215 Clayton St."\
    -d city="San Francisco"\
    -d state="CA"\
    -d zip=94117\
    -d country="US"\
    -d validate=true
```

<img src="https://mintcdn.com/shippo-f4b7b609/bsljvq9P8Idqx1CE/images/step2.svg?fit=max&auto=format&n=bsljvq9P8Idqx1CE&q=85&s=bbb481f85d226206e137bbc697adaf75" alt="step 2 icon" width="44" height="32" data-path="images/step2.svg" /> The path must be prefixed with `/v2`.

```shell Address V2 theme={null}
https://api.goshippo.com/v2/addresses/

```

```shell legacy Address theme={null}
https://api.goshippo.com/addresses/
```

<img src="https://mintcdn.com/shippo-f4b7b609/bsljvq9P8Idqx1CE/images/step3.svg?fit=max&auto=format&n=bsljvq9P8Idqx1CE&q=85&s=415c14bc7794a5c41c85d1b4a9b0a401" alt="step 3 icon" width="44" height="32" data-path="images/step3.svg" /> The returned response includes a richer details about the validated address including the following.

* A `recommended_address`.
* A `confidence_result` with a `score` and `description` describing the quality of the recommended address.
* `analysis` that includes details about the validation.
* `changed_attributes` that lists which values changed between the `original_address` and the `recommended_address`.

```json Address V2 response theme={null}
{
  "original_address": {
    "address_line_1": "965 Mission St # 572",
    "address_line_2": "#200",
    "city_locality": "San Francisco",
    "state_province": "CA",
    "postal_code": "94103-2921",
    "country_code": "US",
    "name": "Mr. Hippo"
  },
  "analysis": {
    "validation_result": {
      "value": "valid",
      "reasons": [
        {
          "code": "address_found",
          "description": "The entire address is present in the database."
        }
      ]
    },
    "address_type": "commercial"
  },
  "geo": {
    "latitude": 37.78152,
    "longitude": -122.40786
  }
}
```

```json legacy Address response theme={null}
{
    "object_created": "2024-02-15T16:04:06.649Z",
    "object_updated": "2024-02-15T16:04:06.674Z",
    "object_id": "3af6fd3321c3468caeb5cf6d5545de36",
    "is_complete": true,
    "validation_results": {
        "is_valid": true,
        "messages": [
            {
                "source": "Shippo Address Validator",
                "code": "Default Match",
                "type": "address_warning",
                "text": "More information, such as an apartment or suite number, may give a more specific address."
            }
        ]
    },
    "object_owner": "adrian.collins@goshippo.com",
    "name": "Mr Hippo",
    "company": "",
    "street_no": "",
    "street1": "965 Mission St # 572",
    "street2": "",
    "street3": "",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94103-2921",
    "country": "US",
    "longitude": -122.40786,
    "latitude": 37.78152,
    "phone": "4151234567",
    "email": "mrhippo@goshippo.com",
    "is_residential": false,
    "metadata": "",
    "test": true
}
```

<img src="https://mintcdn.com/shippo-f4b7b609/bsljvq9P8Idqx1CE/images/step4.svg?fit=max&auto=format&n=bsljvq9P8Idqx1CE&q=85&s=2afdb7da328d88327fd4d1ac6de4215e" alt="step 4 icon" width="44" height="32" data-path="images/step4.svg" /> The returned address is not stored.

<img src="https://mintcdn.com/shippo-f4b7b609/bsljvq9P8Idqx1CE/images/step5.svg?fit=max&auto=format&n=bsljvq9P8Idqx1CE&q=85&s=848f0b9e5f1be982a9e507c101ba41d6" alt="step 5 icon" width="44" height="32" data-path="images/step5.svg" /> The following fields have changed.

| V1 Address Field            | V2 Address Field | Notes                          |
| --------------------------- | ---------------- | ------------------------------ |
| \*\* Deprecated Fields \*\* |                  |                                |
| is\_complete                |                  |                                |
| object\_created             |                  |                                |
| object\_updated             |                  |                                |
| object\_id                  |                  |                                |
| object\_owner               |                  |                                |
| street\_no                  |                  |                                |
| street3                     |                  |                                |
| phone                       |                  |                                |
| email                       |                  |                                |
| test                        |                  |                                |
| validation\_results         |                  | Moved to analysis but modified |
| metadata                    |                  |                                |

| V1 Address Field                                            | V2 Address Field | Notes |
| ----------------------------------------------------------- | ---------------- | ----- |
| \*\* original\_address \*\*, \*\* recommended\_address \*\* |                  |       |
| name                                                        | name             |       |
| company                                                     | organization     |       |
| street1                                                     | address\_line\_1 |       |
| street2                                                     | address\_line\_2 |       |
| city                                                        | city\_locality   |       |
| state                                                       | state\_province  |       |
| zip                                                         | postal\_code     |       |
| country                                                     | country\_code    |       |

| V1 Address Field                                                                                        | V2 Address Field   | Notes                                                                                                                                                                                                                             |
| ------------------------------------------------------------------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \*\* recommended\_address (exclusive fields) \*\*                                                       |                    |                                                                                                                                                                                                                                   |
| \*\* recommended\_address is present if we believe there is a more accurate version of the address \*\* |                    |                                                                                                                                                                                                                                   |
|                                                                                                         | complete\_address  | The full address in one string whenever available                                                                                                                                                                                 |
|                                                                                                         | confidence\_result | Contains the score field which takes values of high, medium, low; contains the code field which is the machine readable explanation to the score; and the description field which is the human friendly explanation to the score. |

| V1 Address Field              | V2 Address Field            | Notes                                                                                                                                                                                                                                  |
| ----------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \*\* analysis \*\*            |                             |                                                                                                                                                                                                                                        |
| is\_residential               | address\_type               | changed from boolean to an enum. `residential`, `commercial`, `unknown`, `po_box`, `military`                                                                                                                                          |
| validation\_results           | validation\_results         | changed from boolean to an object.                                                                                                                                                                                                     |
| validation\_results.is\_valid | validation\_results.value   | Changed from Bool to enum.  `valid`, `partially_valid`, `invalid`                                                                                                                                                                      |
| validation\_results.messages  | validation\_results.reasons | Each reason is an object containing the code and the description. The code is the machine readable explanation to why the address is valid, partially valid, or invalid. And the description is the human friendly value for the same. |
|                               | changed\_attributes         | list of fields changed in the recommended address from the original address.                                                                                                                                                           |

| V1 Address Field | V2 Address Field | Notes |
| ---------------- | ---------------- | ----- |
| \*\* geo \*\*    |                  |       |
|                  | latitude         |       |
|                  | longitude        |       |
