Brands
Brands and logos found on screen, in speech and in the caption, with screen time, timestamps and confidence.
Brand detection finds brands on screen, in speech, and in the video's title, description and tags. Each brand comes back with a confidence and its appearances. Video length, fps and frames per job are capped per plan: see Limits.
curl -X POST https://api.netraflow.com/v1/jobs \
-H "Content-Type: application/json" \
-H "X-Api-Key: sk_live_your_key_here" \
-d '{
"url": "https://www.youtube.com/watch?v=jNQXAC9IVRw",
"capabilities": ["brands"],
"brands": ["Nike", "Adidas"],
"surfaces": ["jersey"]
}'{
"data": {
"job_id": "job_abcdefghij123456",
"status": "completed",
"results": {
"brands": [
{
"name": "nike",
"raw_name": "Nike",
"confidence": 0.95,
"total_appearances": 3,
"total_visible_duration": 8.4,
"mark_seconds": 14.2,
"peak_marks": 3,
"first_seen": 12.5,
"last_seen": 89.6,
"surfaces": ["jersey"],
"appearances": [
{
"timestamp": 12.5,
"timestamp_start": 12.5,
"timestamp_end": 20.9,
"visible_duration": 8.4,
"confidence": 0.95,
"verified": true,
"source": "visual",
"surface": "jersey",
"bounding_box": { "x": 0.3, "y": 0.2, "width": 0.15, "height": 0.1 },
"frame_detections": [
{
"timestamp": 12.5,
"bounding_box": { "x": 0.3, "y": 0.2, "width": 0.15, "height": 0.1 },
"mask": { "size": [144, 256], "counts": [20412, 31, 225, 36, 16160] }
},
{
"timestamp": 14.5,
"bounding_box": { "x": 0.33, "y": 0.21, "width": 0.14, "height": 0.1 },
"mask": { "size": [144, 256], "counts": [20671, 30, 226, 35, 15902] }
}
]
},
{
"timestamp": 89.0,
"timestamp_start": 89.0,
"timestamp_end": 89.6,
"confidence": 0.82,
"source": "audio",
"context": "Mentioned in speech",
"speech_context": "We partnered with Nike for this campaign."
},
{
"source": "metadata",
"confidence": 0.5,
"context": "Mentioned in video metadata"
}
]
}
],
"confidence_summary": { "high": 1, "medium": 0, "low": 0, "total": 1 }
}
}
}Targeting
Both fields are optional. Without them, a job finds every brand it sees.
| Prop | Type | Description |
|---|---|---|
| brands | string[] | Brand names to report. Up to 50, 100 characters each. Accents are optional: "Hermes" finds Hermès. |
| surfaces | string[] | Where the brand should appear, such as "jersey". Up to 10. An unknown slug is VALIDATION_FAILED; one not available yet is INVALID_SURFACE, which lists the ones you can use. |
surfacesnarrows where brands are looked for, so the job is usually faster, cheaper and more precise. Each appearance carries itssurface, and each brand asurfaceslist.brandsnarrows what is reported, not what is looked at, so it doesn't make a job cheaper. A name you pass is looked for even if it is little known.
Surfaces you can target
Each row starts with its broadest surface.
| Group | Slugs |
|---|---|
| Clothing | apparel, clothing, jersey, t-shirt, hoodie, jacket, pants, gloves |
| Footwear | footwear, sneakers, boots, sandals |
| Headwear | headwear, cap, beanie, helmet |
| Bags | bags, backpack, handbag, suitcase, tote-bag |
| Eyewear and watches | eyewear, sunglasses, watches-jewelry, watch |
| Drinks | beverages, beverage-can, bottle, carton, cup |
| Packaging | food-packaging, snack-packaging, box-packaging, jar-tub, supplements, takeout |
| Beauty | beauty, cosmetics, skincare, perfume, spray |
| Electronics | electronics, smartphone, laptop, tv-monitor, headphones, camera, microphone, game-console |
Brand fields
| Prop | Type | Description |
|---|---|---|
| name | string | Lowercase brand identity ("nike"), stable across runs and sources. Key on it; don't display it. |
| raw_name | string | The name to display ("Nike", "AT&T"). Older results may omit it: fall back to name. |
| confidence | number (0-1) | Higher is surer. |
| low_confidence | boolean (optional) | True when a brand seen on screen scored low. Treat it as a candidate to check. |
| total_appearances | integer | On-screen stretches plus speech and metadata mentions. Not a count of frames or marks. |
| total_visible_duration | number | Seconds the brand was on screen at all. Never longer than the video. 0 if never on screen. |
| mark_seconds | number (optional) | Seconds of exposure with each mark counted on its own: two boards for one second are 2. Can exceed the video length. |
| peak_marks | integer (optional) | The most marks of this brand on screen in one frame. |
| first_seen | number | null | Seconds. First timed appearance. null when only found in metadata. |
| last_seen | number | null | Seconds. Last timed appearance. null when only found in metadata. |
| surfaces | string[] (optional) | The surfaces its appearances were on. Surface-targeted jobs only. |
| appearances | Appearance[] | Each appearance. See below. |
total_visible_duration says how long a brand was showing; mark_seconds and peak_marks say how much of
it. Nineteen boards for five seconds and one board for five seconds both have a total_visible_duration of 5, but
mark_seconds of 95 and 5, and peak_marks of 19 and 1. A brand never on screen has 0 for all three.
mark_seconds and peak_marks are absent on older results.
Appearance fields
Branch on source first. A metadata appearance is timeless: no timestamp, duration or box.
A visual appearance is one stretch of time the brand was on screen, however many of its marks were up. Stretches less than about a second apart are joined. On a surface-targeted job, stretches are per surface.
| Prop | Type | Description |
|---|---|---|
| source | "visual" | "audio" | "metadata" | On screen, in speech, or in the title, description or tags. |
| timestamp | number (optional) | Seconds. Start of the appearance. |
| timestamp_start | number (optional) | Seconds. Start of the stretch. |
| timestamp_end | number (optional) | Seconds. End of the stretch. |
| visible_duration | number (optional) | Length of the stretch. Don't add these up for screen time: use total_visible_duration. |
| confidence | number (0-1, optional) | Visual: the brand's confidence, repeated. Speech and metadata carry their own. |
| verified | boolean (optional) | Set on visual appearances whose brand was identified. |
| bounding_box | { x, y, width, height } (optional) | The largest box in the stretch, as 0-1 fractions of the frame. |
| frame_detections | FrameDetection[] (optional) | The frames where a mark was boxed, in time order. Several can share a timestamp. Visual only. |
| surface | string (optional) | The surface it was found on. Surface-targeted jobs only. |
| context | string (optional) | A fixed label on audio and metadata appearances, such as "Mentioned in speech". |
| speech_context | string (optional) | The transcript around a spoken mention. Needs return_proof. |
Frame detection fields
| Prop | Type | Description |
|---|---|---|
| timestamp | number | Seconds. The frame. |
| bounding_box | { x, y, width, height } | The mark on that frame, as 0-1 fractions. |
| mask | { size, counts } (optional) | Run-length outline of the surface the brand is on. Surface-targeted jobs only. |
Older results may also carry confidence and confidence_kind on each detection. Ignore them: use the brand's
confidence.
Visual evidence
With return_proof on (the default), a brands job adds a storyboard: up to 150 frames spread across the video,
tiled into sheets. Tiles are plain frames. To show a brand, find the tile nearest a frame_detections timestamp and
draw its bounding_box over it. See Frames. return_proof: false also drops
speech_context.
Result signals
| Prop | Type | Description |
|---|---|---|
| confidence_summary | { high, medium, low, total } | Brands per band: high ≥ 0.8, low < 0.5, medium in between. |
| meta.brand_detection_degraded | boolean (optional) | Detection returned only part of its work. Check it before reading an empty list as "no brands". |
When brand detection can't run at all, see When one capability cannot run.
Frame rate and cost
Brand detection looks at 1 frame per second unless you pass fps. A higher rate catches marks that flash past and
costs more. A lower rate mainly risks missing a brief mark. On a long video, fps is lowered to fit your plan's frames
per job.
How brands are named
Everyday-word brands such as United, Square, Delta, Target, Apple and Meta are named only when the whole text is that word: a jersey reading "MANCHESTER UNITED" is not United. A longer name, such as Square Enix, is kept whole.
A few brands are reported under a shorter or longer name than the mark on screen, and name is that name in lowercase:
| On screen | Reported as (raw_name) |
|---|---|
| Monster Energy | Monster |
| Pepsi Max | Pepsi |
| Etihad | Etihad Airways |
| Mercedes-Benz | Mercedes |
| Mobil | Mobil 1 |
| Citi | Citibank |
| Coke | Coca-Cola |
| Petronas Syntium, Syntium | Petronas |
| P Zero | Pirelli |
| F1 | Formula 1 |
| NB | New Balance |
| LV | Louis Vuitton |
See also: Brand and logo detection, with real results.