Natural language API
Send a piece of text, get back structured facts about it: which topic categories it belongs to, how positive or negative it is, which people, companies, places and products it mentions, and whether it touches sensitive subjects. Use it to tag content at scale, route support messages, watch brand mentions or check pages before publishing.
The API uses the standard documents:<method> request format: one JSON body with a
document, one answer per call. If your code already sends requests in this format, it
works here after two edits: the base URL and the key.
The Natural language API works on every OmevAI API key, with no separate enablement, and is charged to the key's usual balance. For volumes or questions, contact support@omev.be.
Methods
| Method | Route | What you get |
|---|---|---|
| Classify text | POST /v2/documents:classifyText | up to 5 topic categories with confidence, from the current category list |
| Classify text (v1 route) | POST /v1/documents:classifyText | the same, for code written for the v1 route; send the option shown below |
| Sentiment | POST /v1/documents:analyzeSentiment | the overall tone of the text and of each sentence |
| Entities | POST /v1/documents:analyzeEntities | people, organisations, places, events, products and other entities with their mentions |
| Entity sentiment | POST /v1/documents:analyzeEntitySentiment | entities plus the tone towards each of them |
| Moderation | POST /v1/documents:moderateText | a confidence for each of 16 sensitive categories |
| Several at once | POST /v1/documents:annotateText | any combination of the above in one call |
Syntax analysis (analyzeSyntax) is not offered.
Price
| Method | Price | Counted per | Price per 1M characters |
|---|---|---|---|
classifyText (v1 and v2) | $0.001 | 1,000 characters | $1.00 |
analyzeSentiment | $0.0005 | 1,000 characters | $0.50 |
analyzeEntities | $0.0005 | 1,000 characters | $0.50 |
analyzeEntitySentiment | $0.001 | 1,000 characters | $1.00 |
moderateText | $0.00025 | 100 characters | $2.50 |
annotateText | the sum of the features you switch on | as above |
Characters are Unicode characters of document.content, rounded up to whole units: a
2,300-character text is three units for classification and 23 units for moderation.
For annotateText, extractEntitySentiment is charged as entity sentiment and replaces
the charge for extractEntities. A request that ends with an error is not charged.
Classify a text
curl -sS "https://llmapi.omev.be/v2/documents:classifyText" \
-H "Authorization: Bearer $OMEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document": {
"type": "PLAIN_TEXT",
"content": "Slow-cooked beef ragù: brown the meat, add tomatoes and red wine, then simmer for three hours and serve over fresh pappardelle."
}
}'
{
"categories": [
{"name": "/Food & Drink/Cooking & Recipes", "confidence": 0.93}
],
"languageCode": "en",
"languageSupported": true
}
categories holds up to 5 category paths, best first. On the v1 route, the answer holds
only categories, and the request must ask for the current category list:
"classificationModelOptions": {"v2Model": {"contentCategoriesVersion": "V2"}}. The earlier
(V1) category list is not offered; a v1 request without this option is not served and not
charged.
The document
Every method takes the same document object.
| Field | Required | Values |
|---|---|---|
document.type | yes | PLAIN_TEXT or HTML |
document.content | yes | the text itself, not empty, up to 1,000,000 bytes in UTF-8 |
document.languageCode | no | a language code such as en; detected automatically when omitted |
encodingType | no | NONE (default), UTF8, UTF16, UTF32: how beginOffset values are counted; not accepted by moderateText |
Only inline text is accepted; links to stored files are rejected with 400. Unknown
fields are rejected with 400.
Sentiment, entities, moderation and annotateText work in 26 languages: en, ru,
uk, de, fr, es, it, pt, nl, pl, cs, sk, sl, hr, sr, sv, da,
no, fi, hu, ro, bg, el, lt, lv, et. Text in another language answers 400.
Sentiment
curl -sS "https://llmapi.omev.be/v1/documents:analyzeSentiment" \
-H "Authorization: Bearer $OMEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document": {"type": "PLAIN_TEXT", "content": "The parcel arrived two days late. Support fixed it in minutes, though."},
"encodingType": "UTF8"
}'
{
"documentSentiment": {"magnitude": 1.4, "score": 0.1},
"sentences": [
{"text": {"content": "The parcel arrived two days late.", "beginOffset": 0},
"sentiment": {"magnitude": 0.6, "score": -0.6}},
{"text": {"content": "Support fixed it in minutes, though.", "beginOffset": 34},
"sentiment": {"magnitude": 0.8, "score": 0.8}}
],
"language": "en"
}
score runs from -1 (negative) to 1 (positive). magnitude (0 and up) is how much
emotion the text carries in total: a mixed text can have a score near 0 and a high
magnitude.
Entities and entity sentiment
analyzeEntities and analyzeEntitySentiment take the same body. Each item of
entities has:
| Field | Meaning |
|---|---|
name | the entity as written in the text |
type | PERSON, ORGANIZATION, LOCATION, EVENT, WORK_OF_ART, CONSUMER_GOOD, OTHER, plus DATE, NUMBER, PRICE, PHONE_NUMBER |
salience | 0–1, how central the entity is to the text; the list is sorted by it |
mentions | each place it appears: text (content, beginOffset) and type (PROPER, COMMON, or TYPE_UNKNOWN for dates, numbers, prices and phone numbers) |
metadata | extra structured data when available |
sentiment | score and magnitude towards this entity (analyzeEntitySentiment only) |
Moderation
moderateText takes only document. The answer lists every category with a
confidence from 0 to 1 that the text belongs to it (discusses, shows or expresses it,
whether positively or negatively):
{
"moderationCategories": [
{"name": "Toxic", "confidence": 0.04},
{"name": "Health", "confidence": 0.81}
]
}
Categories: Toxic, Insult, Profanity, Derogatory, Violent, Sexual,
Death, Harm & Tragedy, Firearms & Weapons, Public Safety, Health,
Religion & Belief, Illicit Drugs, War & Conflict, Finance, Politics, Legal.
Choose your own threshold per category.
Several analyses in one call
{
"document": {"type": "PLAIN_TEXT", "content": "…"},
"features": {
"extractEntities": true,
"extractDocumentSentiment": true,
"classifyText": true,
"moderateText": true
}
}
features accepts extractEntities, extractEntitySentiment,
extractDocumentSentiment, classifyText, moderateText and
classificationModelOptions. At least one must be true; extractSyntax answers 400.
With classifyText on, add "classificationModelOptions": {"v2Model": {"contentCategoriesVersion": "V2"}}
to features, as for the v1 classification route.
The answer holds language plus the fields of each switched-on analysis: entities,
documentSentiment, categories, moderationCategories.
Errors
| Code | When |
|---|---|
400 | missing or empty document, a wrong type, text over 1,000,000 bytes, an unsupported language, an unknown field or feature |
401 | missing or invalid API key |
403 | the key cannot use this product |
404 | an unknown method, including analyzeSyntax |
429 | too many requests, or the key's balance or budget cannot cover the call; retry after a short pause or top up |
500 | temporary problem; retry a limited number of times |
See Errors for the common format and retry advice.