Browse documentation

Messaging

Retrieving inbound media

Fetch customer-sent media through Yanola without exposing Meta credentials to your application.

DevelopersAdvancedAvailable

What this guide covers

  • Start with the media reference included in an inbound message or event.
  • Retrieve media from trusted server code using the same project-scoped API key.
  • Store customer media according to your privacy and retention requirements.

Start with a Yanola media ID

Inbound media is represented by an opaque Yanola ID beginning with med_. Obtain it from a Yanola-normalized inbound message or event, then retrieve it with GET /v1/media/{mediaId}. Raw Meta media IDs are not accepted.

The operation requires messages:read and is restricted to the key's Yanola Account, Agent Project, environment, and permitted Senders.

Retrieve media metadata
ts
import { WhatsAppClient } from "@yanola/whatsapp"

const apiKey = process.env.YANOLA_API_KEY

if (!apiKey) {
  throw new Error("Missing YANOLA_API_KEY")
}

const yanola = new WhatsAppClient({ apiKey })

const media = await yanola.media.retrieve("med_...")

console.log(media.mimeType)
console.log(media.downloadUrl)
console.log(media.expiresAt)

Media response

Inbound media fields
FieldMeaning
idOpaque Yanola med_ public ID.
environmentlive or test; always matches the API key environment.
mimeTypeBest available cached or provider MIME type.
filenameOriginal or cached filename when available; otherwise null or omitted.
sizeBytesKnown byte size when available; otherwise null or omitted.
downloadUrlShort-lived signed Yanola proxy URL.
expiresAtISO 8601 time after which that download URL must not be used.

Download before the URL expires

downloadUrl is a signed capability URL. It streams through Yanola without an Authorization header and does not reveal Meta credentials or Yanola's permanent cache location.

Use the URL before expiresAt. If it expires while the retained media still exists, call media.retrieve with the same med_ ID to obtain a new URL.

Stream the temporary URL
ts
import { WhatsAppClient } from "@yanola/whatsapp"

const apiKey = process.env.YANOLA_API_KEY

if (!apiKey) {
  throw new Error("Missing YANOLA_API_KEY")
}

const yanola = new WhatsAppClient({ apiKey })

const media = await yanola.media.retrieve("med_...")
const response = await fetch(media.downloadUrl)

if (!response.ok) {
  throw new Error(`Media download failed: ${response.status}`)
}

const contentType =
  response.headers.get("content-type") ?? media.mimeType
const bytes = await response.arrayBuffer()

console.log(contentType, bytes.byteLength)

Environment and retention boundaries

A Live Mode key cannot retrieve Test Mode media, and a Test Mode key cannot retrieve Live Mode media. Passing an environment query for the other mode returns environment_mismatch.

Media is available only during its Yanola retention period. After retention ends, retrieval returns the same not-found response used for missing or inaccessible media so scope details are not disclosed.

Store customer media responsibly

  1. Download from trusted server or worker code, not by exposing the API key in a browser.
  2. Validate the returned MIME type and enforce your own size and file-policy limits before processing.
  3. Encrypt retained customer media and grant access according to your application's privacy policy.
  4. Delete local copies when your business purpose or retention period ends.
  5. Do not attempt to derive Meta credentials, provider IDs, or permanent storage locations from Yanola responses.

Retrieval errors

Common inbound media errors
Status and codeMeaningAction
400 environment_mismatchThe requested environment differs from the key environment.Remove the filter or use the matching key.
403 insufficient_scopeThe key lacks messages:read.Use a key with read access.
404 media_not_foundThe ID is malformed, expired, missing, inaccessible, or in another environment.Use the med_ ID from a visible Yanola event and check retention.
503 media_not_readyInbound media is still being prepared.Retry shortly; this error is retryable.
503 media_unavailableThe retained media is temporarily unavailable.Retry only when retryable is true.
404 media_download_not_foundA signed download grant is expired, malformed, or no longer valid.Retrieve metadata again to obtain a fresh URL.