URL expiry: The url field in the response is a short-lived signed URL that expires approximately 5 minutes after it is issued. Do not cache this URL — call media/download immediately if you need the file content.
When to Use
- Inbound media inspection: A webhook trigger receives a media message from a customer. Before downloading, a workflow uses this node to check the file size and MIME type to decide whether to accept, reject, or quarantine the file.
- Integrity verification: A compliance workflow retrieves the
sha256 field and compares it against a known hash to confirm that a media asset has not been altered since upload.
- File type routing: A support workflow receives media messages and uses the
mimeType from this node to route images to a visual inspection queue and PDFs to a document processing pipeline.
- Pre-download size check: A storage workflow checks
fileSize before downloading to avoid exceeding quota limits on the destination storage service.
- Audit logging: A governance workflow stores metadata (ID, MIME type, size, SHA-256) for every inbound media item for regulatory audit trail purposes without downloading the content.
Configuration
Connection
| Field | Required | Description |
accessToken | Required | Permanent System User access token from Meta Business Manager. Store in BizFirst Credentials Manager. |
phoneNumberId | Required | Numeric string ID of the WhatsApp Business phone number associated with the media. |
apiVersion | Optional | Meta Graph API version, e.g. v18.0. Defaults to v18.0. |
Operation
| Field | Required | Description |
mediaId | Required | The media object ID to look up. Typically sourced from a webhook event payload ({{ $trigger.message.image.id }}) or from a previous media/upload node output. |
Sample Configuration
{
"resource": "media",
"operation": "get",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"mediaId": "{{ $trigger.message.image.id }}"
}
Validation Errors
| Error | Cause |
accessToken is required | The accessToken field is empty or missing. |
phoneNumberId is required | The phoneNumberId field is empty or missing. |
mediaId is required | The mediaId field is empty or missing. |
100 (Meta) | Invalid media ID — the ID does not exist or belongs to a different phone number. |
190 (Meta) | Access token is expired or invalid. Rotate the token in BizFirst Credentials Manager. |
missing_url | Meta returned a success response but the URL field was absent. Retry once after a short delay. |
parse_error | Meta returned a non-JSON response, typically during a temporary API outage. |
Output
Success Port
Fires when Meta returns the media metadata. Note that the url expires after approximately 5 minutes — use it immediately or pass it directly to media/download.
| Field | Type | Description |
mediaId | string | The requested media object ID, echoed back. |
url | string | Temporary signed URL to download the media binary. Expires in ~5 minutes. |
mimeType | string | MIME type of the media file, e.g. image/jpeg. |
sha256 | string | SHA-256 hash of the file content for integrity verification. |
fileSize | number | File size in bytes. |
status | string | "success" on success. |
errorCode | string | Empty on success. |
errorMessage | string | Empty on success. |
rawResponse | string | Full raw JSON response from the Meta API. |
Error Port
Fires when Meta cannot locate the media or the request fails.
| Field | Type | Description |
status | string | "failed" or "error". |
errorCode | string | Meta error code or BizFirst internal code. |
errorMessage | string | Human-readable description of the failure. |
rawResponse | string | Raw API error JSON for diagnostics. |
Sample Output
{
"mediaId": "1234567890123456",
"url": "https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=1234567890123456&ext=...",
"mimeType": "image/jpeg",
"sha256": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"fileSize": 204800,
"status": "success",
"errorCode": null,
"errorMessage": null,
"rawResponse": "{\"url\":\"https://lookaside.fbsbx.com/...\",\"mime_type\":\"image/jpeg\",\"sha256\":\"a1b2...\",\"file_size\":204800,\"id\":\"1234567890123456\",\"messaging_product\":\"whatsapp\"}"
}
Expression Reference
| Value | Expression | Notes |
| Media ID | {{ $output.getMedia.mediaId }} | Echoed ID — pass to media/download or media/delete. |
| Download URL | {{ $output.getMedia.url }} | Use immediately — valid for ~5 minutes only. |
| MIME type | {{ $output.getMedia.mimeType }} | Use in a Switch node to route images vs. documents vs. audio. |
| File size (bytes) | {{ $output.getMedia.fileSize }} | Compare against storage quota limits before downloading. |
| SHA-256 hash | {{ $output.getMedia.sha256 }} | Compare against a known hash for integrity verification. |
| Status | {{ $output.getMedia.status }} | "success" on success. |
Node Policies & GuardRails
| Policy Area | Recommendation |
| URL expiry | The returned url expires in ~5 minutes. Never store it in a database or pass it to a long-running async step. Use media/download in the same workflow branch immediately after this node. |
| Credential storage | Store the access token in BizFirst Credentials Manager. Never paste it directly into node configuration. |
| Media ID scope | A media ID is only accessible from the same phone number ID that received or uploaded the media. Cross-account access returns error 100. |
| Size-before-download | Use the fileSize output in an IfCondition node to gate the download step and prevent large files from overwhelming downstream storage. |
| Error port handling | Always connect the error port. A deleted or expired media ID returns a 100 error — the workflow should log the event and notify the relevant team. |
| Integrity checks | For compliance use cases, store the sha256 value alongside the downloaded content so integrity can be re-verified later. |
Examples
Inspect Inbound Image Before Processing
{
"resource": "media",
"operation": "get",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"mediaId": "{{ $trigger.message.image.id }}"
}
A webhook trigger fires when a customer sends an image. This node fetches the metadata first. An IfCondition node downstream checks $output.getMedia.fileSize — files under 5 MB route to media/download and then to an OCR processor, while larger files are rejected with a courtesy text reply.
Route by MIME Type
{
"resource": "media",
"operation": "get",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"mediaId": "{{ $input.inboundMediaId }}"
}
A document ingestion workflow uses a Switch node on {{ $output.getMedia.mimeType }}: application/pdf routes to a PDF parser, image/jpeg and image/png route to an image analyser, and everything else routes to a generic binary storage node.
Pre-Download Integrity Check
{
"resource": "media",
"operation": "get",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"mediaId": "{{ $input.mediaId }}"
}
A compliance archival workflow first fetches metadata and stores sha256, mimeType, and fileSize in an audit log record. It then passes the mediaId to media/download and re-computes the hash server-side to confirm the content matches the metadata before archiving.