# Verify API Quickstart

Use this guide to validate your first Australian address, then try Mailpoint, phone, or email validation.

## Before you begin

You need:

- A [Geoscape Hub](https://hub.geoscape.com.au) account and an API key with access to the Verify products you will use
- A terminal with `curl` and `jq` installed. The first example uses `jq` to read the JSON response

Plan access depends on the operation:

- Address validation, geocoding, reverse geocoding, info, and autocomplete are available on Free and paid plans
- Mailpoint, phone validation, and email validation require paid-plan access

See [Verify access](/apis/verify#access) for the access rules.

If you do not have an API key, follow [Authentication](/guides/authentication) first.

**Verify base URL:** `https://api.geoscape.com.au`. Endpoint paths start with `/v1/verify`. Use this base URL for every request below.

## 1. Set your API key

Store the Consumer Key outside source code. Replace the placeholder below with your application's key:

```shell
export GEOSCAPE_API_KEY="YOUR_CONSUMER_KEY"
```

The header name is `Authorization` and its value is the Consumer Key directly. Do not prefix it with `Bearer`.

## 2. Validate an Australian address

Send the address as a JSON request body. `Content-Type: application/json` tells the API how to parse it; JSON-aware clients set this header automatically, while raw-body requests must set it explicitly.

```shell
VERIFY_RESULT=$(curl --fail-with-body \
  "https://api.geoscape.com.au/v1/verify/address/validate/AU" \
  -H "Authorization: $GEOSCAPE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data '{"query":"1 Martin Place Sydney NSW 2000"}')

printf '%s\n' "$VERIFY_RESULT" | jq .
```

- `AU` selects Australian coverage, the only supported address coverage value
- `query` is required and accepts 1–200 characters
- Send request fields in the JSON body. Unsupported body fields return `400`

A successful request returns `200 OK`. This illustrative exact-match response shows the address decision. Live results can differ:

```json
{
  "input": {
    "query": "1 Martin Place Sydney NSW 2000"
  },
  "nextAction": "ACCEPT",
  "id": "GANSW705988020",
  "formatted": "1 MARTIN PL, SYDNEY NSW 2000",
  "attribution": "NOTICE All rights reserved. Use of this data is subject to the Geoscape Hub Terms and Conditions (https://geoscape.com.au/legal/geoscape-developer-terms/)",
  "requestTimeStamp": 1792540800.0,
  "requestDateTime": "2026-10-21T00:00:00+00:00"
}
```

## 3. Read the address decision

Use `nextAction` before accepting an address:

- `ACCEPT`: the first candidate has Exact match quality
- `ACCEPT_WITH_CHANGES`: the first candidate has Confident match quality. Ask the user to confirm the returned address
- `DENY`: ask for a correction or review. A denied result can still include a lower-quality candidate's `id` and `formatted`

A `200` response means the check completed, not that the address was accepted. Fields unavailable from a candidate are omitted.

## 4. Try another Verify check

Each endpoint checks one record and accepts JSON. Choose the operation you need.

### Match a postal address with Mailpoint

```shell
curl --fail-with-body \
  "https://api.geoscape.com.au/v1/verify/mailpoint/validate/AU" \
  -H "Authorization: $GEOSCAPE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data '{"query":"1 Martin Place Sydney NSW 2000"}'
```

`query` is required and accepts 1–200 characters. Read `matchScore`, `properties.dpid`, and the returned postal address. A no-match response uses `matchScore: 0` and `properties.dpid: "00000000"`. Do not accept that sentinel DPID.

### Validate and format a phone number

```shell
curl --fail-with-body \
  "https://api.geoscape.com.au/v1/verify/phone/validate" \
  -H "Authorization: $GEOSCAPE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data '{"phone":"+1 202 5xx xxxx"}'
```

The number is masked. Replace the `x` characters with a number you are authorised to validate before testing.

`phone` is required and accepts 1–40 characters. This fictional US number has an explicit country code. Numbers without a country code are interpreted as Australian numbers.

Use `format.e164` for storage and comparison. `valid` checks the numbering range and does not confirm ownership or a live connection.

### Check an email address

```shell
curl --fail-with-body \
  "https://api.geoscape.com.au/v1/verify/email/validate" \
  -H "Authorization: $GEOSCAPE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  --data '{"email":"xxx@example.com"}'
```

`email` is required and accepts 1–320 characters. `example.com` publishes a null MX record, indicating that it accepts no email. Expect `200` with `valid: false`, `syntax.valid: true`, and `domain.has_mx: false`.

A true verdict confirms syntax and usable mail servers. It does not confirm mailbox existence. Role, consumer-provider, and disposable-email flags help you set your own acceptance policy.

See [Interpreting Results](/guides/verify/interpreting-results) for check definitions, omitted fields, and further examples. Address autocomplete, geocoding, and reverse geocoding are covered under [Other address operations](/guides/verify/interpreting-results#other-address-operations).

## 5. Retrieve address details (optional)

After an accepted result provides an ID, retrieve its details. This command reads the ID from the saved validation response and builds the JSON body:

```shell
ADDRESS_ID=$(printf '%s\n' "$VERIFY_RESULT" | jq -er 'select(.nextAction == "ACCEPT" or .nextAction == "ACCEPT_WITH_CHANGES") | .id')
```

If this command succeeds, run:

```shell
jq -n --arg id "$ADDRESS_ID" '{id: $id}' | \
  curl --fail-with-body \
    "https://api.geoscape.com.au/v1/verify/address/info/AU" \
    -H "Authorization: $GEOSCAPE_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    --data-binary @-
```

The response is a `Feature` containing address properties and geometry when available. An unknown ID returns `200` with empty `properties`.

<span id="transaction-usage-and-request-rates"></span>

## Credit usage and request rates

| Operation | Credits per processed request |
| --- | --- |
| Address autocomplete | 0.1 |
| Address validation, geocoding, reverse geocoding, or info | 1 |
| Email or phone validation | 1 |
| Mailpoint | 2 |

Read `x-attr-basicTransaction` for the credit cost. Processed invalid or no-match results still incur these costs. An access refusal is not charged.

Request-rate limits are separate from credit usage. Follow your subscription's allowance and see [Rate Limiting](/guides/rate-limiting) for throttling and retry guidance.

## If a request fails

| Status | What to check |
| --- | --- |
| `400` | Required fields, input lengths, JSON syntax, and unsupported body fields. Email and phone endpoints also reject query parameters. Correct the request |
| `401` | Consumer Key and application access |
| `403` | Product access. Mailpoint, phone, and email validation require a paid plan |
| `429` | Request rate. Follow your subscription allowance and retry with backoff |
| `500` | Service or lookup failure. Retry transient failures with backoff and contact support if they persist |

Verify service errors contain `error_count`, a structured `errors` array, echoed `input`, `attribution`, `timestamp`, and `requestDateTime`. Success responses use `requestTimeStamp` instead of `timestamp`. Gateway errors can have a different body. Inspect the HTTP status first and keep API keys and contact data out of your logs. See [Verify errors](/guides/verify/interpreting-results#verify-errors) for the error example and recovery guidance.

## Next steps

- [Interpret address and contact results](/guides/verify/interpreting-results)
- [Choose a Verify operation](/apis/verify)
- [Handle errors and retries](/guides/errors)
- [Apply request-rate limits](/guides/rate-limiting)
