Portal Community
Asynchronous processing: This node sends the update request to Meta and receives a confirmation that the request was accepted. WhatsApp processes the image asynchronously — the new photo may take several minutes to appear on the profile. Do not call profile/getPhoto immediately after this node and expect the new URL.

When to Use

Configuration

Connection

FieldRequiredDescription
accessTokenRequiredPermanent System User access token from Meta Business Manager. Store in BizFirst Credentials Manager.
phoneNumberIdRequiredNumeric string ID of the WhatsApp Business phone number whose profile photo you want to update.
apiVersionOptionalMeta Graph API version, e.g. v18.0. Defaults to v18.0.

Operation

FieldRequiredDescription
photoUrlRequiredPublicly accessible URL of the new profile picture. Must be JPEG or PNG format. Minimum dimensions: 192 × 192 pixels. Recommended: 640 × 640 pixels, square aspect ratio. The URL must be directly reachable by Meta's servers — authenticated URLs (requiring cookies or tokens) will fail.
Image requirements:

Sample Configuration

{
  "resource": "profile",
  "operation": "updatePhoto",
  "accessToken": "{{ $credentials.whatsAppToken }}",
  "phoneNumberId": "123456789012345",
  "photoUrl": "https://cdn.bizfirstai.com/brand/logo-whatsapp-640x640.jpg"
}

Validation Errors

ErrorCause
accessToken is requiredThe accessToken field is empty or missing.
phoneNumberId is requiredThe phoneNumberId field is empty or missing.
photoUrl is requiredThe photoUrl field is empty or missing.
100 (Meta)Phone number ID not found or token does not have access.
190 (Meta)Access token expired or invalid.
200 (Meta)Token lacks required permission scope.
131000 (Meta)The image URL is not accessible by Meta's servers, the image format is unsupported, or the image dimensions are below the minimum.

Output

Success Port

Fires when Meta accepts the photo update request. The profile picture update is processed asynchronously — the new photo will appear on the profile within a few minutes. Use profile/getPhoto to confirm the new URL after a delay.

FieldTypeDescription
statusstring"updated" when Meta accepts the request. Note this reflects API acceptance, not completion of image processing.
errorCodestringEmpty on success.
errorMessagestringEmpty on success.
rawResponsestringFull raw JSON response from Meta, typically {"success":true}.

Error Port

FieldTypeDescription
statusstring"failed" or "error".
errorCodestringMeta error code or BizFirst internal code.
errorMessagestringHuman-readable description of the failure.
rawResponsestringRaw API error JSON for diagnostics.

Sample Output

{
  "status": "updated",
  "errorCode": null,
  "errorMessage": null,
  "rawResponse": "{\"success\":true}"
}

Expression Reference

ValueExpressionNotes
Status{{ $output.updatePhoto.status }}"updated" confirms acceptance. Wait several minutes then use profile/getPhoto to verify the new URL is live.
Error code{{ $output.updatePhoto.errorCode }}Non-null on error port. Code 131000 means the image URL is inaccessible or format is wrong.
Error message{{ $output.updatePhoto.errorMessage }}Human-readable reason for failure. Log for audit records.
Raw response{{ $output.updatePhoto.rawResponse }}Meta's raw confirmation JSON for logging.

Node Policies & GuardRails

Policy AreaRecommendation
Public image URLThe photoUrl must be publicly accessible without authentication. Test the URL in a browser in incognito mode before using it in the workflow. Authentication-protected URLs (S3 presigned URLs, CDN-gated URLs) will fail with error 131000.
Image dimensionsValidate image dimensions in an upstream Function node before calling this operation. Images below 192 × 192 pixels will be rejected.
Asynchronous confirmationDo not poll profile/getPhoto immediately after this node. Wait at least 5 minutes before checking that the new photo URL has propagated. Use a scheduled or delayed workflow step for verification.
Credential storageStore the access token in BizFirst Credentials Manager. Never paste it into node configuration as plain text.
Audit loggingLog all profile photo updates — phone number ID, old photo URL (from a prior profile/getPhoto call), new photo URL, timestamp, and the triggering workflow — for brand change management.
Error port handlingAlways connect the error port. A failed photo update that goes undetected can leave a profile with a broken or outdated image.

Examples

Onboarding — Set Brand Logo

{
  "resource": "profile",
  "operation": "updatePhoto",
  "accessToken": "{{ $credentials.whatsAppToken }}",
  "phoneNumberId": "{{ $input.phoneNumberId }}",
  "photoUrl": "{{ $input.brandLogoUrl }}"
}

A new tenant onboarding workflow calls this node to set the tenant's brand logo on their WhatsApp profile. The brand logo URL is retrieved from the tenant's asset record in the platform database. After a 5-minute Delay node, a profile/getPhoto node verifies the new photo is live, then marks the onboarding step as complete.

Seasonal Logo Rotation

// Scheduled to run on Dec 1:
{
  "resource": "profile",
  "operation": "updatePhoto",
  "accessToken": "{{ $credentials.whatsAppToken }}",
  "phoneNumberId": "123456789012345",
  "photoUrl": "https://cdn.bizfirstai.com/brand/holiday-logo-640x640.jpg"
}

// Scheduled to run on Jan 2:
{
  "resource": "profile",
  "operation": "updatePhoto",
  "accessToken": "{{ $credentials.whatsAppToken }}",
  "phoneNumberId": "123456789012345",
  "photoUrl": "https://cdn.bizfirstai.com/brand/standard-logo-640x640.jpg"
}

Two scheduled workflows handle seasonal logo rotation. The December 1 workflow sets the holiday logo. The January 2 workflow restores the standard logo. Both the holiday and standard logo URLs are permanent, publicly accessible CDN URLs that do not expire. The brand team stores the approved URLs in a configuration table managed by the platform.

Multi-Account Brand Refresh

// Loop node iterates over all managed phone number IDs
{
  "resource": "profile",
  "operation": "updatePhoto",
  "accessToken": "{{ $credentials.whatsAppToken }}",
  "phoneNumberId": "{{ $loop.currentItem.phoneNumberId }}",
  "photoUrl": "{{ $input.newBrandLogoUrl }}"
}

After a company rebrand, a one-time bulk workflow iterates over all registered phone number IDs and updates each with the new logo URL. A Delay node between iterations (500ms) prevents rate-limit errors for large account portfolios. Results are collected and a completion summary is sent to the brand manager confirming how many accounts were updated successfully.