Release 1.0.1

A guide to scienceio 1.0.1.

Overview of Changes

ScienceIO has released a new asynchronous endpoint for its API, which is replacing our original synchronous endpoint. The async method allows the API to more easily work with larger amounts of data and will also improve the API's ability to accommodate different trigger methods.

Key changes include:

  • Moving from a single request to multiple requests
  • The addition of a request_id, which is necessary to retrieve results
  • The use of inference_status in the response
  • Allowing up to 10,000 characters in a single request (the size of an HL7 message)
  • A time limit of 15 minutes to hold results before they expire
  • A change in our model name from "annotate" to "structure"
  • The addition of "v2" to the endpoint

The new API workflow is a POST to structure and a GET to structure that includes the request_id. For SDK users, this process will happen automatically.

#Because the endpoint is async, use GET with the request_id to retrieve.

Required Updates


No changes to the API keys are required to utilize this update.

SDK Customers

An update to the latest version is all that is required. This may be achieved using the pip command. You may still make the call as you normally would, and the API will automatically use the request _id and poll in a loop until a response is received.

pip install scienceio --upgrade

Direct API Customers

A change to your code is required to accommodate the new response workflow. In addition to your normal POST, you will be required to pull out the request_id from the POST response body and use it in a GET request as described earlier on this page (make sure the endpoint reflects the change in model name from "annotate" to "structure" as well as the addition of "v2").

You will also need to create a loop in order to check for and get your results. ScienceIO recommends using an exponential backoff starting at 1 second to increase the time in between tries, that the maximum number of tries be set to 8, and that the polling logic be set to give an exception if results are not received within a certain amount of time.

import time

import requests


def exponential_backoff(request_id: str, api_key_id: str, api_key_secret: str) -> dict:
    url = f"{request_id}"
    headers = {
        "Content-Type": "application/json",
        "x-api-id": api_key_id,
        "x-api-secret": api_key_secret,

    current_timeout = INITIAL_TIMEOUT_SECS

    for _ in range(MAX_ATTEMPTS):
        response = requests.get(url, headers=headers)


        response_json = response.json()

        inference_result = response_json.get("inference_result", None)

        if inference_result is not None:
            return inference_result

        # At this point, the request is still processing, so sleep and try again.
        current_timeout *= 2

    # Here, we've exhausted all of our retry attempts, so fail.
    raise Exception("Number of attempts exhausted, try again later")

Status Messages

All responses will include an inference_status. Because the API is now making more than one request for results, the typical progression would be to see an initial response with a Submitted status followed by a full response with a Completed status.

Sample Initial Response Body in JSON

Here is an expected response to indicate the request was sent successfully and is in progress. Notice that it includes a request_id and inference_status.

    Content-Type: "application/json"
  "request_id": "6f251316-805d-45c6-8a32-ba9f3d8aba35",
  "text": "Cancer is a disease.",
  "inference_status": "SUBMITTED",
  "message": "Submitted a new inference request.",
  "model_type": "structure"

Statuses and Recommendations

SubmittedYour request was submitted and the API is currently processing it.Wait a bit longer for the API to process your request. The process is working as expected unless Submitted changes to Errored.
CompletedYour results have been returned and the process is complete.None (the process worked as expected and is complete).
ErroredSomething failed in the request, so the Submitted status changed into an Errored status.Check your code and input text before retrying. If this status continues to display despite troubleshooting, contact the support team for help.

Note that this error status is a ScienceIO error and applies to your NLP inference request; it is different from HTTP request errors. However, you may also see the HTTP 500 error code when this status displays.
ExpiredYour results have expired.ScienceIO does not hold on to data for longer than 15 minutes after the results are returned. Submit the request again to get your results.