# Error Handling

Use this guide to interpret HTTP status codes and error bodies, correct failed requests, and choose when to retry.

The Geoscape API uses standard HTTP status codes. A successful request returns a `2xx` status. A failed request returns a `4xx` or `5xx` status. Treat the status code as the primary signal and inspect the response body for endpoint-specific diagnostic details.

For general information on HTTP status codes, see the [REST API Tutorial](https://www.restapitutorial.com/httpstatuscodes.html#).

## Common status codes

| Status | Meaning | What to do |
| --- | --- | --- |
| `400` | Bad request | Check the URL, query parameters, required fields, and parameter values before retrying. |
| `401` | Unauthorized | Check that the API key is present, valid, active, and permitted to use the product. |
| `403` | Forbidden | Check product access, licensing, job ownership, or available credits as documented for the endpoint. |
| `404` | Not found | Check the endpoint path, API version, and resource identifier. |
| `405` | Method not allowed | Check the HTTP method documented for the path. Some actions, such as deleting batch jobs, use POST. |
| `409` | Conflict | Resolve the resource state reported by the endpoint before retrying. |
| `429` | Too many requests | Slow down, apply backoff, and review [Rate Limiting](/guides/rate-limiting). |
| `500` | Internal server error | Retry with backoff if appropriate. Contact support if the problem persists. |

## Troubleshooting example

```shell
curl --fail-with-body \
  "https://api.psma.com.au/v2/addresses/geocoder?address=1%20Swanston%20Street%20Melbourne%20VIC%203000" \
  -H "Authorization: $GEOSCAPE_API_KEY" \
  -H "Accept: application/geo+json"
```

When handling errors in application code:

- Correct request and access errors before retrying. An unchanged `400`, `401`, `403`, or `404` usually fails again.
- Retry `429` and transient service failures with exponential backoff and a maximum retry count
- Before retrying a POST that creates or changes a job, check whether the first request succeeded. Do not blindly resubmit a batch after a timeout
- Log a request identifier or response headers when available, but never log the API key.
- Show users an actionable message rather than exposing the raw response or credentials.

## Read the error body

Error bodies differ between services and the gateway:

- Many API service errors use a JSON `messages` array, with `requestTimeStamp` and `requestDateTime`
- Gateway authentication errors can use a JSON `fault` object with `faultstring` and `detail.errorcode`
- Maps errors can use plain text
- Signed file-download URLs can return storage-service errors rather than the API’s JSON model

A service error can look like this:

```json
{
  "messages": [
    "Bad Request, the service could not understand your request"
  ],
  "requestTimeStamp": 1667972874.590019,
  "requestDateTime": "2022-11-09T05:47:54.590019"
}
```

Use the endpoint’s response schema for its error fields and messages. Handle the HTTP status even if the body is empty or cannot be parsed as JSON.

### Verify service errors

Verify service errors use `error_count` and a structured `error` array containing `type`, `description`, and an optional `field`. They also include echoed request `input`, `attribution`, `timestamp`, and `requestDateTime`. Errors use `timestamp` while successful Verify responses use `requestTimeStamp`. Service and lookup failures return `500` with a generic support description. Gateway authentication and rate-limit failures can have a different body.

See [Verify errors](/guides/verify/interpreting-results#verify-errors) for a complete example and recovery guidance. Avoid logging the echoed input because it can contain contact details.

## Distinguish request errors from result messages

A `200` response can still report no match, missing optional data, or a job still in progress. Check the result’s features, messages, or job status before accepting it. A batch deletion also returns per-job failure codes inside an HTTP `200` response. See [Managing Jobs](/guides/batches/managing-jobs#check-each-deletion-result).

## Next steps

- [Review authentication](/guides/authentication)
- [Handle request rates](/guides/rate-limiting)
- [Browse the API Reference](/reference)
