# Resolve tax addresses

Validate address precision before calculating tax.

Stripe Tax calculates tax rates based on customer addresses, but some addresses don’t contain enough detail to determine an exact rate. For example, a US postal code can span multiple tax jurisdictions, so Stripe Tax could approximate the rate rather than calculate the exact rate for that address.

Use the Address Resolution API to check how precisely Stripe Tax can determine the tax rate for a given address before using it in a tax calculation. The API returns:

- The precision level at which Stripe Tax can determine the tax rate for the address
- The address fields to collect or update so Stripe Tax can determine a more precise tax rate

  The Address Resolution API is in private preview. Provide your email to be added to the waitlist. We’ll follow up to confirm if you’re eligible and share onboarding instructions. If you already have a Stripe account, log in before signing up.  

## Before you begin

[Set up Stripe Tax](https://docs.stripe.com/tax/set-up.md) and configure your tax settings.

## Resolve an address

### Request

`POST /v2/tax/address_resolution`

```json
{
  "address": {
    "country": "US",
    "state": "CA",
    "city": "South San Francisco",
    "postal_code": "94080",
    "line1": "354 Oyster Point Blvd"
  }
}
```

### Response

```json
{
  "object": "v2.tax.address_resolution",
  "livemode": false,
  "precision": "address",
  "precision_details": {
    "issues": []
  },
  "address": {
    "country": "US",
    "state": "CA",
    "city": "South San Francisco",
    "postal_code": "94080",
    "line1": "354 Oyster Point Blvd"
  }
}
```

## Understand precision levels

The `precision` field tells you at what level of detail Stripe Tax can determine the tax rate when calculating tax for the given address. Precision levels from the highest to lowest level of detail are:

| Precision     | Description                                                                                                                                   |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `address`     | We can determine the tax rate for a specific address. The highest level of detail, and only available in the US.                              |
| `street`      | We can determine the tax rate for a street. For some addresses, this is the highest level of detail.                                          |
| `postal_code` | We can determine the tax rate for a postal code area. Usually this level leads to tax rate approximations in the US.                          |
| `city`        | We can determine the tax rate for a city-level area.                                                                                          |
| `state`       | We can determine the tax rate for a state or province. For countries such as Canada and India, this is the highest level of detail available. |
| `country`     | We can determine the tax rate for a country. For most countries outside North America, a single tax rate applies nationwide.                  |
| `none`        | The address doesn’t contain enough information to determine any tax rate.                                                                     |

If `precision` isn’t `none`, we can use the address in tax calculations. However, a lower level of detail (less precision) might result in an approximated tax rate when a more precise rate exists for that location.

### How precision relates to tax accuracy

The key signal is the combination of `precision` and `precision_details.issues`:

- **Empty `issues` array**: Stripe Tax determines the most accurate tax rate possible for this address. There’s no additional information you can collect from the customer to get a more precise rate. For example, a US address at `street` precision with no issues means every address on that street has the same tax rate.
- **Non-empty `issues` array**: A more precise tax rate might exist for this location, but the input address doesn’t have enough detail to determine it. Collect or update the fields listed in `issues` to improve the precision.

### Best precision by country

The number of details available to determine tax rates varies by country. After the address reaches the best precision for its country, the `issues` array is empty:

| Country         | Best precision | Required fields                                                                                                             |
| --------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------- |
| United States   | `address`      | `country`, `state`, `city`, `postal_code`, `line1`                                                                          |
| Canada          | `state`        | `country`, and `state` or `postal_code`                                                                                     |
| India           | `state`        | `country`, and `state` or `postal_code`                                                                                     |
| Spain           | `state`        | `country`, and `state` or `postal_code` (for Canary Islands and Ceuta, in the rest of Spain, `country` precision is enough) |
| Other countries | `country`      | `country`                                                                                                                   |

## Collect missing fields with issues

When a more precise tax rate exists but the address doesn’t have enough detail to determine it, the `precision_details.issues` array tells you which fields to collect from the customer. Each issue has:

- `field`: The address field to collect or update (`line1`, `city`, `postal_code`, `state`, or `country`).
- `code`: The type of issue. Currently, the only value is `required_for_improved_precision`, indicating that providing this field might allow Stripe Tax to determine a more precise tax rate.

For example, resolving a US address with only a postal code returns `postal_code` precision with issues for the missing fields:

```json
// Request
{"address": {"country": "US", "postal_code": "94080"}}
```

```json
// Response
{
  "precision": "postal_code",
  "precision_details": {
    "issues": [
      {"field": "city", "code": "required_for_improved_precision"},
      {"field": "line1", "code": "required_for_improved_precision"}
    ]
  },
  "address": {
    "country": "US",
    "postal_code": "94080"
  }
}
```

When `precision_details.issues` is empty, the address yields the most accurate tax rate that Stripe Tax can determine for that location. You don’t need to collect any additional information from the customer.

## Validate addresses in your integration

The typical flow for using address resolution in your integration is:

1. Collect an address from your customer.
1. Call the Address Resolution API to check precision.
1. If `precision_details.issues` contains entries, prompt the customer to provide or update the listed fields. This means a more accurate tax rate is available if the customer provides more address detail.
1. When `precision_details.issues` is empty, the address yields the most accurate tax rate possible.

### Validate before creating a customer

Resolve the address first. If `precision` is `none`, we can’t use the address for tax calculations. If `precision_details.issues` is empty, the tax rate is as accurate as possible and you can create the customer.

```json
// Request
POST /v2/tax/address_resolution

{
  "address": {
    "country": "US",
    "state": "CA",
    "city": "South San Francisco",
    "postal_code": "94080",
    "line1": "354 Oyster Point Blvd"
  }
}
```

```json
// Response — precision_details.issues is empty, so the tax rate is as accurate as possible
{
  "precision": "address",
  "precision_details": {
    "issues": []
  },
  "address": {
    "country": "US",
    "state": "CA",
    "city": "South San Francisco",
    "postal_code": "94080",
    "line1": "354 Oyster Point Blvd"
  }
}
```

If the response contains issues, prompt the customer to provide the missing fields before creating the customer:

```json
// Response — issues present, a more precise tax rate is available
{
  "precision": "postal_code",
  "precision_details": {
    "issues": [
      {"field": "city", "code": "required_for_improved_precision"},
      {"field": "line1", "code": "required_for_improved_precision"}
    ]
  },
  "address": {
    "country": "US",
    "postal_code": "94080"
  }
}
```

### Validate a merchant origin address

You can validate your own origin address before configuring your [tax settings](https://docs.stripe.com/tax/settings-api.md).

```json
// Request
POST /v2/tax/address_resolution

{
  "address": {
    "country": "US",
    "state": "FL",
    "city": "Fort Lauderdale",
    "postal_code": "33301",
    "line1": "433 NE 8th Ave"
  }
}
```

```json
// Response — no issues, safe to use as your origin address
{
  "precision": "address",
  "precision_details": {
    "issues": []
  },
  "address": {
    "country": "US",
    "state": "FL",
    "city": "Fort Lauderdale",
    "postal_code": "33301",
    "line1": "433 NE 8th Ave"
  }
}
```

## Country-specific examples

### United States

For US addresses, the best available precision is `address`. Tax rates in the US can vary down to the street address level, so providing all fields produces the most accurate tax rate.

A partial address returns lower precision with issues, indicating that a more precise tax rate might exist:

```json
// Request
{"address": {"country": "US", "state": "FL", "postal_code": "32789"}}
```

```json
// Response
{
  "precision": "postal_code",
  "precision_details": {
    "issues": [
      {"field": "city", "code": "required_for_improved_precision"},
      {"field": "line1", "code": "required_for_improved_precision"}
    ]
  },
}
```

A US address with only the state and no postal code returns a precision of `none`, because the minimum required fields for a US address aren’t met:

```json
// Request
{"address": {"country": "US", "state": "FL"}}
```

```json
// Response
{
  "precision": "none",
  "precision_details": {
    "issues": [
      {"field": "city", "code": "required_for_improved_precision"},
      {"field": "postal_code", "code": "required_for_improved_precision"},
      {"field": "line1", "code": "required_for_improved_precision"}
    ]
  }
}
```

### Canada

We determine tax rates for Canadian addresses at the province level. The best available precision is `state`. When you provide the state or postal code, the `issues` array is empty because the tax rate is as accurate as it can be:

```json
// Request
{"address": {"country": "CA", "postal_code": "T2P 2P2"}}
```

```json
// Response
{
  "precision": "state",
  "precision_details": {
    "issues": []
  },
}
```

Providing only the country returns `country` precision with issues. Canada has different tax rates by province, so the `issues` array tells you to collect a state or postal code to determine the correct provincial rate:

```json
// Request
{"address": {"country": "CA"}}
```

```json
// Response
{
  "precision": "country",
  "precision_details": {
    "issues": [
      {"field": "state", "code": "required_for_improved_precision"},
      {"field": "postal_code", "code": "required_for_improved_precision"}
    ]
  },
}
```

### Spain

Spain has autonomous regions (Canary Islands and Ceuta) with different tax rates than mainland Spain. When the address resolves to one of these regions, the precision is `state` with an empty `issues` array, meaning the tax rate is as accurate as possible:

```json
// Request
{"address": {"country": "ES", "postal_code": "38003"}}
```

```json
// Response
{
  "precision": "state",
  "precision_details": {
    "issues": []
  },
}
```

When the address resolves to a region with a known state (for example, Malaga), the precision is `country` and the `issues` array is empty. This means the national tax rate applies and no additional address detail produces a different rate:

```json
// Request
{"address": {"country": "ES", "state": "MA"}}
```

```json
// Response
{
  "precision": "country",
  "precision_details": {
    "issues": []
  },
}
```

When you provide only the country, the `issues` array suggests collecting the `state` or `postal_code`. This is because the API can’t determine whether or not the customer is in an autonomous region with a different tax rate without more detail:

```json
// Request
{"address": {"country": "ES"}}
```

```json
// Response
{
  "precision": "country",
  "precision_details": {
    "issues": [
      {"field": "state", "code": "required_for_improved_precision"},
      {"field": "postal_code", "code": "required_for_improved_precision"}
    ]
  },
}
```

When you provide a postal code without a state, the `issues` array always suggests collecting the `state` field because the API can’t validate whether the postal code maps to an autonomous region:

```json
// Request
{"address": {"country": "ES", "postal_code": "29001"}}
```

```json
// Response
{
  "precision": "country",
  "precision_details": {
    "issues": [
      {"field": "state", "code": "required_for_improved_precision"}
    ]
  },
}
```

### Other countries

Most countries apply a single tax rate across their entire territory. For these countries, providing only the country code produces the most accurate tax rate. The empty `issues` array confirms there’s no more precise rate to determine:

```json
// Request
{"address": {"country": "DE", "postal_code": "12345"}}
```

```json
// Response
{
  "precision": "country",
  "precision_details": {
    "issues": []
  },
}
```

## Limitations

- **`line2` isn’t supported**: The Stripe Tax engine doesn’t use `line2` for tax rate determination, so the API doesn’t accept it.
- **Precision guarantees apply to the Stripe Tax engine only**: If you use a third-party tax calculation engine, the precision levels from this API don’t guarantee the same results.
- **Daily rate limits apply.** The API has daily usage limits in both live mode and test mode. Contact [Stripe support](https://support.stripe.com/) if you hit the usage limits.

## Next steps

- [Collect customer addresses](https://docs.stripe.com/tax/customer-locations.md) to understand how Stripe Tax uses addresses for calculations.
- [Calculate tax with the Tax API](https://docs.stripe.com/tax/custom.md) to use validated addresses in tax calculations.
