Content Tagging

Classify a document against IPTC and IAB taxonomies.

The Tagging API classifies a document against standard content taxonomies. You send a title and body text. Miso returns the topics, entities, and keywords for that document. Below we tag one article end to end.

Common uses:

  • Add IPTC or IAB categories to an article.
  • Route content to the right section or feed.
  • Build topic pages and related-content links.

The API is stateless. You pass the text you want to tag. Miso does not read your content index, and it does not store the document.


Tag sets

A tag set is a named group of taxonomies. The URL path selects it: /v1/ask/tagging/{tag_set}.

Miso ships with one tag set, iptc_iab. It tags against two industry taxonomies:

  • IPTC Media Topics — a subject taxonomy for news and media.
  • IAB Content Taxonomy (v3.1) — a taxonomy for content and advertising.

The API key on a request controls access and usage only. It does not change the tag set or the result.


Authentication

Every request needs your API key. Pass it as ?api_key=YOUR_KEY or in the X-Api-Key header. Base URL: https://api.askmiso.com.


Tag a document

Tagging is a two-step flow. First you submit the document. Then you poll for the result.

1. Submit the document

POST /v1/ask/tagging/{tag_set}

Field Type Default Notes
title string required The document title.
content string required The document body, as plain text.
curl -X POST "https://api.askmiso.com/v1/ask/tagging/iptc_iab" \
  -H "X-Api-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Central bank signals two rate cuts in 2026",
    "content": "The central bank said it expects two cuts..."
  }'
const res = await fetch("https://api.askmiso.com/v1/ask/tagging/iptc_iab", {
  method: "POST",
  headers: {
    "X-Api-Key": KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "Central bank signals two rate cuts in 2026",
    content: "The central bank said it expects two cuts..."
  }),
});
const data = (await res.json()).data;
import requests

res = requests.post(
    "https://api.askmiso.com/v1/ask/tagging/iptc_iab",
    headers={"X-Api-Key": KEY},
    json={
      "title": "Central bank signals two rate cuts in 2026",
      "content": "The central bank said it expects two cuts..."
    },
)
data = res.json()["data"]

You get back a tagging_id to poll:

{
  "message": "success",
  "data": {
    "tagging_id": "0e1f2a3b-4c5d-6e7f-8a9b-0c1d2e3f4a5b"
  }
}

If the {tag_set} does not exist, Miso returns 404.

To get the result in one call, add ?wait_for_answer=true to the POST. The request then blocks until tagging is complete and returns the result directly.

2. Get the tags

GET /v1/ask/tagging/{tag_set}/{tagging_id}

Poll this endpoint until finished is true.

curl "https://api.askmiso.com/v1/ask/tagging/iptc_iab/$TAGGING_ID" \
  -H "X-Api-Key: $KEY"
const res = await fetch(
  "https://api.askmiso.com/v1/ask/tagging/iptc_iab/$TAGGING_ID",
  { headers: { "X-Api-Key": KEY } }
);
const data = (await res.json()).data;
import requests

res = requests.get(
    "https://api.askmiso.com/v1/ask/tagging/iptc_iab/$TAGGING_ID",
    headers={"X-Api-Key": KEY},
)
data = res.json()["data"]
{
  "message": "success",
  "data": {
    "tag_set": "iptc_iab",
    "stage": "Done",
    "finished": true,
    "finish_reason": "success",
    "tags": {
      "tag_set": "iptc_iab",
      "taxonomies": [
        {
          "taxonomy": "iptc",
          "themes": [
            {
              "code": "medtop:20000350",
              "label": "economy, business and finance",
              "confidence": 0.91,
              "model_agreement": "3/3"
            }
          ]
        },
        {
          "taxonomy": "iab",
          "themes": [
            {
              "code": "432",
              "label": "Personal Finance",
              "confidence": 0.78,
              "model_agreement": "2/3"
            }
          ]
        }
      ],
      "entities": [
        {
          "name": "Federal Reserve",
          "kind": "organization",
          "relevance": 0.9,
          "role": "primary",
          "model_agreement": "3/3"
        }
      ],
      "keywords": [
        {
          "keyword": "interest rates",
          "relevance": 0.85,
          "model_agreement": "3/3"
        }
      ]
    }
  }
}

Read the result

Tagging is asynchronous. finished says the job is over, and finish_reason says whether it worked. Do not branch on stage, which is a progress label: a successful tagging leaves it at "Done", and only a failure sets "Failed".

See Async results and polling for the value list, the grace window, the stall guard, the status codes, and a polling loop.

A poll returns 404 in three cases. The tagging_id does not exist, it belongs to a different app, or the {tag_set} does not match the one that created the id. Inside the first 10 seconds, a 404 means "not ready yet". After that, it means Miso lost the job, so submit the document again.

An empty result is a real "no tags". finish_reason: "success" with empty taxonomies, entities and keywords means the job worked and Miso found nothing above the threshold. With a failure value, empty tags mean the job failed instead.

One article takes 30 to 50 seconds. Poll every 2 to 3 seconds. Tagging returns nothing until it is done, so a shorter interval only costs you requests.


Result fields

The tags object holds three lists: taxonomies, entities, and keywords.

Themes (per taxonomy)

Each entry in taxonomies has a taxonomy name and a list of themes.

Field What it is
code The taxonomy code or id for the topic.
label The topic name in plain words.
confidence A score from 0 to 1. It is the mean confidence over the models that agreed.
model_agreement The vote, as <agreed>/<answered>. 2/3 means 2 of the 3 models that returned data agreed.

Entities

Field What it is
name The entity name.
kind person, organization, or location.
relevance A score from 0 to 1. It shows how central the entity is to the document.
role primary or secondary.
model_agreement Same meaning as above.

Keywords

Field What it is
keyword The keyword.
relevance A score from 0 to 1.
model_agreement Same meaning as above.

How the tags are chosen

Miso sends the document to several models. Each model tags it against the taxonomy on its own. Miso then merges the results with a cross-vote.

  • Miso keeps a topic when enough models agree on it.
  • confidence is the mean over the models that agreed.
  • model_agreement shows the vote, for example 3/3.

Miso validates every code against the taxonomy. If a code is a near-miss, Miso corrects it to the closest valid code. If a code has no match, Miso drops it.

Miso extracts entities and keywords once, then votes across the models. It normalizes entity names and drops social-platform handles. If a keyword repeats an entity, Miso removes the keyword.


Caching

Miso caches each result against the tag set, the title, and the content. A repeat request for an unchanged document returns the cached tags, so you can call the API again safely.

Re-tagging is automatic. Miso classifies the document again when you edit the title or the body, and when Miso updates the tag set.