# getAssetUrl

```ts
function getAssetUrl(asset, preset): string;
```

Defined in: packages/asset-client/dist/index.d.ts:1099

Build the public CDN URL for a specific variant of an asset. The variant
may not actually exist (regenerate may not have run, or video has no
`aiproxy`); call `hasPreset()` first or expect a 404.

For the `original` preset, pass the whole `AssetDTO` — it carries `variants`
and `oext`, either of which gives the EXACT stored key. `mime` alone is only a
guess (the server keys the original off the uploaded filename), and with
nothing at all the original falls back to the `"bin"` sentinel, which 404s.

## Parameters

| Parameter | Type | Description |
| ------ | ------ | ------ |
| `asset` | [`Pick`](/api/nitida/sdk/react/-internal-/type-aliases/pick/)\<[`AssetDTO`](/api/nitida/sdk/type-aliases/assetdto/), `"sha"`\> & [`OriginalHints`](/api/nitida/sdk/-internal-/type-aliases/originalhints/) & [`VisibilityHint`](/api/nitida/sdk/type-aliases/visibilityhint/) & [`Partial`](/api/nitida/sdk/-internal-/type-aliases/partial/)\<[`Pick`](/api/nitida/sdk/react/-internal-/type-aliases/pick/)\<[`AssetDTO`](/api/nitida/sdk/type-aliases/assetdto/), `"presets"`\>\> | ⭐ `presets` ESTÁ EN EL TIPO PORQUE LA FUNCIÓN LO LEE. `transformFallbackFor` decide con este campo si devolver la clave de variante o caer a `/t/…width=N/`. Sin él en la firma, el tipo PROHIBÍA el campo que la implementación consulta: pasarlo era un error de compilación, y no pasarlo daba `…-x.webp` → 404 en silencio. Medido 2026-08-25 sobre un asset con `presets: "lmoqs"`: sin `presets` → /f/v/<sha>-x.webp 404 con `presets` → /t/format=webp,width=3840/<sha>.webp 200 |
| `preset` | [`VariantPreset`](/api/nitida/sdk/type-aliases/variantpreset/) | - |

## Returns

`string`

## Examples

**Video — the tenant segment is base36, so let this build the path**

```ts
import { getAssetUrl, setTenantId } from "@nitida/asset-client";

setTenantId(12);                        // 12 → "c"; a decimal "/12/v/" 404s
getAssetUrl({ sha }, "video");          // → https://8ok.uk/c/v/<sha16>-v.mp4
getAssetUrl({ sha }, "poster");         // → https://8ok.uk/c/v/<sha16>-p.webp
```

**The \`original\` — pass the DTO, not just the sha**

```ts
const asset = await aq.assets.get(id);

getAssetUrl({ sha }, "original");        // → …-o.bin   ❌ 404, always
getAssetUrl({ sha, mime }, "original");  // → a guess from the mime table
getAssetUrl(asset, "original");          // ✓ the stored key, verbatim
```

**Check before you link**

```ts
import { getAssetUrl, hasPreset } from "@nitida/asset-client";
const url = hasPreset(asset, "thumb") ? getAssetUrl(asset, "thumb") : null;
```