> ## Documentation Index
> Fetch the complete documentation index at: https://docs.semicola.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Inspect a tag sheet

> Use when a buyer wants to check how Semicola reads a CSV, XLS or XLSX ad tag sheet before importing it: how many creatives it finds, their sizes, and which rows need a destination.

Skill `inspect-tag-sheet` · version 1.0.0 · for buyers.

## When to use

* A person has an ad-server tag sheet (for example a CM360 export) and wants to know what Semicola
  will make of it before creating creatives.
* An import found fewer or more creatives than the person expected.
* A sheet was refused ("Failed to read uploaded files") and the person wants to know why.

## Before you start

* You are connected to the buyer account with an API key (the preview is a REST call).
* The file is CSV, XLS or XLSX and at most 5 MB.
* The person agrees to send the file to Semicola for the preview. The preview doesn't save anything,
  but the workbook does leave their machine.

## Steps

1. Base64-encode the file as a `data:` URL, keeping its real MIME type.
2. Call `POST /api/v2/buyer/creatives/tag-sheet-preview` with
   `{ "asset": { "data_url": "data:…;base64,…", "name": "<file name>" } }`. `name` must end in
   `.csv`, `.xls` or `.xlsx`. No advertiser is needed and nothing is stored.
3. Read the result:
   * `creative_count`: how many creatives an import would create, one per placement row.
   * `rows[].name` and `rows[].declared_sizes`: what each creative would be called and its sizes.
   * `rows[].needs_destination`: `true` when the row only has a VAST or Internal Redirect tag. That
     tag depends on where it's trafficked, so it's kept as inert source until a destination is
     chosen.
4. Compare `creative_count` with what the person expected. If it matches, tell them they can import
   it from the creative library's **Bulk upload creatives** task.
5. If the call fails, say which of these it is:
   * "Tag sheets are CSV, XLS or XLSX files." Wrong file type.
   * "That file is larger than 5 MB." Split the sheet.
   * "The expanded files exceed the upload limits." An XLSX that unpacks too large.
   * "Failed to read uploaded files." The file couldn't be parsed, or no tag rows were found.

## How the parser reads a sheet

* It finds the real header row under any instruction preamble.
* For each placement row it picks one display tag, preferring **Iframes/JavaScript**, then
  **JavaScript**, then **Standard**; a generic `Tag`/`Code`/`Snippet` column also counts.
* A modern row wins over the same placement and size on a **Legacy** sheet.
* VAST pre-fetch and Internal Redirect columns are kept as alternatives, never picked as the display
  tag.
* Formulas, tags and scripts are never executed.

## Guardrails

* The preview never returns tag markup or URLs, only names, sizes and flags. Don't ask the person to
  paste tags into chat to "check" them.
* `creative_count` is what the parser found, not proof that a tag works. Say so.
* Don't import without the person's go-ahead; an import creates draft creatives on an advertiser.
* To report a sheet the parser reads wrongly, ask first, then call `save_ask` with `type: "support"`
  and only the expected and observed counts. Never attach the workbook or its contents.

## Not available yet

* An offline inspector that runs on the person's machine without sending the file.
* A content-free parse receipt (`mode`, `appliedRuleIds`, `recognizedRoles`, `diagnosticCodes`) and
  a published parser profile.
* A tag-sheet preview tool on the v3 MCP endpoint: in chat the preview runs inside the Bulk upload
  task; agents use the REST call.
