Texts

Check a text with POST /v1/text, for comments, messages, names and bios.

POST /v1/text checks one text and answers with the decision. One text is one check, whatever the number of categories it is checked against.

Request

Send JSON, with the header Content-Type: application/json. Without it the API answers 415 unsupported_media.

FieldRequiredDescription
textYesThe text, at most 20,000 characters (5,000 on the free plan).
workflowNoThe workflow to check against. default when absent.
refNoYour own id for the text, 1 to 128 characters, no control character. It is echoed in the answer and kept in the journal.
contextNoWhere the text comes from, in plain words, at most 2,000 characters: for example "a buyer writes to a seller on a marketplace that forbids sharing phone numbers". Paid plans read it in their advanced AI workflows; the free plan ignores it. It is not kept in the journal.
curl -X POST "https://api.openshield.dev/v1/text" \
  -H "Authorization: Bearer $OPENMOD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Write me at jane@example.com", "workflow": "default", "ref": "comment_9034"}'

What is checked

The categories of the workflow. The default workflow:

  • Rejects unsafe text, violence, sexual content, hate, illegal activity and unethical content at a score of 0.8 (and sends them to review from 0.5), and bank account numbers, payment card numbers and unsafe links outright.
  • Sends to review self-harm from 0.5, and email addresses, phone numbers, requests to continue on another messaging app, spam, scams, extremism and links to adult or gambling sites outright.

Some rules look at the text itself, such as personal data and links. Their score is 1 when they match, which is why their thresholds are 1. Workflows explains how to change all of this.

Answer

The answer has the shape described here. For a text that holds an email address:

{
  "status": "success",
  "workflow": "default",
  "workflow_version": 1,
  "summary": {
    "action": "review",
    "reject_prob": 0,
    "reject_reason": [],
    "review_reason": [
      {
        "id": "pii_email",
        "text": "Email address",
        "message": "This content contains an email address.",
        "score": 1,
        "threshold": 1,
        "source": "rules"
      }
    ]
  },
  "scores": { "pii_email": 1 },
  "time_ms": 4,
  "request_id": "0192b7c5-1d20-7b3a-8f61-5c9e2a7d4b10",
  "ref": "comment_9034"
}

Advanced AI workflows

On Starter, Growth and Scale, a text that the first check sends to review gets a second, deeper reading by a more advanced AI model, with your context. It answers:

  • reject when the text clearly breaks the policy on the points flagged, or on another point (then under text_unsafe);
  • accept when the flag was a false alarm;
  • review as before when it is not sure.

A reason it gives has "source": "advanced". It costs nothing more per check. When it is not available, or slower than 1.5 seconds, the first check's decision stands. Images are not concerned. The model runs at a sub-processor listed on the sub-processors page.

Errors

Statuserror.typeWhen
400bad_requestThe body is not JSON, or has no text, or ref is refused, or context has more than 2,000 characters.
400unknown_workflowThere is no workflow of that name.
413text_too_longThe text has more than 20,000 characters (5,000 on the free plan).
413body_too_largeThe body is over the size limit.
415unsupported_mediaThe Content-Type is not application/json.
503workflow_unavailableThe workflow has no rule for texts, or none this server can check.

Authentication, rate limit and quota errors are in responses and errors.