---
search:
  tags:
    - Assets
    - POST
seo:
  description: >-
    Creates an Asset in one of two ways. The Content-Type of the request picks
    one. Reference for the POST /assets endpoint in the AdCrunch API.
sidebar:
  label: Create an Asset from raw bytes
  badge: POST
title: Create an Asset from raw bytes
type: openapi-operation
---
Creates an Asset in one of two ways. The `Content-Type` of the request picks one.

**Raw bytes.** The body is the file. AdCrunch answers `201` with a `ready` Asset. Do not use `multipart/form-data`.

```
curl --data-binary @ad.png \
  -H "Authorization: Bearer $ADCRUNCH_API_KEY" \
  "https://api.adcrunch.dev/assets?filename=ad.png"
```

The bytes stream into storage. AdCrunch identifies the type from the bytes, and the `Content-Type` is only a hint. A file that AdCrunch refuses leaves no object and no Asset.

The request needs a `Content-Length`. A body with no length answers `411`.

**Size.** This route takes a body up to 95 MB. Over that, it answers `413` with `error` set to `use_upload_url`: reserve an upload with `POST /assets/uploads`, and `PUT` the file to the URL. A body over the limit of the Cloudflare plan of the domain, 100 MB at the lowest, never reaches AdCrunch. Cloudflare refuses it at the edge with its own `413` page, with no `use_upload_url`. Send a large video to `POST /assets/uploads`.

**Import from a URL.** The JSON body needs a `Content-Length` and is at most 8 KB. Send `Content-Type: application/json` with `{ "sourceUrl": "https://...", "name": "..." }`. `sourceUrl` must be an `https` URL on port 443, else the answer is `400` with `error` set to `invalid_url`. Its host must be a public name: an IP address, a local or private host, or an AdCrunch domain (`adcrunch.dev` and its subdomains) answers `400` with `error` set to `source_not_allowed`. AdCrunch answers `202` with a `pending` Asset, and a Workflow fetches the file. Poll `GET /assets/{id}` until `status` is `ready` or `failed`. A `failed` Asset has a `failureCode`: `source_unreachable` (the source did not answer, answered with an error, or sent the file in part), `source_length_unknown` (the source sent no `Content-Length`), `too_large`, `unsupported_type` or `unreadable`. The import does not follow a redirect to a URL that is not `https`.

```
curl -X POST \
  -H "Authorization: Bearer $ADCRUNCH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sourceUrl":"https://example.com/ad.png"}' \
  "https://api.adcrunch.dev/assets"
```

`POST /assets`
