Feedback
Providing feedback helps our models improve over time. When you send feedback, the system learns from your preferences and corrections, refining both accuracy and alignment with your preferences.
This section explains how to send feedback on:
Providing feedback for sentiment analysis works the same way—see AnalyzeFeedback API reference.
Feedback on Tags
Opt-in, Opt-out, and Mixed Modes
How you provide feedback depends on how tag suggestions are handled by journalists or editors. Geneea supports three typical workflows:
- Opt-in:
Journalists actively select the tags they want from the suggestions made by the API. Any tag not selected is ignored. - Opt-out:
All suggested tags are used by default unless explicitly removed. - Mixed:
Tags are split into two groups based on their relevance score:- The most relevant tags are in opt-out mode (journalists only reject incorrect ones).
- Less certain tags are in opt-in mode (journalists pick the ones they want).
Feedback Types
In opt-in mode:
(no tag is used unless explicitly approved)
accepted-actively: The tag was explicitly selected as correct and relevant.rejected-passively: The tag was not selected (either incorrect or irrelevant).rejected-actively: Stronger version ofrejected-passively—the tag was explicitly marked as wrong.expected: A tag that was not suggested but should have been.
In the opt-out mode:
(all tags are used unless removed)
rejected-actively: the tag was explicitly marked as wrong (it is either incorrect or not relevant).accepted-passively: the tag was not removed from the suggestions,expected: the tag was not part of the suggestions but should have been.
To improve accuracy, rejected-actively can be refined into:
rejected-actively-wrong: The tag is wrong because the article does not mention the concept (e.g., confusion with a similar name).rejected-actively-marginal: The tag is technically correct but not relevant enough (mentioned only once in passing).blocked: The tag should never be returned (e.g., too specific; a broader tag is preferred).
Providing these more specific values instead of just rejected-actively helps the system
improve faster.
Technical Details
Feedback on tags consists of:
- Tag identifier – either the GKB ID or the standard form (or both).
- Status – indicating whether the tag was correct, incorrect, or missing.
Including the GKB ID is strongly recommended, as it allows automated feedback processing. Tags without GKB IDs are reviewed manually by our data team.
Common status values include:
accepted-actively:
The tag was explicitly accepted as correct and relevant.accepted-passively:
The tag was accepted, but not explicitly — typically meaning it was not rejected in an opt-out setup.rejected-actively:
The tag was explicitly rejected.
You can optionally use a more specific variant:rejected-actively-wrong:
The tag was explicitly rejected because the article does not mention the concept at all (e.g., a different person or place with the same name).
This is more specific thanrejected-actively.rejected-actively-marginal:
The tag was explicitly rejected because, although technically correct, is not relevant enough to be selected
(for example, mentioned only once in passing).
This is more specific thanrejected-actively.blocked:
The tag should never be returned, for instance, because it is too specific and a broader tag should be used instead.
rejected-passively:
The tag was rejected, but not explicitly — usually meaning it was not accepted in the opt-in mode.expected:
The tag should have been returned but wasn't.
Legacy values
The following older values are still supported, though we recommend using the updated ones above:
correct→ useaccepted-activelyaccepted→ useaccepted-passivelywrong→ userejected-activelyrejected→ userejected-passively
Obligatory, Recommended, and Optional Information
When sending feedback, include the following:
- Obligatory:
- The ID of the document that was analyzed (e.g.,
article-123).
- The ID of the document that was analyzed (e.g.,
- Recommended:
ThereferenceKeyidentifying the specific analysis run (e.g.,211201-103000-d64a0290).
This helps to avoid ambiguity, especially if the article has been analyzed more than once. - Per tag:
- Provide either the GKB ID, the standard form, or both.
- If a tag is expected but was not suggested, and the GKB ID is unknown, you may provide only the standard form.
- Completeness of feedback:
- Ideally, include feedback for all returned tags. If a tag is missing from the feedback:
- In opt-in mode: it will be treated as
rejected-passively. - In opt-out mode: it will be treated as
accepted-passively. - In the mixed mode: missing tags make the feedback inconsistent and are treated as an error.
- In opt-in mode: it will be treated as
- Ideally, include feedback for all returned tags. If a tag is missing from the feedback:
- Duplicate submissions:
- If multiple feedback calls are submitted for the same analysis (or
document, if
referenceKeyis not provided), only the most recent one will be used.
- If multiple feedback calls are submitted for the same analysis (or
document, if
Example
Basic code common to all guide pages
Basic Code
To use the API, you'll need a valid API key with the appropriate permissions. If you don't have one, please contact us here.
In the code below, replace <YOUR_API_KEY> with your actual API key.
Note: We do not currently provide dedicated SDKs for this API, but our G3 SDKs can be used to perform NLP analysis.
- cURL
- cURL (Windows)
- JavaScript
- Python
- Python SDK
# No special setup necessary
# No special setup necessary
// HTTP client; see https://github.com/axios/axios
const axios = require('axios');
const config = {
baseURL: 'https://media-api.geneea.com/v2/',
headers: {
'X-API-KEY': '<YOUR_API_KEY>'
}
};
// A simple function to report the returned json objects
const report = (output) => console.dir(output, { depth: null });
// In production environment, the API should always be called from the backend,
// otherwise you run into CORS problems
# http client; see https://docs.python-requests.org/en/latest/
import requests
BASE_URL = 'https://media-api.geneea.com/v2/'
HEADERS = {
'content-type': 'application/json',
'X-API-Key': '<YOUR_API_KEY>'
}
# We do not provide a dedicated SDK for the Media API yet.
# However, the SDK for General API can be used for the content analysis (i.e. NLP) part of the Media API.
# Geneea NLP client SDK; see https://help.geneea.com/sdk/index.html
# Use `pip install geneea-nlp-client`
from geneeanlpclient import g3
BASE_URL = 'https://media-api.geneea.com/v2/'
API_KEY = '<YOUR_API_KEY>'
As an example, consider the following article (source: Reuters). Let's say we use the API to analyze it and obtain tags:
- cURL
- Python
- Python SDK
POST https://media-api.geneea.com/v2/nlp/analyze
{
"id": "article-123",
"title": "Tesla to accept Dogecoin as payment for merchandise, says Musk",
"text": "Dec 14 (Reuters) - Tesla Inc (TSLA.O) chief Elon Musk said on Tuesday the electric carmaker will accept Dogecoin as payment for merchandise on a test basis, sending the meme-based cryptocurrency up 24%.",
"language": "en"
}
def analyze(input):
return requests.post(f'{BASE_URL}nlp/analyze', json=input, headers=HEADERS).json()
input = {
'id': 'article-123',
'title': 'Tesla to accept Dogecoin as payment for merchandise, says Musk',
'text': 'Dec 14 (Reuters) - Tesla Inc (TSLA.O) chief Elon Musk said on Tuesday the electric carmaker will accept Dogecoin as payment for merchandise on a test basis, sending the meme-based cryptocurrency up 24%.',
'language': 'en'
}
analyze(input)
requestBuilder = g3.Request.Builder()
with g3.Client.create(url=f'{BASE_URL}nlp/analyze') as analyzer:
analyzer.session.headers.update({'X-API-Key': API_KEY})
request = requestBuilder.build(
id=str('article-1234'),
title='Tesla to accept Dogecoin as payment for merchandise, says Musk.',
text='Dec 14 (Reuters) - Tesla Inc (TSLA.O) chief Elon Musk said on Tuesday the electric carmaker will accept Dogecoin as payment for merchandise on a test basis, sending the meme-based cryptocurrency up 24%.'
)
result = analyzer.analyze(request)
print('Tags:')
for t in result.tags:
print(f' \t{t.type}: {t.stdForm} ({t.gkbId}) relevance: {t.relevance}')
The API returns the following (depending on your configuration, other analyses may also be included):
{
"id": "article-123",
"language": { "detected": "en" },
"tags": [
{
"id": "t0",
"gkbId": "G478214",
"stdForm": "Tesla, Inc.",
"type": "media",
"relevance": 24.33
},
{
"id": "t1",
"gkbId": "G317521",
"stdForm": "Elon Musk",
"type": "media",
"relevance": 22.5
},
{
"id": "t2",
"gkbId": "G15377916",
"stdForm": "Dogecoin",
"type": "media",
"relevance": 19.24
},
{
"id": "t3",
"gkbId": "G130879",
"stdForm": "Reuters",
"type": "media",
"relevance": 9.275
}
],
"metadata": { "referenceKey": "211201-103000-d64a0290" }
}
Let's assume the journalist is using the opt-in setup, i.e., they manually select relevant tags.
They decide to:
- Actively select
TeslaandElon Musk. - Explicitly reject
Reutersas not relevant.
(They could have ignored it, which would mark it asrejected-passively, but they chose to be more precise — a good practice.) - Notice that the tag
cryptocurrency(GKB IDG13479982) is missing, and they expect it to be included.
To send this feedback, they use the following API call:
- cURL
- Python
POST https://media-api.geneea.com/v2/nlp/analyze/feedback
{
"docId": "article-123",
"referenceKey": "211201-103000-d64a0290",
"tags": [
{ "gkbId": "G478214", "stdForm": "Tesla, Inc.", "status": "accepted-actively"},
{ "gkbId": "G317521", "stdForm": "Elon Musk", "status": "accepted-actively"},
{ "gkbId": "G130879", "stdForm": "Reuters", "status": "rejected-actively-marginal", "comment": "Reuters not wanted" },
{ "gkbId": "G13479982", "stdForm": "cryptocurrency", "status": "expected", "comment": "cryptocurrency is missing"}
]
}
def feedback(input):
return requests.post(f'{BASE_URL}nlp/analyze/feedback', json=input, headers=HEADERS).json()
input = {
'docId': 'article-123',
'referenceKey': '211201-103000-d64a0290',
'tags': [
{ 'gkbId': 'G478214', 'stdForm': 'Tesla, Inc.', 'status': 'accepted-actively'},
{ 'gkbId': 'G317521', 'stdForm': 'Elon Musk', 'status': 'accepted-actively'},
{ 'gkbId': 'G130879', 'stdForm': 'Reuters', 'status': 'rejected-actively-marginal', 'comment': 'Reuters not wanted' },
{ 'gkbId': 'G13479982', 'stdForm': 'cryptocurrency', 'status': 'expected', 'comment': 'cryptocurrency is missing'}
]
}
feedback(input)
Feedback on Entities
Providing feedback for entities works the same way:
- cURL
- Python
POST https://media-api.geneea.com/v2/nlp/analyze/feedback
{
"docId": "article-123",
"referenceKey": "211201-103000-d64a0290",
"entities": [
{ "gkbId": "G130879", "status": "accepted-actively", "comment": "Reuters is ok as an entity" },
{ "stdForm": "cryptocurrency", "status": "expected", "comment": "cryptocurrency is missing"},
{ "gkbId": "G478214", "stdForm": "Tesla, Inc.", "status": "accepted-actively"},
{ "gkbId": "G317521", "stdForm": "John Smith", "status": "accepted-actively"}
]
}
def feedback(input):
return requests.post(f'{BASE_URL}nlp/analyze/feedback', json=input, headers=HEADERS).json()
input = {
'docId': 'article-123',
'referenceKey': '211201-103000-d64a0290',
'entities': [
{ 'gkbId': 'G130879', 'status': 'accepted-actively', 'comment': 'Reuters is ok as an entity' },
{ 'stdForm': 'cryptocurrency', 'status': 'expected', 'comment': 'cryptocurrency is missing'},
{ 'gkbId': 'G478214', 'stdForm': 'Tesla, Inc.', 'status': 'accepted-actively'},
{ 'gkbId': 'G317521', 'stdForm': 'John Smith', 'status': 'accepted-actively'}
]
}
feedback(input)