Rising Tide Developers
SDKCore

rtClient.productImages

The permanent picture of a product or edition, resolved in batches.

Every rendered smart product and every edition of one has a permanent PNG on Arweave - the same image its token URI advertises and a wallet displays. rtClient.productImages hands back the URL for a batch of them, so a grid can show people the thing rather than a placeholder.

It renders nothing. An entity whose render has not completed is simply absent from the reply, which is the distinction a caller needs: still being made is not the same as broken.

rtClient.productImages.list(entity, ids, options?)

entity is "product_instance" or "smart_product". ids is bounded at PRODUCT_IMAGES_MAX_IDS (100); batch above that.

import { PRODUCT_IMAGES_MAX_IDS } from "@rising-tide/sdk";

const res = await rtClient.productImages.list("product_instance", [1, 2, 3]);
const image = res.data.images["1"];   // undefined = no artifact yet
if (image) {
  console.log(image.url, image.role, image.bytes);
}

Each ProductImage carries:

FieldMeaning
urlPermanent, content-addressed. Safe to cache indefinitely.
roleIMAGE_PORTRAIT, IMAGE_SQUARE, IMAGE_LANDSCAPE or IMAGE_OG - which render this came from
contentTypeimage/png today
bytesSize of the stored artifact

role is returned because it is not always the one you asked for. Portrait is preferred, but a product rendered only in another orientation still returns its picture: a wrong-shaped real image beats a grey box, and the caller needs to know so it can crop or letterbox honestly.

Pass { prefer: "og" } for a social card. Every product and edition is rendered in a 2400x1260 card aspect, and this option returns that shape or nothing - it deliberately does not substitute a portrait, which a link preview would crop to a band. An absent entry means use your own default card.

const res = await rtClient.productImages.list("smart_product", [productId], { prefer: "og" });

Choosing this over the thumbnail route

/api/contracts/{address}/{name}/tokens/{index}/thumbnail renders SVG on demand. Prefer it for a single large view or a lightbox. Prefer productImages anywhere many things are shown at once:

  • The SVG carries its font faces inline, so one costs about 106 KiB against roughly 48 KiB for the archival PNG.
  • The font cannot be linked to make it smaller. An SVG loaded as <img src> is a restricted context that fetches no external resource, so a linked face silently renders in a fallback - a failure that looks like success.
  • The PNG is content-addressed, so it caches forever rather than for the thumbnail route's TTL.

Serving the URL

The reply prefers the canonical Arweave gateway. Both it and the upload provider's gateway address the same immutable bytes, but measured across eight live artifacts the canonical one served 8/8 in 0.52-1.31s while the provider's took 13-20 seconds on a first fetch and 404'd one artifact the canonical gateway returned correctly.

If you render these through an image optimizer, allow arweave.net as a remote host. The artifact is drawn at wallet size (1700×2200), so a grid of unoptimized ones downloads far more than it displays.