Upload Brand Image

Learn how to upload brand assets to your workspace

Updated

POST
/v1/brand-assets/images/add
curl -X POST "https://api.orshot.com/v1/brand-assets/images/add" \
  -H "Authorization: Bearer <ORSHOT_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "file": "<FILE>",
    "fileName": "<FILE_NAME>",
    "fileType": "<FILE_TYPE>",
    "tags": []
  }'

Overview#

This endpoint allows you to upload new brand assets (images) to your workspace. You can upload images from a URL or as a base64-encoded string.

Endpoint
https://api.orshot.com/v1/brand-assets/images/add

Request#

JavaScript
await fetch("https://api.orshot.com/v1/brand-assets/images/add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    file: "https://example.com/path/to/image.png", // supports base64, url or binary
    fileName: "company-logo.png", // optional
    fileType: "image/png", // optional
    tags: ["logo", "brand"], // optional
  }),
});
JavaScript
await fetch("https://api.orshot.com/v1/brand-assets/images/add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: "Bearer <ORSHOT_API_KEY>",
  },
  body: JSON.stringify({
    file: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
    fileName: "product-image.png", // optional
    meta: { // optional
      description: "Product image for website",
      category: "products"
    }
  }),
});
JSON
{
  "data": {
    "asset": {
      "id": 102,
      "created_at": "2025-09-11T10:15:30.123Z",
      "direct_url": "https://storage.orshot.com/cloud/w-50/renders/brand_assets/company-logopng-R7tL2mWq8Zd.png",
      "file_name": "company-logo.png",
      "file_size": 24680,
      "tags": ["logo", "brand"],
      "workspace_id": 50,
      "user_id": "abcdef01-2345-6789-abcd-ef0123456789"
    },
    "url": "https://storage.orshot.com/cloud/w-50/renders/brand_assets/company-logopng-R7tL2mWq8Zd.png"
  }
}

Request Parameters#

ParameterTypeRequiredDescription
fileStringYesURL, binary or base64-encoded string of the image
fileNameStringNoCustom filename for the asset (default: auto-generated based on timestamp)
fileTypeStringNoMIME type of the file (e.g., "image/png"). If omitted, the type comes from the URL's Content-Type or extension, or from the data: prefix. Raw base64 without a prefix is treated as PNG, so pass fileType for SVG, JPEG, WebP or GIF
tagsString[]NoArray of tags to associate with the asset (e.g., ["logo", "brand"])
metaObjectNoArbitrary metadata to store with the asset (e.g., { "source": "product-catalog" })

Supported Image Formats#

  • PNG (image/png)
  • JPEG (image/jpeg)
  • WebP (image/webp)
  • SVG (image/svg+xml)
  • GIF (image/gif)

Notes#

  • Images are automatically optimized and resized if needed (maximum dimensions: 2000x2000 pixels)
  • Raster images are re-encoded at quality 80
  • Animated GIF and WebP files keep only their first frame. Upload animated GIFs with Upload Video to keep the animation
  • direct_url and url point to the stored file. Treat these URLs as opaque.
  • Maximum file size: 10MB
  • SVG files keep their vector format. They are stored in a cleaned form: shapes, groups, paths, text, gradients, patterns, masks, clip paths, markers, the common filter primitives, <style> rules and embedded data: images stay. Links to other files, @import and external url() loads are removed. An SVG with scripts, event handlers, foreignObject, javascript: links or embedded documents is refused with code: "svg_unsafe". So is a file that declares XML entities (some older Illustrator exports). Remove that content or re-export it as plain SVG, then upload again. The stored file is served with Content-Disposition: attachment, so it downloads when opened by its URL and renders as usual inside <img>, templates and renders.

Error responses#

Input problems return 400 with a plain-language error and, for the two cases agents hit most, a stable code:

  • IMAGE_NOT_AN_IMAGE: the bytes carry no PNG, JPEG, WebP, GIF or SVG signature. Usually a filename, a description, or placeholder text was sent instead of the file, or a URL served an HTML page.
  • IMAGE_DATA_INCOMPLETE: the data starts as a real image file but ends early. The base64 was cut off in transit, the URL served a partial file, or the upload stopped before the end. The error names the fix for how the file was sent.

Hosted chat clients such as ChatGPT and Claude.ai cannot send file bytes, so a base64 file from them is almost always cut off. Pass a publicly reachable image URL instead.

Query Parameters#

ParameterTypeRequiredDescription
embedIdStringNoEmbed instance ID. Pair with embedUserId to scope this call to one embed user
embedUserIdStringNoThe same userId your app passes to the embed URL. Requires embedId

Per-User Libraries#

Pass embedId and embedUserId together to create the image in that embed user's private library instead of the shared workspace library. This is how one embed serves many brands or tenants, each with its own brand space.

Omit them and this endpoint behaves exactly as documented above. See Per-User Brand Assets for the full picture.

Rate Limits#

  • 30 requests per minute per endpoint
Was this page helpful?

Ready to automate?

Start rendering images, PDFs and videos from your templates in under 2 minutes. Free plan, no credit card.

Get your API key
  • Image, PDF and video generation via API
  • Visual editor with AI and smart layouts
  • Zapier, Make, MCP and 40+ integrations
  • White-label embed for your own app
  • 100 free credits a month, no credit card required