Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.photon.codes/docs/llms.txt

Use this file to discover all available pages before exploring further.

The media resource handles the lifecycle of every file you send or receive. Uploaded media gets a mediaId you reference from messages.send; inbound media arrives as a mediaId you resolve to a signed URL.

Upload

import { readFile } from "node:fs/promises";

const { mediaId } = await client.media.upload({
  file: await readFile("/path/to/photo.jpg"),
  mimeType: "image/jpeg",
  filename: "photo.jpg",
});

await client.messages.send({
  to: "+15551234567",
  image: { id: mediaId, caption: "Here's the photo" },
});
file accepts a Buffer or Uint8Array — stream the file yourself if it doesn’t fit in memory.
OptionTypeDescription
fileBuffer | Uint8Array
filenamestring
mimeTypestring
Returns an . Save the mediaId only long enough to use it — WhatsApp expires uploaded media after ~30 days.

Get URL

Resolve an inbound mediaId to a signed, time-limited URL plus metadata:
for await (const event of client.events.subscribe()) {
  if (event.type !== "message") continue;
  if (event.message.content.type !== "image") continue;

  const { url, mimeType, fileSize, sha256 } = await client.media.getUrl(
    event.message.content.media.id,
  );

  // Fetch the bytes yourself
  const response = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.WA_ACCESS_TOKEN}` },
  });
  const bytes = await response.arrayBuffer();
}
FieldTypeDescription
fileSizenumber
mimeTypestring
sha256string
urlstring
The URL is signed by Meta and requires your access token in the Authorization header when you fetch it.

Delete

await client.media.delete(mediaId);
Removes the uploaded file from Meta’s storage. Safe to skip if you’re happy to let the 30-day expiration handle cleanup — delete explicitly when you need the space freed immediately (e.g. compliance requirements).

Supported MIME types

WhatsApp restricts which types are accepted per content category. The SDK passes whatever you give it — validation happens server-side.
CategoryCommon types
Imageimage/jpeg, image/png
Videovideo/mp4, video/3gpp
Audioaudio/aac, audio/mp4, audio/mpeg, audio/amr, audio/ogg (voice notes only)
DocumentAny MIME — PDFs, spreadsheets, archives
Stickerimage/webp
Check the official limits table for current size caps — they change per account tier.