# Items and Characteristics endpoints

The Items & Characteristics endpoints surface the items and characteristics detected in an image or video, including sound and speech. Each item or characteristic has a prevalence score which represents the extent to which it is present in a given piece of content. Unitary can also analyse the text that is shared alongside the image or video.

You can use these scores in mappings or models to implement safety policies, for example setting a numerical threshold for automated flagging of content or in a linear regression model (read more in the [guide for selecting thresholds](https://docs.unitary.ai/api-references/how-to-select-thresholds-for-items-and-characteristics)).

**Unitary output's over 50 different classes you can find on**[list-of-i-and-c-classes](https://docs.unitary.ai/api-references/items-and-characteristics/list-of-i-and-c-classes "mention")

{% hint style="info" %}
This guide assumes to have your API key already setup. If this is not the case, please email at <support@unitary.ai>
{% endhint %}

## 1. Authenticate

Please follow the [authentication](https://docs.unitary.ai/api-references/authentication "mention") instructions first in order to authenticate with the API. This will generate a token that is valid for 24 hours and must be used in subsequent API requests.

## 2. Sending your first request

Depending on your use case, pick an image or a video and then use one of the following `POST` endpoints to send your first request.

### POST endpoint reference

{% openapi src="<https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media>" path="/classify/items-characteristics/image" method="post" %}
[api-worker.autogenerated.openapi.yaml](https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="<https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media>" path="/classify/items-characteristics/video" method="post" %}
[api-worker.autogenerated.openapi.yaml](https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media)
{% endopenapi %}

### Example code

{% tabs %}
{% tab title="cURL" %}
Content supplied as a binary file upload:

{% code overflow="wrap" %}

```bash
curl --location --request POST "https://api.unitary.ai/v1/classify/items-characteristics/image" \
--header "Authorization: Bearer {API_TOKEN}" \
--header "Content-Type: multipart/form-data" \
--form "file=@{FILE};type=image/{FILE_EXTENSION}" \
--form "caption={CAPTION}"
```

{% endcode %}

Content supplied as a resource URL:

{% code overflow="wrap" %}

```bash
curl --location --request POST "https://api.unitary.ai/v1/classify/items-characteristics/image" \
--header "Authorization: Bearer {API_TOKEN}" \
--form "caption={CAPTION}" \
--form "url={RESOURCE_URL}"
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}

```python
import requests

api_token = "your_api_token_here"
file_path = "/path/to/your/file.jpg"
caption = "your_caption_here"
url = "https://api.unitary.ai/v1/classify/items-characteristics/image"

# For sending a file
files = {'file': (file_path, open(file_path, 'rb'), 'image/jpeg')}
data = {'caption': caption}
headers = {'Authorization': f'Bearer {api_token}'}

response = requests.post(url, files=files, data=data, headers=headers)
job_id = resonse.text["job_id"]

print(job_id)

# For sending a URL
data = {
    'caption': caption,
    'url': 'your_resource_url_here'
}
headers = {'Authorization': f'Bearer {api_token}'}

response = requests.post(url, data=data, headers=headers)
job_id = resonse.text["job_id"]

print(job_id)
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const fetch = require('node-fetch');
const FormData = require('form-data');
const fs = require('fs');

const apiToken = 'your_api_token_here';
const file_path = '/path/to/your/file.jpg';
const caption = 'your_caption_here';
const url = 'https://api.unitary.ai/v1/classify/items-characteristics/image';

// For sending a file
const formDataFile = new FormData();
formDataFile.append('file', fs.createReadStream(file_path), { type: 'image/jpeg' });
formDataFile.append('caption', caption);

fetch(url, {
  method: 'POST',
  body: formDataFile,
  headers: {
    'Authorization': `Bearer ${apiToken}`,
  },
})
.then(response => response.text())
.then(result => console.log(result["job_id"]))
.catch(error => console.log('error', error));

// For sending a URL
const dataUrl = new URLSearchParams();
dataUrl.append('caption', caption);
dataUrl.append('url', 'your_resource_url_here');

fetch(url, {
  method: 'POST',
  body: dataUrl,
  headers: {
    'Authorization': `Bearer ${apiToken}`,
    'Content-Type': 'application/x-www-form-urlencoded',
  },
})
.then(response => response.text())
.then(result => console.log(result["job_id"]))
.catch(error => console.log('error', error));
```

{% endtab %}
{% endtabs %}

## 3. Get results back via the GET endpoint

{% hint style="warning" %}
Using the GET endpoint may be inadequate for large scale! The recommendation is using the "`callback_url`" parameter instead. Please check the [integrating\_webhooks](https://docs.unitary.ai/api-references/integrating_webhooks "mention") guide for more information.
{% endhint %}

### GET endpoint reference

{% openapi src="<https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media>" path="/classify/items-characteristics/image/{job\_id}" method="get" %}
[api-worker.autogenerated.openapi.yaml](https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="<https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media>" path="/classify/items-characteristics/video/{job\_id}" method="get" %}
[api-worker.autogenerated.openapi.yaml](https://1303016406-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FgkYGyPKqtHGZyEvMl1GP%2Fuploads%2Fgit-blob-1ea297cbed161d2a16d21ca42ffa258cb07caefb%2Fapi-worker.autogenerated.openapi.yaml?alt=media)
{% endopenapi %}

### Example code

{% tabs %}
{% tab title="cURL" %}
{% code overflow="wrap" %}

```bash
curl --location --request GET "https://api.unitary.ai/v1/classify/items-characteristics/image/{JOB_ID}" \
--header "Authorization: Bearer {BEARER_TOKEN}"
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}

```python
import requests

BEARER_TOKEN = "{BEARER_TOKEN}"
JOB_ID = "{JOB_ID}"
url = f"https://api.unitary.ai/v1/classify/items-characteristics/image/{JOB_ID}"

payload={}
headers = {
  'Authorization': f'Bearer {BEARER_TOKEN}'
}

response = requests.request("GET", url, headers=headers, data=payload)

results = response["results"]
violence = results["violence"]
has_firearms = violence["firearm"] > 0.8

print(has_firearms)

```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const fetch = require("node-fetch"); 
const BEARER_TOKEN = "{BEARER_TOKEN}";
const JOB_ID = "{JOB_ID}";
const url = `https://api.unitary.ai/v1/classify/items-characteristics/image/${JOB_ID}`;

fetch(url, {
  method: "GET",
  headers: {
    'Authorization': `Bearer ${BEARER_TOKEN}`,
  },
})
.then(response => response.json())
.then(data => {
  const results = data["results"];
  const violence = results["violence"];
  const has_firearms = violence["firearm"] > 0.8;
  console.log(has_firearms);
})
.catch((error) => {
  console.error('Error:', error);
});
```

{% endtab %}
{% endtabs %}

Depending on the processing status of the job at the time of request, you can get any of the following as the response from the GET endpoints:

{% tabs %}
{% tab title="Status: successful" %}

```json
{
  "status": "done",
  "results": {
    "violence": {
      "violence": 0.006823897361755371,
      "firearm": 0.06859919428825378,
      "knife": 0.03536936640739441,
      "violent_knife": 0.03841346502304077
    },
    "substances": {
      "alcohol": 0.09190595149993896,
      "drink": 0.11272519826889038,
      "smoking_and_tobacco": 0.1175956130027771,
      "marijuana": 0.10564917325973511,
      "pills": 0.1289033591747284,
      "recreational_pills": 0.12389451265335083
    },
    "nsfw": {
      "adult_content": 0.7132323980331421,
      "suggestive": 0.9982926249504089,
      "adult_toys": 2.8699636459350586e-05,
      "medical": 0.9637787342071533,
      "over_18": 0.8957071900367737,
      "exposed_anus": 0.0003555417060852051,
      "exposed_armpits": 0.1219978928565979,
      "exposed_belly": 0.2361663281917572,
      "covered_belly": 0.004645615816116333,
      "covered_buttocks": 0.007969379425048828,
      "exposed_buttocks": 0.040920644998550415,
      "covered_feet": 0.004700213670730591,
      "exposed_feet": 0.0017207860946655273,
      "covered_breast_f": 0.5827286839485168,
      "exposed_breast_f": 0.5190947651863098,
      "covered_genitalia_f": 0.11009037494659424,
      "exposed_genitalia_f": 0.003075540065765381,
      "exposed_breast_m": 0.0006746351718902588,
      "exposed_genitalia_m": 0.005911082029342651
    },
    "hate_symbols": {
      "confederate_flag": 0.10465598106384277,
      "pepe_frog": 0.009708642959594727,
      "nazi_swastika": 0.07055380940437317
    },
    "caption_language_toxicity": {
      "toxicity": 0.0003523826599121094,
      "severe_toxicity": 4.458427429199219e-05,
      "obscene": 0.00036585330963134766,
      "insult": 0.0004227757453918457,
      "identity_attack": 0.00011718273162841797,
      "threat": 5.6624412536621094e-05,
      "sexual_explicit": 4.363059997558594e-05
    },
    "visual_content": {
      "artistic": 0.00594728346914053,
      "comic": 0.0004559260851237923,
      "meme": 0.00048818273353390396,
      "screenshot": 0.009867854416370392,
      "map": 2.6955993234878406e-05,
      "poster_cover": 4.053880275023403e-06,
      "game_screenshot": 4.549684308585711e-05,
      "face_filter": 0.008053907193243504,
      "promo_info_graphic": 6.63170067127794e-06,
      "photo": 0.9751037955284119
    },
    "other": {
      "child": 0.05087965726852417,
      "middle_finger_gesture": 0.0770421028137207,
      "toy": 0.09503969550132751,
      "gambling_machine": 0.09784704446792603,
      "face_f": 0.501373291015625,
      "face_m": 0.0010322332382202148
    },
    "url": "{RESOURCE_URL}"
  },
  "msg": null
}
```

{% endtab %}

{% tab title="Status: queued" %}

```json
{
  "status": "queued"
}
```

{% endtab %}

{% tab title="Status: error" %}

```json
{
  "status": "failed",
  "msg": "the error message for the request"
}
```

{% endtab %}
{% endtabs %}

## 4. Thresholding

Please follow our thresholding guide: [how-to-select-thresholds-for-items-and-characteristics](https://docs.unitary.ai/api-references/how-to-select-thresholds-for-items-and-characteristics "mention")

## 5. Webhooks

**(optional but encouraged)**&#x20;

In order to have a scalable end-to-end integration, the last step is to set up the receiving of webhooks as described in the following guide: [integrating\_webhooks](https://docs.unitary.ai/api-references/integrating_webhooks "mention")
