# Report what happened to post you sent

`POST /api/v1/address/feedback`

- Authentication: Secret API key as a bearer token
- Billing: Free.
- Group: Address

Tells Spaw what became of post your account sent to an address: `delivered`, `returned` (it came back), `moved` (the occupant is no longer there) or `refused` (delivery was refused). Your own reports feed your own later lookups of that address, with the dataset `address-feedback`: an address whose most recent report within 90 days is `returned`, `moved` or `refused` rather than `delivered` scores `reported_returned` (+50), and a delivery reported afterwards cancels it.

Reports also keep your postal suppression list: a `moved` or `refused` report suppresses the address at once, a second `returned` report with no later delivery suppresses it, and a `delivered` report clears an entry your reports added.

There is deliberately no cross-account reputation here and no provider webhook. A postal address is where somebody lives, and a shared "post fails here" database would be a database about residences. What you report raises the risk of your own lookups and of nobody else's, and no other account ever sees it.

Each item is a written address or the separated fields, and may name its own `country`, which wins over the request-level one. Addresses are folded the way a lookup folds them, so any spelling of one building lines up; an item that names no building — no postcode or locality, no street, no house number — is skipped and counted, not rejected. Feedback is free, never billed and never logged as a lookup. Reports are kept for 180 days.

## Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `items` | object[] | yes | 1 to 1,000 reports per request. |
| `items[].address` | string | null | no | The whole address written as it would be on an envelope. Required unless address_line1 is sent. At most 500 characters. |
| `items[].address_line1` | string | null | no | The street line, when the address arrives separated. Required unless address is sent. At most 255 characters. |
| `items[].address_line2` | string | null | no | At most 255 characters. |
| `items[].organization` | string | null | no | At most 200 characters. |
| `items[].dependent_locality` | string | null | no | At most 100 characters. |
| `items[].locality` | string | null | no | At most 100 characters. |
| `items[].administrative_area` | string | null | no | At most 100 characters. |
| `items[].postal_code` | string | null | no | At most 32 characters. |
| `items[].po_box` | string | null | no | At most 64 characters. |
| `items[].country` | string | null | no | This item's own country; overrides the request-level one. At most 2 characters. |
| `items[].outcome` | string | yes | One of: delivered, returned, moved, refused. |
| `items[].occurred_at` | string | null | no | When it happened. Defaults to now. |
| `country` | string | null | no | An ISO 3166-1 alpha-2 code applied to items that do not name their own. At most 2 characters. |

## Example request

```bash
curl -X POST https://spaw.co/api/v1/address/feedback \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "country": "GB",
  "items": [
    {
      "address": "221B Baker Street, London NW1 6XE",
      "outcome": "returned"
    },
    {
      "address_line1": "10 Downing Street",
      "locality": "London",
      "postal_code": "SW1A 2AA",
      "outcome": "moved",
      "occurred_at": "2026-09-05T09:00:00Z"
    }
  ]
}'
```

## Responses

### 202 — The reports were recorded.

```json
{
    "success": true,
    "data": {
        "recorded": 2,
        "skipped": 0
    }
}
```

### 401 — The key is missing, malformed, or revoked.

```json
{
    "success": false,
    "error": {
        "code": "UNAUTHENTICATED",
        "message": "Provide a valid API key as a bearer token.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}
```

### 422 — The request body could not be validated; `error.errors` lists the fields.

```json
{
    "success": false,
    "error": {
        "code": "VALIDATION_FAILED",
        "message": "The email field is required.",
        "errors": {
            "email": [
                "The email field is required."
            ]
        },
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}
```

### 429 — Over 5 requests per second for the key. Retry after the limit resets.

```json
{
    "success": false,
    "error": {
        "code": "RATE_LIMITED",
        "message": "Too many requests. Retry after the limit resets.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}
```

## Error codes

- `UNAUTHENTICATED` — https://spaw.co/docs/errors/UNAUTHENTICATED
- `VALIDATION_FAILED` — https://spaw.co/docs/errors/VALIDATION_FAILED
- `RATE_LIMITED` — https://spaw.co/docs/errors/RATE_LIMITED

---

Canonical page: https://spaw.co/docs/api/report-address-feedback · OpenAPI document: https://spaw.co/openapi.json · All endpoints: https://spaw.co/docs/api
