Skip to main content

Using Passfort

Run a Geodistance check and a Geocoding check (API)

This developer guide takes you through the steps to run a Geodistance check in the Passfort API 4.0 to confirm whether two coordinates are within the same proximity.

The guide also includes instructions for using the Geocoding check to get the coordinates of the customer's stated address to use in the Geodistance check.

Get the profile's ID and confirm it has the required fields

Select a profile for the check

The Geodistance check and Geocoding check are always run on profiles with the INDIVIDUAL entity type.

Choose an individual profile to run the check on, and get the profile's ID number, for example, a2c4393a-e219-67a4-5ab4-2186952e9038. You'll need it to make the request in the next step.

If you haven't created the company's profile yet, follow the steps to create a profile via the API. You can also create a profile via the portal. To get the profile ID, view the profile in the portal and copy the string of letters and numbers after /onboarding/ in the URL.

Confirm the profile has the required fields

The Geodistance check and Geocoding check are run on the Verify address task (INDIVIDUAL_VERIFY_ADDRESS).

Geodistance check only

If you're only running the Geodistance check, the profile does not require any additional fields. You can confirm it has the Verify address task by making a request to the following endpoint.

Request endpoint:

GET https://api.passfort.com/4.0/profiles/{profile_id}/tasks

In this example, the only task on the profile is Verify address.

Sample response:

[
    {
        "check_ids": [ ],
        "creation_date": "2020-08-27 13:48:16",
        "form_instance_ids": [ ],
        "id": "72aadb55-8b02-8495-d6b0-e1627ec23612",
        "is_complete": false,
        "is_expired": false,
        "is_skipped": false,
        "state": "INCOMPLETE",
        "type": "INDIVIDUAL_VERIFY_ADDRESS",
        "variant": {
            "alias": "verify_address",
            "id": "5562c4e4-4d12-b16a-a151-7c9eed6816e9",
            "task_type": "INDIVIDUAL_VERIFY_ADDRESS"
        }
    }
]

Use the response to:

  • Confirm the profile has the INDIVIDUAL_VERIFY_ADDRESS task.

  • Take note of the task ID (id). Use the corresponding task alias (variant.alias) to confirm you're looking at the right task. If there is more than one task with the same alias, which happens when a task has more than one version, use the task with "is_expired": "false". Note that the task variant ID (variant.id) won't be used to run this check, so you don't need to take note of it.

Geodistance check and geocoding check

If, in addition to the Geodistance check, you want to run the Geocoding check to get the latitude and longitude of the customer's stated address, you have two options:

  • You can send the stated address in the request to run the Geocoding check.

  • You can run the Geocoding check without an address, which retrieves the latitude and longitude for the address in the profile's collected_data.

If you're sending the stated address in the request to run the Geocoding check, the profile only needs to have the Verify address task. Use the endpoint above to confirm if the task is present.

If you want to use the address in the profile's collected_data, you can confirm it's there as well as confirm the profile has the Verify address task by making a single call to the following endpoint.

Request endpoint:

GET https://api.passfort.com/4.0/profiles/{profile_id}/tasks

In this example, data is returned for an individual profile with an address and the Verify address task.

Sample response:

{
    "applications": [ … ],
    "category": "APPLICANT",
    "checks": [ ],
    "collected_data": {
        "entity_type": "INDIVIDUAL",
        "address_history": [
            {
                "address": {
                    "type": "STRUCTURED",
                    "country": "GBR",
                    "locality": "London",
                    "original_freeform_address": "38, Crown Street, London, W1 2ZT",
                    "original_structured_address": { … },
                    "postal_code": "W1 2ZT",
                    "route": "Crown Street",
                    "street_number": "38"
                }
            }
        ],
        "personal_details": { … }
    },
    "collection_steps": [ ],
    "creation_date": "2020-08-27 12:50:07",
    "display_name": "Alex Wheeler",
    "document_images": [ ],
    "events": [ ],
    "has_associates": false,
    "has_collection_steps": false,
    "id": "a2c4393a-e219-67a4-5ab4-2186952e9038",
    "linked_to": [ ],
    "role": "INDIVIDUAL_CUSTOMER",
    "root_id": "6bba3592-d9de-1ee5-8e97-ba8d8d13c558",
    "status": "NORMAL",
    "tags": [ ],
    "task_progress": { … },
    "task_types": [
        "INDIVIDUAL_VERIFY_ADDRESS"
    ],
    "tasks": [
        {
            "check_ids": [ ],
            "creation_date": "2020-08-27 12:50:07",
            "form_instance_ids": [ ],
            "id": "3d7a333c-418d-72a1-007b-06854dbb28eb",
            "is_complete": false,
            "is_expired": false,
            "is_skipped": false,
            "state": "INCOMPLETE",
            "type": "INDIVIDUAL_VERIFY_ADDRESS",
            "variant": {
                "alias": "fraud_check_individuals",
                "id": "ddc72ea7-6e45-cc3b-dc52-30a94b9ec8c2",
                "task_type": "INDIVIDUAL_VERIFY_ADDRESS"
            }
        }
    ],
    "unresolved_event_types": [ ]
}

Use the response to:

  • Confirm the profile has the INDIVIDUAL_VERIFY_ADDRESS task.

  • Take note of the task ID (tasks.id). Use the corresponding task alias (tasks.variant.alias) to confirm you're looking at the right task. If there is more than one task with the same alias (which happens when a task has more than one version), use the task with "is_expired": "false". Note that the task variant ID (tasks.variant.id) won't be used to run this check, so you don't need to take note of it.

  • Confirm the profile has an address (collected_data.address_history.address).

If the individual has multiple addresses, the most recent address is used. If no dates are provided, the address is selected at random. To add an address to the profile's collected_data, follow the steps to update Passfort's profile data.

Get the coordinates of the customer's stated address

To run the check, you'll need the latitude and longitude of the customer's stated address.

If you have this information, you can skip to the next section.

If not, you can use the Geocoding check to get the latitude and longitude.

Run the Geocoding check

To get the latitude and longitude of the address in the profile using the Geocoding check, make the following request.

Request endpoint:

POST https://api.passfort.com/4.0/profiles/{profile_id}/checks

By default, the Geocoding check runs asynchronously. You can also send mode as a query parameter to run the check synchronously.

Body parameters:

When you make the POST request, include the following parameters in the body.

Key

Value

Description

check_type

*Required

string

GEOCODING

The type of check that's being run.

task_ids

Optional, but we recommend including it whenever possible

string

Sample value: 3d7a333c-418d-72a1-007b-06854dbb28eb

When you're running the check on an individual profile, this is the unique identifier for the INDIVIDUAL_VERIFY_ADDRESS task.

variant

*Required

object

For a sample value, see Sample request body below.

Object to indicate which variant of the check will run.

variant.alias

*Required

String

This key is optional if variant.id is provided, but we recommend sending the alias whenever possible.

Sample value: default

The check alias.

variant.id

*Required

String

This key is optional if variant.alias is provided.

Sample value:

ea70ade9-3de3-1785-203b-68044cd3ecbb

The unique identifier for the check.

address

Optional

Object

For a sample value, see Sample request body below.

Object containing the address.

If you do not send an address in the request, the address from the profile is used.

address.type

*Required

String

STRUCTURED

The address type.

Note that freeform addresses cannot be used to run this check. Learn how to convert a freeform address to a structured address.

address.country

*Required

String

Sample value: GBR

The country must be provided as an ISO3 code.

The country of the address.

county

Optional

String

Sample value: Middlesex

The county of the address.

Note that a US state or a Canadian province or territory should not go here.

locality

Optional

String

Sample value: London

The city or town of the address.

original_freeform_address

Optional

String

Sample value:

, , 38, Crown Street, London, , Middlesex, , W1 2ZT

The freeform address, prior to structuring attempts.

postal_code

Optional

String

Sample value: W1 2ZT

The postal code or zip code of the address.

postal_town

Optional

String

Sample value: London

The postal town or district of the address.

premise

Optional

String

Sample value: Princelet House

The name of the building.

route

Optional

String

Sample value: Crown Street

The name of the route or street.

state_province

*Required (US, Canada, Australia)

Optional (all other countries)

String

Sample value: ON

The state, province, or territory of the address.

The format follows the state code of the ISO-3166-2 standard.

Note that a UK county should not go here.

street_number

Optional

String

Sample value: 38

The street number of the address.

subpremise

Optional

String

Sample value: Flat C

The subaddress within the building. Typically this is a flat number.

Sample request body:

{
    "check_type": "GEOCODING",
    "task_ids": [
        "3d7a333c-418d-72a1-007b-06854dbb28eb"
    ],
    "variant": {
        "alias": "default"
    },
    "address": {
        "type": "STRUCTURED",
        "country": "GBR",
        "locality": "London",
        "original_freeform_address": "38, Crown Street, London, W1 2ZT",
        "postal_code": "W1 2ZT",
        "route": "Crown Street",
        "street_number": "38"
    }
}

Sample response:

{
  "address": {
    "country": "GBR",
    "locality": "London",
    "original_freeform_address": "38, Crown Street, London, W1 2ZT",
    "original_structured_address": {
      "country": "GBR",
      "locality": "London",
      "postal_code": "W1 2ZT",
      "route": "Crown Street",
      "street_number": "38"
    },
    "postal_code": "W1 2ZT",
    "route": "Crown Street",
    "street_number": "38",
    "type": "STRUCTURED"
  },
  "check_type": "GEOCODING",
  "id": "72aadb55-8b02-8495-d6b0-e1627ec23612",
  "instructed_on": "2020-08-27 13:52:25",
  "performed_on": "2020-08-27 13:52:25",
  "providers": [],
  "state": "PENDING",
  "task_ids": [
    "3d7a333c-418d-72a1-007b-06854dbb28eb"
  ],
  "variant": { ... }
}

Take note of the check id in the response because you'll need it for the next sections to learn how to get the check results.

Because this check runs asynchronously, the check state is expected to be PENDING in the response.

Get the check result

Listen to the Check completed webhook to get a notification when the check is finished running and to learn what the result is.

This webhook sends a payload whenever results are returned from any check (including checks other than the Geocoding check).

Payloads from this webhook have several important keys:

  • secret: Authenticate the request by ensuring this secret matches your secret.

  • data.check.id: The check ID. Use it to confirm the payload is for your check by matching it to the check ID you captured in the previous step.

  • data.check.check_type: The type of check was run. When the Geocoding check is run, the value is GEOCODING.

  • data.check.variant.alias: The alias for the check variant. You can use it for additional confirmation that the payload is for your check by matching it to the check variant alias you captured in the previous step.

  • data.check.result: The results of the check. Possible results for the Geocoding check are Pass, Fail, or Error. If the coordinates are found, the result is Pass. If the coordinates cannot be found, the result is Fail.

In this example, the Geocoding check was able to find the latitude and longitude, which we know because the result is Pass.

{
  "id": "33bae6b8-5689-b96b-143c-06e93ab8527e",
  "event": "CHECK_COMPLETED",
  "secret": "yourSecret",
  "timestamp": 1570807808,
  "data": {
    "check": {
      "check_type": "GEOCODING",
      "id": "72aadb55-8b02-8495-d6b0-e1627ec23612",
      "result": "Pass",
      "variant": {
        "alias": geocoding",
        "id": "ea565b55-47d9-1858-4588-3a22a3838707",
        "name": "Geocoding"
      }
    },
    "customer_ref": null,
    "profile_id": "a2c4393a-e219-67a4-5ab4-2186952e9038"
  }
}
Getting more information about the check result

To get the latitude and longitude of the address, make a call to the following endpoint.

In the request, include the profile ID and the check ID.

Request endpoint:

GET https://api.passfort.com/4.0/profiles/{profile_id}/checks/{check_id}

Sample response:

{
  "address": {
    "country": "GBR",
    "locality": "London",
    "original_freeform_address": "38, Crown Street, London, W1 2ZT",
    "original_structured_address": {
      "country": "GBR",
      "locality": "London",
      "postal_code": "W1 2ZT",
      "route": "Crown Street",
      "street_number": "38"
    },
    "postal_code": "W1 2ZT",
    "route": "Crown Street",
    "street_number": "38",
    "type": "STRUCTURED"
  },
  "check_type": "GEOCODING",
  "completed_on": "2020-08-27 13:52:25",
  "decision": "PASS",
  "errors": [],
  "id": "d526831a-e2f2-11ea-ab2b-1e271aa31109",
  "input_data": {
    "address_history": [ … ],
    "entity_type": "INDIVIDUAL"
  },
  "instructed_on": "2020-08-27 13:52:25",
  "output_data": {
    "address_history": [
      {
        "address": {
          "country": "GBR",
          "latitude": 57.145618,
          "locality": "London",
          "longitude": -2.096897,
          "original_freeform_address": "Crown Street, London, W1 2ZT",
          "original_structured_address": {
            "country": "GBR",
            "latitude": 57.145618,
            "locality": "London",
            "longitude": -2.096897,
            "postal_code": "W1 2ZT",
            "route": "Crown Street"
          },
          "postal_code": "W1 2ZT",
          "route": "Crown Street",
          "street_number": "",
          "type": "STRUCTURED"
        }
      }
    ],
    "entity_type": "INDIVIDUAL"
  },
  "performed_on": "2020-08-27 13:52:25",
  "providers": [ … ],
  "result": "Pass",
  "started_on": "2020-08-27 13:52:25",
  "state": "COMPLETE",
  "task_ids": [
    "692e8682-e239-11ea-9218-5a65e6bcfda0"
  ],
  "variant": {
    "id": "631897c2-e179-11ea-ba0a-5694cb8533a6",
    "name": "Geocoding"
  }
}

Capture the latitude (output_data.address_history.address.latitude) and the longitude (output_data.address_history.address.latitude) so you have it when you run the Geodistance check.

Get the coordinates of the user's current location

To run the Geodistance check, you'll also need the latitude and longitude of the user's current location.

Once you have this information, you can go to the step to run the Geolocation check.

You can use the Device fraud detection check with TransUnion TruValidate to get the coordinates of the user's device. To do so, follow the steps to run a Device fraud detection check. When you get more information about the check result, the latitude and longitude are returned in the output_data.ip_location.coordinates object.

Run the Geodistance check

To run the Geodistance check, make a request to the following endpoint.

Request endpoint:

POST https://api.passfort.com/4.0/profiles/{profile_id}/checks

By default, the Geodistance check runs asynchronously, but you can send mode as a query parameter to run the check synchronously.

Body parameters:

When you make the POST request, include the following parameters in the body.

Key

Value

Description

check_type

*Required

string

GEODISTANCE

The type of check that's being run.

task_ids

Optional, but we recommend including it whenever possible

string

Sample value: 3d7a333c-418d-72a1-007b-06854dbb28eb

When you're running the check on an individual profile, this is the unique identifier for the INDIVIDUAL_VERIFY_ADDRESS task.

variant

*Required

object

For a sample value, see the following sample request body.

Object to indicate which variant of the check will run.

variant.alias

*Required

string

This key is optional if variant.id is provided, but we recommend sending the alias whenever possible.

Sample value: default

The check alias.

variant.id

*Required

string

This key is optional if variant.alias is provided.

Sample value: ea70ade9-3de3-1785-203b-68044cd3ecbb

The unique identifier for the check.

coordinates

*Required

object

For a sample value, see the following sample request body.

Object with the coordinates for the stated address and current location.

coordinates.p1

*Required

object

For a sample value, see the following sample request body.

Object with the latitude and longitude of the stated address.

coordinates.p1.name

Optional

string

Sample value: Stated address

The name of the first coordinate.

If you do not send a name, this coordinate will be named Initial point .

coordinates.p1.latitude

*Required

float

Sample value: 53.38297

Latitude of the stated address.

coordinates.p1.longitude

*Required

Float

Sample value: -1.4659

Longitude of the stated address.

coordinates.p2

*Required

Object

For a sample value, see the following sample request body.

Object with the latitude and longitude of the current address.

coordinates.p2.name

Optional

string

Sample value: Current location

The name of the second coordinate.

If you do not send a name, this coordinate will be named Final point

coordinates.p2.latitude

*Required

float

Sample value: 51.50853

Latitude of the current address.

coordinates.p2.longitude

*Required

float

Sample value: -0.12574

Longitude of the current address.

Sample request body:

{
    "check_type":"GEODISTANCE",
    "task_ids": [
        "3d7a333c-418d-72a1-007b-06854dbb28eb"
    ],
    "variant": {
        "alias": "default"
    },
    "coordinates": {
        "p1": {
            "name": "Stated address",
            "latitude": 53.38297,
            "longitude": -1.4659
        },
        "p2": {
            "name": "Current location",
            "latitude": 51.50853,
            "longitude": -0.12574
        }
    }
}

Sample response:

{
  "check_type": "GEODISTANCE",
  "coordinates": {
    "p1": {
      "name": "Stated address",
      "latitude": 53.38297,
      "longitude": -1.4659
    },
    "p2": {
      "name": "Current location",
      "latitude": 51.50853,
      "longitude": -0.12574
    }
  },
  "id": "72aadb55-8b02-8495-d6b0-e1627ec23612",
  "instructed_on": "2020-08-27 13:53:12",
  "performed_on": "2020-08-27 13:53:12",
  "providers": [ ],
  "state": "PENDING",
  "task_ids": [
    "3d7a333c-418d-72a1-007b-06854dbb28eb0"
  ],
  "variant": { … }
}

Take note of the check id in the response because you'll need it for the sections to learn how to get the check results.

Because this check runs asynchronously, the check state is expected to be PENDING in the response.

Get the check result

Listen to the Check completed webhook to get a notification when the check is finished running and to learn what the result is.

This webhook sends a payload whenever results are returned from any check, including checks other than the Geodistance check.

Payloads from this webhook have several important keys:

  • secret: Authenticate the request by ensuring this secret matches your secret.

  • data.check.id: The check ID. Use it to confirm the payload is for your check by matching it to the check ID you captured in the previous step.

  • data.check.check_type: The type of check was run. When the Geodistance check is run, the value is GEODISTANCE.

  • data.check.variant.alias: The alias for the check variant. You can use it for additional confirmation that the payload is for your check by matching it to the check variant alias you captured in the previous step.

  • data.check.result: The results of the check. Possible results for the Geodistance check are Pass, Fail, or Error. If the distance between the two coordinates is within the proximity threshold configured for the task, the result is Pass. If the distance is beyond the threshold or the coordinates are not provided, the result is Fail.

In this example, the Geodistance check failed.

{
  "id": "33bae6b8-5689-b96b-143c-06e93ab8527e",
  "event": "CHECK_COMPLETED",
  "secret": "yourSecret",
  "timestamp": 1570807808,
  "data": {
    "check": {
     "check_type": "GEODISTANCE",
      "id": "72aadb55-8b02-8495-d6b0-e1627ec23612",
      "result": "Fail",
      "variant": {
        "alias": "geodistance",
        "id": "ea565b55-47d9-1858-4588-3a22a3838707",
        "name": "Geodistance"
      }
    },
    "customer_ref": null,
    "profile_id": "a2c4393a-e219-67a4-5ab4-2186952e9038"
  }
}

Getting more information about the check result

To get more information about the result, make a call to the following endpoint.

In the request, include the profile ID and the check ID.

Request endpoint:

GET https://api.passfort.com/4.0/profiles/{profile_id}/checks/{check_id}

Sample response:

{
  "check_type": "GEODISTANCE",
  "completed_on": "2020-08-27 13:53:23",
  "coordinates": {
    "p1": {
      "latitude": 53.38297,
      "longitude": -1.4659,
      "name": "Stated IP"
    },
    "p2": {
      "latitude": 51.50853,
      "longitude": -0.12574,
      "name": "Current location"
    }
  },
  "decision": "FAIL",
  "errors": [ ],
  "id": "d526831a-e2f2-11ea-ab2b-1e271aa31109",
  "input_data": {
    "contact_details": { },
    "coordinates": {
      "p1": {
        "latitude": 53.38297,
        "longitude": -1.4659,
        "name": "Stated IP"
      },
      "p2": {
        "latitude": 51.50853,
        "longitude": -0.12574,
        "name": "Current location"
      }
    },
    "entity_type": "INDIVIDUAL",
    "personal_details": {
     "name": {
        "family_name": "Wheeler",
        "given_names": [
          "Alex"
        ]
      }
    }
  },
  "instructed_on": "2020-08-27 13:53:12",
  "output_data": {
    "entity_type": "INDIVIDUAL",
    "geodistance": {
      "distance": 227.605138,
      "is_within_threshold": false,
      "threshold": 100.0
    }
  },
  "performed_on": "2020-08-27 13:53:12",
  "providers": [
    {
      "instructed_on": "2020-08-27 13:53:12",
      "provider_name": "GeoDistance Passfort",
      "variant_name": "Passfort"
    }
  ],
  "result": "Fail",
  "started_on": "2020-08-27 13:53:12",
  "state": "COMPLETE",
  "task_ids": [
    "692e8682-e239-11ea-9218-5a65e6bcfda0"
  ],
  "variant": {
    "id": "4371c34c-e17d-11ea-8479-d6de177101d7",
    "name": "Geodistance"
  }
}

Use the response to:

  • Confirm whether the distance is within the threshold. If it is, output_data.geodistance.is_within_threshold is true.

  • See the threshold configured for the task (output_data.geodistance.threshold).

  • See the distance between the two points, in kilometres (output_data.geodistance.distance).

The result returns the distance in kilometres, but portal users will see the distance in miles. The distance is measured as a direct path between the two points. It does not account for any mountains, rivers, and so on.