Import an image from a URL
Fetches the image at url into the asset library and returns the
{{asset}} reference to use in its place — the fix an
external_image notice offers. Only public addresses are fetched,
with a 15-second timeout and at most three redirects.
It is an upload whose bytes come from a URL, so the format allowlist,
the 5 MiB limit, the storage quota and 409 edge_cdn_not_provisioned
are the upload's. Two things differ: the path is chosen for you —
imported/<name>-<hash8>.<ext>, named by the stored bytes, so
importing the same image again answers unchanged: true with the same
path — and an SVG is converted to PNG rather than refused.
Your template is not changed. You own its source; replace
source_url with reference there and push again.
Request body
Content type: application/json
url string required An http://, https:// or protocol-relative image URL — typically the ref of an external_image notice.
Responses
Errors follow the RFC 7807 problem format — see the error reference.
unchanged is true when it was already in the library. application/json id string<uuid> required source_path string required The logical path templates reference, e.g. static/logo.png. It is the path that was supplied on upload.
url string required Public CDN URL for the image, or "" when no Edge stack is provisioned yet.
content_hash string required Content-addressed hash of the image bytes.
content_type string required MIME type, e.g. image/png.
size_bytes integer<int64> required width integer required Pixel width, or 0 when unknown (e.g. SVG).
height integer required Pixel height, or 0 when unknown (e.g. SVG).
created_at string<date-time> required referenced_by array<object> required The templates whose body references this asset's path. Always present: an empty array means the scan ran and found none, which is what a caller about to delete the asset needs to know.
Each entry in referenced_by:
id string<uuid> required name string required tags array<object> optional Org-side tags/folders applied to this asset (managed via the dashboard). Filter the collection with ?tag=.
Each entry in tags:
id string<uuid> required name string required Full folder path (e.g. Marketing/Newsletters).
key string required Normalized slug handle of the name.
color string optional Chip colour token (chart-1..chart-5), or empty.
description string optional created_at string<date-time> required updated_at string<date-time> required unchanged boolean required True when the same bytes were already stored at this path — no object was written and no row was touched. A CI push that re-runs on every commit sees this on every unchanged image.
reference string required The token to put where source_url was: {{asset "imported/logo-1a2b3c4d.png"}}.
source_url string required The URL as given, to find and replace in your template source.
converted_from_svg boolean required The URL served an SVG; the library holds a PNG rendering of it, because Gmail and most Outlook versions do not render SVG.
code: plan_limit_exceeded). limit_type names the limit — a usage axis such as contacts, segments or active_workflows, or a feature the plan does not include (inboxes, platform_profile, audit_log, notification_presets). upgrade_url is the dashboard page that lifts it; overage_available says a Business organization can lift it by switching overage on instead. Retrying will not succeed until the plan changes or usage drops below the limit. application/problem+json code is conflict.
application/problem+json validation_failed Problem. When the refusal is about a
reference — a segment key, template slug, topic or attribute name the
organization does not have — it additionally carries validation_code,
field, line/column, missing, candidates and next_step, so a
client can correct the call without a second round of guessing. See
ValidationProblem.
application/problem+json code is internal_error. The
request_id field can be quoted to SendOps support to investigate.
application/problem+json