# Person Report

`POST /person_report`

- Live: `POST https://gdapi.globaldata.net.au/api/v2/person_report`
- Sandbox: `POST https://sandbox-gdapi.globaldata.net.au/api/v2/person_report`

## Experimental

The Person Report API is still in the experimental stage and is subject to change.

Takes whatever you know about a person - a name, a date of birth, an address or locality, a phone
number, an email address, or any combination - resolves it to a **single person** in the Global Data
universe, and returns a consolidated report of everything held about them.

Resolution is iterative: each source consulted (the person universe, the ASIC person register, the
commercial universe, social enrichment) can return new identifiers, which feed the next round of
searches until no new information appears. Every fact in the report cites the lookup it came from,
and a plain-English research log records what was searched, what was found, what was decided and
what was rejected.

## Asynchronous

The request is queued and answered immediately with an acknowledgement carrying a `request_uuid`
and `result_url` - nothing else. Poll `GET /person_report/{request_uuid}` (free) until `status` is
`complete`; the full report response (`search_criteria`, `resolution`, `report`, `provenance`) is
documented on that endpoint. Results are retained for 24 hours.

## Resolution outcomes

The `resolution.outcome` field tells you what happened. Only a `resolved` outcome carries a `report`.

| Outcome | Meaning | What to do |
|:--|:--|:--|
| `resolved` | One subject was identified with `medium` or `high` confidence. | Read the `report`. |
| `low_confidence` | One candidate matched on name only; the details you supplied did not corroborate it. | Confirm with the `candidate_token`, or add a phone / email / date of birth. |
| `ambiguous` | Several people match. A redacted candidate list is returned. | Re-submit with the `candidate_token` of the right person, or add narrowing details. |
| `too_many` | The name is too common to list. Distribution hints are returned. | Add a date of birth, postcode, phone or email. |
| `not_found` | Nothing matched. | Check the details; try a different identifier. |

Date of birth is treated as evidence, not a key: a supplied date that is a day out, or has the day and
month swapped, will still match and is reported as a `near_miss`. Where sources disagree the report
lists every date seen in `birth_date_candidates` with its supporting votes.

## Sections

Every report is as comprehensive as the sources allow - there is no way to narrow it. It always
contains `identity`, `addresses` (an address timeline - each entry carries the subject's tenure,
occupancy, the other people seen at that address with their overlap, and real-estate events there),
`contacts`, `household` (possible relatives - co-residents sharing the surname, extended to every
same-surname person when the surname is rare), `business`, `asic`, `watchlists`, `court` (court
record summaries, matched on name and labelled as unverified), `judgements` and `social`
(professional profile, employment history and social profile URLs, where a social profile matches
one of the subject's phones or emails and carries the subject's name).

Every section carries a `status` of `ok`, `empty`, `clear` (watchlists), `skipped` or `error`, so one
unavailable source never fails the whole report.

## Provenance

`provenance.sources` lists every lookup performed (with the exact query, dataset or provider, round
and result count), `provenance.inferences` every conclusion drawn (with the rule applied and the
evidence it rests on), and `provenance.research_notes` the chronological research log. Facts in the
report cite source ids (`S1`, `S2`, ...) and inference ids (`I1`, `I2`, ...). Use `provenance: summary`
for a compact form or `none` to suppress it.

## Billing

One unit per call. Accounts billed on **success** are only charged when the outcome is `resolved`;
`ambiguous`, `too_many`, `low_confidence` and `not_found` responses are free. Accounts billed on
**attempt** are charged for every call.

## Sandbox environment data

The sandbox runs against the sample universe. Useful inputs:

| Input | Outcome |
|:--|:--|
| `first_name: John`, `last_name: Smith`, `birth_date: 1998-03-21` | `resolved` - full report including real-estate events on the address timeline |
| `phone: 0427151494` | `resolved` - Robert Patrick Brown, two universe rows merged on a shared email |
| `email: jsmith1998@example.com` | `resolved` |
| `first_name: Robert`, `last_name: Brown` | `ambiguous` - two candidates with `candidate_token`s |
| `first_name: Mary`, `last_name: Jones` | `resolved` on a rare name alone |
| `first_name: Aaron`, `last_name: Wolfe` | `resolved` with Ruth Wolfe as a possible relative |

## Request body

Whatever is known about the person. At least a first and last name, a phone, an email, or a candidate token is required.

| Field | Type | Description |
|-------|------|-------------|
| `first_name` | string | First (given) name. Common equivalents (Tony / Antonio, Bob / Robert) are searched automatically. Example: `John` |
| `middle_name` | string or null | Middle name(s), if known. Example: `Andrew` |
| `last_name` | string | Surname. Matched exactly - make sure the spelling is right. Example: `Smith` |
| `birth_date` | string (date) or null | Date of birth. Treated as evidence - near misses still match and are reported. Example: `1998-03-21` |
| `phone` | string or null | An Australian phone number in 0NSN or +61 format. Example: `+61427151494` |
| `phones` | array of strings [max 4 items] | Up to four phone numbers. |
| `email` | string (email) or null | An email address. Example: `jsmith1998@example.com` |
| `emails` | array of strings [max 4 items] | Up to four email addresses. |
| `gnaf_id` | string or null | A GNAF address identifier, when the address is already resolved. Example: `GAVIC421647320` |
| `suburb` | string or null | Suburb, as a narrowing input. Example: `Lilydale` |
| `state` | string or null | State, as a narrowing input. Enum: `ACT`, `NSW`, `NT`, `QLD`, `SA`, `TAS`, `VIC`, `WA` Example: `VIC` |
| `postcode` | string or null | Postcode, as a narrowing input. Example: `3140` |
| `candidate_token` | string or null | A token from a previous `ambiguous` or `low_confidence` response selecting one candidate. Valid for one hour, in the same environment only. |
| `provenance` | string | How much provenance to return. Enum: `full`, `summary`, `none` Default: `full` |

**Sample request**

```json
{
    "first_name": "John",
    "middle_name": "Andrew",
    "last_name": "Smith",
    "birth_date": "1998-03-21",
    "phone": "+61427151494",
    "phones": [
        "string"
    ],
    "email": "jsmith1998@example.com",
    "emails": [
        "user@example.com"
    ],
    "gnaf_id": "GAVIC421647320",
    "suburb": "Lilydale",
    "state": "VIC",
    "postcode": "3140",
    "candidate_token": "string",
    "provenance": "full"
}
```

## Responses

### 200 Request accepted and queued. This response is an acknowledgement only - poll `GET /person_report/{request_uuid}` for the result, which is documented on that endpoint.

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `message` | string | Example: `Ok` |
| `function` | string | Example: `person_report` |
| `api_reference` | string (uuid) | Reference for this request; also the billing correlation id. |
| `request_uuid` | string (uuid) | Use to poll for the result. |
| `status` | string | Enum: `pending` |
| `result_url` | string (uri) | Absolute URL of the poll endpoint for this request. |

**Sample response**

```json
{
    "message": "Ok",
    "function": "person_report",
    "api_reference": "00000000-0000-0000-0000-000000000000",
    "request_uuid": "00000000-0000-0000-0000-000000000000",
    "status": "pending",
    "result_url": "https://example.com"
}
```

Standard error responses: 400, 401, 402, 403, 429, 5XX (see [Common error responses](/docs/reference/general/common-error-responses.md))

