API reference

Errors

The error envelope, every error code of the Check API, and what your app should do for each one.

Branch on the HTTP status and on code. Do not parse message. The Check API writes message in English, and the text of a message can change.

Error envelope

Every error response of the Check API has the same JSON shape. A response from the network in front of the Check API can have another body. See Answers outside the envelope.

400 response
{
  "data": null,
  "code": "validation_failed",
  "message": "Request is invalid.",
  "errorId": "FMS400",
  "traceId": "req_01M6JYA33G9NXKXXSG1B7Q1J4J",
  "errors": [
    {
      "code": "text_too_long",
      "field": "text",
      "inputTokens": 16001,
      "maxInputTokens": 16000,
      "message": "Text is 16,001 input tokens. The limit is 16,000 input tokens."
    }
  ]
}
FieldTypeDescription
datanullAlways null.
codestringThe error code, such as rate_limited.
messagestringA sentence for people to read.
errorIdstringA fixed ID for the error code, such as FMS429. Each code has one errorId.
traceIdstringThe ID of the request. It is equal to the X-Request-Id header.
errorsarrayPresent only when code is validation_failed. It has one item, which names the problem in the body.
errors[].fieldstringThe part of the request with the problem, text or body.
errors[].codestringThe field error code. See Field errors.
errors[].messagestringA sentence for people to read.
errors[].maxInputTokensintegerPresent only on text_too_long. The limit of input tokens for text.
errors[].inputTokensintegerPresent only on text_too_long, when the Check API counted the tokens of text.

Treat traceId and X-Request-Id as opaque strings. Most IDs start with req_, but a 400 or a 503 from the network in front of the Check API carries an ID in another form.

Error codes

Status and codeerrorIdWhenWhat your app should do
400 validation_failedFMS400The body breaks a rule. errors says which one.Fix the request. Do not send the same body again.
401 unauthorizedFMS401The key is missing, malformed, unknown, or deleted, or it belongs to another region.Use a key that exists, with the API URL of its region. Do not retry.
404 not_foundFMS404The path or the method does not exist in this API version.Send POST to https://api.jp.flowmask.ai/api/v1/check.
404 api_version_not_supportedFMC01The API version in the path does not exist.Use a version that exists. Today that is v1. See Versioning.
429 rate_limitedFMS429The workspace sent more requests in the current minute than its limit allows.Wait the number of seconds in Retry-After, then retry.
429 monthly_quota_exceededFMQ01The workspace used all of its input tokens for the month.Stop sending requests until X-Quota-Reset. To raise the quota, email the address in message.
500 internal_errorFMS500The Check API failed while it handled the request.Retry with backoff. See Retry 500 and 503.
503 service_unavailableFMS503A part of the Check API failed or did not answer in time. The response has no result for the text.Retry with backoff. See Retry 500 and 503.

The Check API handles a request in this order: the path, the key, the body, and the limits. Then it checks the text. A request with a bad key and a bad body gets 401. A 400 or a 401 uses none of the rate limit and none of the monthly quota.

Field errors

A 400 validation_failed response has one item in errors.

errors[].codeerrors[].fieldWhen
invalid_jsonbodyThe body is not a JSON object. This includes a body that is not UTF-8, an array, and broken JSON.
text_emptytexttext is missing, null, an empty string, or only white space.
text_must_be_stringtexttext is a number, a boolean, an object, or an array.
text_too_longtexttext has more than 16,000 input tokens, or the body has more than 4 MiB.

When the body has more than 4 MiB, the Check API stops reading it. The text_too_long item then has maxInputTokens but no inputTokens.

400 response, text_empty
{
  "data": null,
  "code": "validation_failed",
  "message": "Request is invalid.",
  "errorId": "FMS400",
  "traceId": "req_01M6JYA248KMF0WBCMB786A8XD",
  "errors": [
    {
      "code": "text_empty",
      "field": "text",
      "message": "Text is empty."
    }
  ]
}

Answers outside the envelope

Some responses that do not come from the Check API have a body that is not the error envelope.

  • The network in front of the Check API can answer 403 with a plain body that is not JSON. It does so, for example, when a client sends far too many requests or a request looks malicious.
  • The load balancer can answer 502, 503, or 504 with an HTML body when the Check API is not available.

These responses have no code, errorId, or traceId, and they can lack the headers in Response headers. Handle them in your app.

  • Read the body as JSON only when the Content-Type of the response is application/json.
  • Do not retry a 403 that is not JSON right away. Send fewer requests and check what you send. If the 403 keeps coming, contact support with the time of the requests.
  • Retry a 502, 503, or 504 with an HTML body with backoff, as in Retry 500 and 503.

Retry 500 and 503

A 500 or a 503 has no result for the text. Your app decides whether to block the text or to send it on without a check.

To retry, wait longer before each retry.

  1. Wait 1, 2, 4, 8, and then 16 seconds before the retries.
  2. Add a random part of up to 1 second to each wait, so that your servers do not retry at the same moment.
  3. Stop after 5 retries.

The samples also retry a 502 and a 504, which come from the load balancer. See Answers outside the envelope.

retry.py
import os
import random
import time

import requests

MAX_RETRIES = 5


def check(text):
    for attempt in range(MAX_RETRIES + 1):
        response = requests.post(
            "https://api.jp.flowmask.ai/api/v1/check",
            headers={"Authorization": f"Bearer {os.environ['FLOWMASK_API_KEY']}"},
            json={"text": text},
            timeout=30,
        )
        if response.status_code not in (500, 502, 503, 504) or attempt == MAX_RETRIES:
            return response
        time.sleep(2**attempt + random.random())

Keep these facts in mind when you retry.

  • A 503 can come after the Check API counted the request against the rate limit. Retries then use more requests of the minute.
  • Only a 200 uses input tokens. Every 200 counts the tokens of its text, even when the same text came in an earlier request.
  • Do not retry a 429 with this loop. Rate limits and quota explains how to handle each 429.

On this page