Guided Navigation API Calls

Purpose: Allow a LegalServer admin to, with custom coding, send information to an outside endpoint via API, and optionally update information on a LegalServer record.

Cost: This feature is included with LegalServer.  For now, there is no charge for unlimited API calls.

In General

Within Guided Navigation, you can add an element "Action: Perform an API Call". This functions similarly to the Generic Outgoing API Block (but is not exactly the same). When the element is loaded or submitted as part of a GN dialogue segment, it will automatically send an API call to the endpoint specified. 

Please note that there is no indication on the user side of the form that this block is present. You may wish to add an Instruction element to let users know that this API call will be made when the submit/continue button is clicked.

The big difference between the GN API Calls and the Generic outgoing API Block is that the Generic Outgoing API Block lets you set custom headers beyond those required for Authentication.

WARNING:  You must be sure you trust the outside service with your client's data. 


Use Case

With the ability to use jq filters, you could easily set up a chained set of API calls that return data back into the case. One API call to confirm the client, one to confirm an option and the next to populate data. If each is set on a separate segment, it becomes a streamlined method for interacting with another integration.

Basic Configuration

Explanations for these options:

  • Entering Logic: This controls whether this element of the GN Segment is utilized in the interview. It can always happen, or you can set certain expressions as a requirement for it to happen.
  • Run this action when segment is shown or submitted?: lets the user choose to run when the segment is displayed to the user or when the segment is submitted and the user clicks "Next".
  • URL: The service you are sending data to.
  • Method: either GET, POST, PATCH, PUT, or DELETE. This is specified by the outside service's documentation. 
  • Authentication: Rather than offer an HTTP Headers section in the Generic Outgoing API Block, this allows you to specify the exact authentication method directly. 
  • Perform request synchronously: For efficiency purposes, the API call is performed in the background by default. This allows you to move on to the next segment without waiting for a long API call to finish. If you want to wait for the next segment until the API call finishes and the response is processed, you will need to perform the request synchronously. This will process the response with JQ or case notes before moving on to the next segment. For example, if you want to chain API calls together (and pass variables for the second API call based on responses from the first), you will need to perform them synchronously. 
  • Parameters: defines what data you are sending. When you click "Add Parameter", you'll see three boxes. The first is the type of variable. The second is the parameter name. The third is the value to send. The type of variable can be either:
    • Literal Values: that you manually type in and are the same for every API Call. (Useful for API keys or static values).
    • Values from Field: Various matter values are available, including all custom matter fields. If you select a lookup, you will get an additional option of Send lookup value.
    • Data Structure: Allows you to create a hierarchy where you pass data within data -- { "note" : { "body": "This is the note body", "subject": "This is the note subject" } }
  • Path Parameter: is a checkbox to determine whether the parameter is available in the URL as a path parameter. In the url it should be show up as a bracketed version of the Param Name. For example. if the url is http://localhost:9999/anything/{case_id} then {case_id} will be replaced with the parameter named case_id that has the Path Parameter checked. 
  • Send Lookup Value: is a checkbox to determine whether to send the ID of the lookup (i.e., 234) or the value of lookup - "Spanish" - when constructing the outgoing API call. To use an analogy of Reports, if you check the box, you are essentially going to the subtable for the lookup to get the text values instead of the integer reference ID number that is stored. 
  • Store Response in a Note?: Save the response as a casenote. The entire case note will be stored in the format it was returned.  
    • Note Type: For the saved note
    • Note Subject: Can be set specifically for this API call.
    • JSON params to pluck from response: This is a comma separated list of top level parameters to save in the case note. 
  • Update Case from response:  (previously labeled "Set field based on response") This is a powerful option that allows you to set matter fields as a result of the API call. 
    • Set with jq filters: This allows you to use highly customizable jq filters in parsing the JSON response of the API call. See jq documentation for detailed examples. This can work to set text, date, and boolean fields within LegalServer. 
    • Set with legacy simple expression: This is now a deprecated feature that would allow you to capture the top level values in a JSON response.

Especially when troubleshooting API issues, it is worth having "Store Response in a Note" set to true. 


Example Parameters

Should produce a set of query parameters like:

                   { 
                                "ethnicity": "Hispanic",
                                "Test": "Test",
                                "Address": {
                                        "street": "123 Main Street"
                                        "city": "Houston",
                                        "state": "TX",
                                        "zip": "77002"
                                }
                        }
                

Modify Parameters for NYC Data Format

NYC Open Data API calls require addresses to be full spelled out. This will look at the street address parameters lines and expand any abbreviations to the full word. The list includes:

  • AVE becomes AVENUE
  • BLVD becomes BOULEVARD
  • CIR becomes CIRCLE
  • CT becomes COURT
  • DR becomes DRIVE
  • EXPY becomes EXPRESSWAY
  • FWY becomes FREEWAY
  • HWY becomes HIGHWAY
  • LN becomes LANE
  • PKWY becomes PARKWAY
  • PL becomes PLACE
  • RD becomes ROAD
  • SQ becomes SQUARE
  • ST becomes STREET
  • TER becomes TERRACE
  • TPKE becomes TURNPIKE

jq Filters

For example with the jq filters, with a JSON API response of

{   "_internal": {     "starttime": "2021-03-09T15:28:54.391312",     "steps": 1,     "steps_offset": 0,     "tracker": 1   },   "nav": {     "current": null,     "hidden": false,     "progressive": true }
                
  • Using a jq filter of ._internal.starttime and saving into a date field will let you see "03/09/2021".
  • Using a jq filter of ._internal.starttime and saving into a text field will let you see "2021-03-09T15:30:26.768303".
  • Using a jq filter of ._internal.starttime | length and saving into a number or text field will let you see "26" (as the length of the date when considered a string).
  • Using a jq filter of .nav.hidden and saving into a boolean field will let you see "No".

To explore jq filters further, please look at the jq documentation and to test jq filters look to jqplay.org. JQplay can also be run locally in a docker container. LegalServer uses jq version 1.5.

Updating Multiple Records

GN API calls can use jq to update multiple service/phase records on a case when there is multiple records to parse through in the API response. Think of the situation where you want to track all of the housing violations on the property and those all come back as a long API response. There is a limit on creating too many service records at one time using this API call. The standard limit is 250. If that is insufficient for your use case, please reach out to Support. 

See Third Party Integrations: New York City Housing API (video) for an example of this in use. 

Configuration

For this to work, there are a few steps that need to be set up. 

  1. In the Service Type lookup, identify the specific service type that you want to update via the API call. Be sure to select "Create in Guided Navigation API? as true for any of those records. 
  2. Create the Dynamic Service Processes and Profiles. You will want to tie a create process to the new profile that will show all the fields you are getting back from the API call. In addition, be sure to grab the create process ID number. If you edit the create process, look in the URL and grab the number that follows edit_process/edit/. If you use this number in the API call's response, you'll be able to control which process it goes towards. 
  3. Setup your Guided Navigation API call.  Be sure to check the box "Update Case from Response". There are three sections that then appear. For this feature, you'll need to use the second one "Create or Update service with jq filters. 
  4. If you want to create new service records each time you run the Guided Navigation API call, do not check the box for "Update existing service". If you want to update existing records based on a unique identifier in the source, you will need to identify it in the "Record Identifier query" as a jq filter. The filter should be for the specific unique identifer.

    For example, if  you are using the New York City Housing Data APIs to get details on housing violations, the data is returned in an array, you'd need to specify  .[].violationid. 
  5. You'll need to specify which Service Type to save these records to. Only the ones you have identified in the Service Type lookup for GN will show up.
  6. Then you've got the option to Add fields to the set. From the dropdown, you can pick the destination field. For the JQ filter, you'll want to provide a filter that will take you to the array, then a pipe, and then use the jq map() function on the specific key.
  7. Using the same example, if you wanted to map the violationid mentioned above into a field, you'd need to use a jq filter of . | map(.violationid). The first . returns the array. The pipe passes it to the function that maps the specific keys from each housing violation record. You can read more about the map() function in the jq documentation
  8. To disable creating Service records, you will need to delete the rows that map the variables. Unchecking the Update Case from response is not sufficient (see LS-91120).

Responses

If Store the response as a Case Note is also selected, the case note response will be pre-appended by a statement indicating either the success or failure of the JQ processing. This occurs whether you are plucking out specific JSON parameters or just storing the entire response. Success example:

4 service record(s) created and 0 records(s) updated (limit: 250)
                

Failure example:

jq error: Unable to create or update service record(s) (jq: error: contactdescription/0 is not defined at <top-level>, line 1:
. | map(contactdescription)
jq: 1 compile error)
                

Notes

A few notes about mapping variables: 

  1. You likely will want to map something to Title field as that is what gives you a clickable link in the listview and reports. 
  2. You will get errors if you try mapping something to the Database ID or Type fields. 
  3. If you want to map a literal value that is the same on each service, you can use a filter of . | map(166) or something similar. This would be useful for the creation process field. 
  4. You can concatenate literals values (numbers or text) and values received. For example if .[].number returns a number, you can add to it by saying . | map(73 + .number). If you want the text value of a number or if you want to concatenate it with text, you may have to convert it to string. 
  5. If you want to map to a lookup (both custom lookups and system lookups), you have to map the numeric ID value of the lookup option, not the text value of the lookup. You can get the numeric values from the lookup table by clicking on the value in the lookup table. The numeric id in the URL is the value to map. Then you'd need to use a filter like . |  map(if (.violationid) == "1234" then 1 elif (.violationid) == "4567" then 2 else 3 end). 

Always take a sample of the API response and test all your jq filters against it in jqplay.org

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us