# Creative assets upload

Upload creative assets and create first-party atomic creatives. This endpoint
validates files and metadata, stores assets, and returns the atomic creatives
that were created.
Creative upload limits:
| Creative upload shape | Limit |
|  --- | --- |
| Plain/non-ZIP uploaded files | 500KB per uploaded file |
| Uploaded ZIP package | 10MB per ZIP file |
| Direct files in the uploaded outer ZIP | 500KB per direct file |
| Assets inside an inner HTML5 package ZIP | 500KB recommended maximum; warning only |
| Uploaded filename form parts | 10 files max |

Send all files in a request with either the `filename` multipart field name
or the legacy `filename[]` multipart field name; do not mix both field names
in the same request. The OpenAPI
`x-max-file-size: 10485760` value is the transport/schema ceiling for uploaded
ZIP parts. Non-ZIP 500KB and direct outer-ZIP file 500KB limits are endpoint
validation rules. Assets inside an inner HTML5 package ZIP over 500KB are
accepted with a `meta.warnings` entry unless the `html5-file-too-large` sub_code
is promoted to an error by configuration. If multiple ZIP files are uploaded,
ZIP structural/content validation preserves the legacy behavior of validating
the first ZIP selected by the request.
Top-level uploads may use image extensions (`.gif`, `.jpg`, `.jpeg`, `.png`,
`.tiff`, `.tif`, `.svg`), the legacy `.swf` extension, loose HTML/CSS/JS/font
extensions (`.html`, `.htm`, `.css`, `.js`, `.woff`, `.woff2`, `.ttf`, `.otf`),
or ZIP packages. ZIP-inner HTML5 assets may use image extensions plus `.html`,
`.htm`, `.css`, `.js`, `.woff`, `.woff2`, `.ttf`, `.otf`, `.mp4`, and `.webm`.
HTML5 packages must use a two-level ZIP structure: the outer ZIP contains one
or more inner ZIP files, each inner ZIP contains the HTML5 creative assets, and
backup images are included in the outer ZIP. Loose files must not be uploaded
alongside an HTML5 ZIP package. Nested ZIPs beyond two levels are rejected.
HTML5 validation errors and warnings use these stable `sub_code` values:
| `sub_code` | Default disposition | Scope | Trigger |
|  --- | --- | --- | --- |
| `html5-missing-click-tracker` | Error | Inner package | No HTML/JS file contains a MediaMath click-tracker macro |
| `html5-noscript-tag` | Warning | Inner package | Root HTML contains a `<noscript>` tag |
| `html5-storage-api` | Warning | Inner package | HTML/JS file uses `localStorage` or `sessionStorage` |
| `html5-external-reference` | Warning | Inner package | Root HTML references an external asset |
| `html5-invalid-filename-chars` | Warning | Inner package | File name contains spaces, non-ASCII, or other non-standard characters |
| `html5-missing-file-extension` | Warning | Inner package | Extensionless file is recognized by content signature or root HTML reference |
| `html5-unsafe-filename-path` | Error | Inner package | File path is absolute, contains `.`/`..`, drive-letter, or UNC path components |
| `html5-filename-too-long` | Error | Inner package | File path exceeds 255 characters |
| `html5-unsupported-file-type` | Error | Outer ZIP and inner package | File extension is not allowed |
| `html5-file-too-large` | Warning | Inner package | Inner package asset exceeds the recommended 500KB maximum |
| `html5-file-too-large` | Error | Outer ZIP direct entry | Direct entry in uploaded outer ZIP exceeds 500KB |
| `html5-file-read-error` | Error | Inner package | Extracted HTML/JS file cannot be read |
| `html5-backup-mismatch` | Warning | HTML5 package auto-discovery | Backup image matches the package name only by letter case |
| `html5-backup-mismatch` | Error | HTML5 package auto-discovery | No backup metadata and no matching backup image exists |
| `html5-backup-mismatch` | Error | HTML5 package manual backup | Specified backup file is absent from the ZIP |
| `html5-invalid-package-structure` | Error | Outer ZIP | HTML appears directly in the outer ZIP |
| `html5-nested-zip-too-deep` | Error | Outer ZIP | ZIP nesting exceeds two levels |
| `html5-separate-files` | Error | Multipart request | Loose files are uploaded alongside an HTML5 ZIP package |
| `html5-submission-name-mismatch` | Error | Outer ZIP (HTML5) | Inner ZIP name is missing from `metadata.submissions[].name` |
| `submission-name-mismatch` | Error | Outer ZIP (non-HTML5) | Plain ZIP file is missing from `metadata.submissions[].name` |
| `zip-too-large` | Error | Uploaded ZIP | Uploaded ZIP exceeds 10MB |
| `html5-validation-error` | Error | Fallback | Internal fallback for an unmapped HTML5 validation rule |

Endpoint: POST /creative_upload
Version: 3.0.1807
Security: Auth0

## Security:

  - `Auth0` (unknown)
    oauth2 scopes: offline_access, manage:services

## Request fields (multipart/form-data):

  - `filename` (array, required)
    Creative files to upload. Send all files in a request as either `filename`
or the legacy `filename[]` field name; do not mix both field names in the
same request.
Loose/non-ZIP uploads are limited to 500KB per file. Uploaded ZIP packages are
limited to 10MB per ZIP. Direct files in the uploaded outer ZIP are limited to
500KB. Assets inside an inner HTML5 package ZIP over 500KB are accepted with a
warning unless the `html5-file-too-large` sub_code is promoted to an error. If
multiple ZIP files are uploaded, ZIP structural/content validation preserves the
legacy behavior of validating the first ZIP selected by the request.

  - `metadata` (object, required)
    JSON metadata for the upload request.

  - `metadata.advertiser_id` (integer, required)
    Example: 123

  - `metadata.is_https` (boolean)

  - `metadata.submissions` (array, required)
    Submission details for files being uploaded or ZIP/HTML5 package entries.

  - `metadata.submissions.name` (string, required)
    The creative file name. For loose/non-ZIP uploads this is the uploaded
filename. For regular ZIPs this is a file inside the ZIP. For HTML5
packages this is the inner ZIP filename, such as `interactive_ad.zip`.
    Example: banner_300x250.jpg

  - `metadata.submissions.click_through_url` (string, required)
    Example: https://example.com/click

  - `metadata.submissions.landing_page` (string)
    Example: https://example.com/landing

  - `metadata.submissions.concept_id` (integer, required)
    Example: 123

  - `metadata.submissions.backup` (string)
    Optional backup image filename for HTML5 creatives. Backup images must be
inside the HTML5 ZIP package. If omitted, the API attempts to find an
image with the same base filename as the HTML5 package.
    Example: backup_image.jpg

  - `metadata.submissions.mraid_type` (string)
    Optional MRAID type. `expandable` requires the `expandable` image field;
`expandable` must not be supplied for other MRAID types.
    Enum: "static", "expandable", "interstitial"

  - `metadata.submissions.expandable` (string)
    Required when `mraid_type` is `expandable`; otherwise invalid.
    Example: expandable_image.jpg

  - `metadata.submissions.creative_name` (string)
    Optional display name for the created atomic creative. When provided,
this overrides the default name derived from the submission filename.
    Example: My Custom Creative Name

## Request examples:

  - `Single creative upload request` (unknown)

  - `Multiple image upload request` (unknown)

  - `HTML5 creative ZIP upload request` (unknown)

  - `HTML5 creative ZIP upload request with explicit backup image` (unknown)

  - `MRAID expandable upload request` (unknown)

## Response 201:

  - `201` (unknown)
    Upload completed successfully

## Response 201 fields (application/json):

  - `data` (array)

  - `data.id` (integer, required)

  - `data.version` (integer, required)

  - `data.entity_type` (string, required)

  - `data.advertiser_id` (integer, required)

  - `data.concept_id` (integer)

  - `data.concept_name` (string)

  - `data.name` (string, required)

  - `data.width` (integer, required)

  - `data.height` (integer, required)

  - `data.creative_import_file_id` (integer)

  - `data.file_type` (string, required)

  - `data.is_https` (boolean, required)

  - `data.is_multi_creative` (boolean, required)

  - `data.has_sound` (boolean, required)

  - `data.rich_media` (boolean, required)

  - `data.rich_media_provider` (string)

  - `data.status` (boolean)

  - `data.archived` (boolean)

  - `data.built` (boolean, required)

  - `data.build_date` (string)

  - `data.built_by_user_id` (integer)

  - `data.build_errors` (string)

  - `data.created_on` (string, required)

  - `data.last_modified` (string, required)

  - `data.external_identifier` (string)

  - `data.tpas_ad_tag_name` (string, required)

  - `data.updated_on` (string, required)

  - `data.expand` (string)

  - `data.click_url` (string)

  - `data.ad_format` (string, required)

  - `data.expansion_direction` (string, required)

  - `data.expansion_trigger` (string, required)
    Enum: "AUTOMATIC", "MOUSEOVER", "CLICK"

  - `data.ad_server_type` (string)

  - `data.t1as` (boolean, required)

  - `data.tpas_ad_tag` (string)

  - `data.edited_tag` (string)

  - `data.click_through_url` (string)

  - `data.rejected_reason` (string)

  - `data.approval_status` (string, required)

  - `data.start_date` (string)

  - `data.end_date` (string)

  - `data.media_type` (string, required)

  - `data.is_mraid` (boolean, required)

  - `data.vast_version` (number)

  - `data.sizmek_tag_status` (string, required)

  - `data.sizmek_creative_status` (string, required)

  - `data.last_payload_modified` (string)

  - `data.is_audio` (boolean)

  - `data.tag` (string)

  - `data.tag_type` (string)

  - `meta` (object)

  - `meta.status` (string, required)
    Example: success

  - `meta.count` (integer, required)
    Example: 1

  - `meta.warnings` (array)

  - `meta.warnings.code` (string)
    Example: warning

  - `meta.warnings.sub_code` (string)
    Example: html5-noscript-tag

  - `meta.warnings.message` (string)

  - `meta.warnings.field` (string)

## Response 400:

  - `400` (unknown)
    Bad request

## Response 400 fields (application/json):

  - `errors` (array, required)

  - `errors.code` (string)

  - `errors.sub_code` (string)
    Optional identifier that refines the generic `code` category (e.g. `html5-noscript-tag`). Present on HTML5 upload/preview validation errors; absent otherwise.

  - `errors.field` (string)
    Optional when it is a schema error

  - `errors.message` (string)

  - `meta` (object, required)

  - `meta.status` (string, required)

## Response 401:

  - `401` (unknown)
    Error response

## Response 401 fields (application/json):

  - `errors` (array, required)

  - `errors.code` (string)

  - `errors.sub_code` (string)
    Optional identifier that refines the generic `code` category (e.g. `html5-noscript-tag`). Present on HTML5 upload/preview validation errors; absent otherwise.

  - `errors.field` (string)
    Optional when it is a schema error

  - `errors.message` (string)

  - `meta` (object, required)

  - `meta.status` (string, required)

## Response 403:

  - `403` (unknown)
    Not authorized

## Response 403 fields (application/json):

  - `errors` (array, required)

  - `errors.code` (string)

  - `errors.sub_code` (string)
    Optional identifier that refines the generic `code` category (e.g. `html5-noscript-tag`). Present on HTML5 upload/preview validation errors; absent otherwise.

  - `errors.field` (string)
    Optional when it is a schema error

  - `errors.message` (string)

  - `meta` (object, required)

  - `meta.status` (string, required)

## Response 201 examples:

  - `Single image creative uploaded` (unknown)

## Response 400 examples:

  - `Loose uploaded file over 500KB` (unknown)

  - `Uploaded ZIP over 10MB` (unknown)

  - `Direct outer-ZIP entry over 500KB` (unknown)

  - `HTML5 package with multiple blocking violations` (unknown)

