API Inputs and Updates

Providing data to the API when users provide data

API responses include a list of questions and advice. This is found in the advice[] property. The advice[] list holds two types of items: INPUT_REQUEST and ADVICE.

Interface

When determining what to present on the interface, inspect the advice[] property's last index. If it's an INPUT_REQUEST, a question template should be shown to the user.

If it's ADVICE, no more questions need to be (nor can be) answered and the user is "done".

Asking the User Questions

In this example, the API needs to know the user's age as the very first input. The API response looks like this (other fields omitted for legibility):

"error": {
  "name": "EvaluatorError",
  "status": 200,
  "message": "Input Needed"
},
"advice": [{
  "id": "lV46Z0FmpVXYs2R5X0Uet",
  "type": "INPUT_REQUEST",
  "ruleSetId": "U3nYztaJ8yxgNGQkGsP7k",
  "ruleId": "Hv-3FBRdbj12Me0EddJ1R",
  "attachment": null,
  "answer": "0",
  "value": null,
  "question": "How old are you?",
  "form": {
    "name": "Age_Now",
    "type": "VARIABLE",
    "fieldType": "Number",
    "properties": {
      "range": {
        "max": 130,
        "min": 0
      },
      "format": "0"
    },
    "value": null
  }
}],

🚧

API Errors

In our preview environment, API errors include extra meta data at data.error.data. Do NOT reference this in your consumer code as it is not present in production.

Note in the example above the advice[] list has only 1 item, an INPUT_REQUEST. Since it is also the last item and does not have a value, a question should be shown.

Form Data

The INPUT_REQUEST will always have a form property containing all the relevant values.

  • form.name is the form's "name", i.e., the field we need to associate the user's input with.
  • form.fieldType is the form input type (an input box, a list of radio buttons, etc)
  • form.properties includes metadata about how to format the value, any applicable ranges (e.g., users shouldn't enter -1 for age) for validation, etc.
  • form.value, when it is null, indicates the user has not yet answered the question

In some cases, the form.name is a computed value instead of a named variable like Age_Now that looks like rule_nz_0OkS6C1ADviGqYrB4Q_selection. This is expected.

Saving a User's Input

When a user enters 25 in the input box with an Age_Now name, the following data should be sent to the API:

/api/advice/{id}?Age_Now=25

Note: It doesn't matter which method is used (GET or POST) but the examples show GET for legibility.

In this example, the updated API will return a new advice[] list. This time the first item (the Age_Now INPUT_REQUEST) will have a value in form.value (25) and the second item the advice[] list will either be another INPUT_REQUEST or ADVICE.

Submitting Values

When it comes to numerical values, the API understands raw values only. Do not submit formatted values, for example:

Do NOT do this:

/api/advice/{id}?Home_Price=$100,000

Instead, do this:

/api/advice/{id}?Home_Price=100000

If an invalid value is submitted to the API, an HTTP 400 Bad Request error will be returned. Using the example above, below is what an invalid value error would look like.

{
  "error": {
    "status": 400,
    "reason": "Non-numeric value input for Number type variable: Home_Price = $100,000",
    "name": "Error",
    "message": "Bad request",
  }
}

Percentages

Percentage values are considered special in that pre- and post-processing may have to be done, depending on the user interface. For example, consider asking a user for their preferred mortgage interest rate. The user enters 3.656% in the form.

Building on what we discussed above, the API cannot accept formatted values (e.g., Interest_Rate=3.656%). For percentages, the same is true. Submit the numerical equivalent by dividing by 100, if appropriate.

/api/advice/{id}?Interest_Rate=(3.656 / 100)

This simple math divides the user's input by 100, resulting in an API input value of 0.03656.

/api/advice/{id}?Interest_Rate=0.03656

It may be necessary to multiply the variable value by 100 when displaying it in the user interface.

Percent Format

Rely on the form.fieldType property (or perform a look-up on the variables property) to determine when pre- and post-processing may be necessary. (A list of all fieldType values is below.)

"form": {
  "name": "Interest_Rate",
  "type": "VARIABLE",
  "fieldType": "Percent",
  "properties": {
    "format": "0[.]00%"
  },
  "value": 0.03656
}

🚧

Tracking User Inputs

Since our API is stateless, each time a user answers a new question, the API needs to know all of the previous answers as well. For example, if the user is asked "How old are you?" and "Are you married?", when the API is called after the second marital status question is answered, the inputs should include both Age_Now=25&Married=true.

Answered vs Unanswered

Inspecting the advice[] list for INPUT_REQUEST items, any form.value with a null value indicates the user has not yet answered the question. If a value is present, it was either answered by the user or provided as an API input or both.

Form Templates

The form.fieldType property contains a list of possible form types. An ENUM of this field is:

  • Date
  • Radio
  • Select
  • Number
  • Percent
  • Boolean
  • Freetext (default)

Each of these field types correspond to an expected view template. On the web:

📘

Reference

Our open source demo app illustrates, using Handlebars templating, how the fieldType field is used to render the form.

Radio

To determine what radio buttons to render, reference form.values[] and the label and value properties within each item. If HTML is being requested (using Advice Content Types header), look for the label_html property.

Freetext

Using Freetext as the default is the right choice for a catch-all or during early development.

It should be very rare a free text form is used in production given the complexity around validating free-form user input.