Please refer to this post Build a Custom Profile Center for Multi-Org purpose and then to this link in the sfmc documentation:https://developer.salesforce.com/docs/atlas.en-us.mc-apis.meta/mc-apis/creating_a_custom_profile_center_using_ampscript_and_the_soap_api.htm. I'm sure a lot of you are familiar with these two docs.

I'm trying to put together a custom profile, preferences & subscription center and I'm not much of a developer and don't code that frequently, but I'm trying to learn and understand code, specifically Ampscript. I have looked at several posts on SE and referred several code examples but unable to decide where to start. Our requirement really after the subscriber clicks on the "Manage Preferences" link on the email, an encrypted link is generated by the CloudPagesURL function which directs it to the main profile/pref/subscription form and we should be able to retrieve the contact's data from the integrated sales cloud contact object and update it. The profile & Preference attributes are mapped to the respective fields on the contact object in Sales cloud. The sample code given by sfmc seems too overwhelming and there is not enough clear documentation on it. Based on our requirements above, what's the best guidance and help the community experts can provide ? I have looked at Adam Sprigg's boilerplate code in JS for profile & preference management but I think, it lacks subscription management. Please help!

1 Answer 1


if you are trying to learn AMPscript, building an integrated custom profile center isn't the best starting point, as you really need to understand core language fundamentals such as rowsets, conditional statements, logical operators and more. However, I've provided and annotated a simple one page example below.

Paste the code below in a CloudPages Landing Page and then use the CloudPagesURL function to link to the page you create — you just need to include the page id as an argument, for example: %%=CloudPagesURL(123)=%%.

Update: Subscription Management

Regarding your comment on subscription management:

My thought is to create two new custom fields on the contact object called subscription (text) & subscribed (boolean) and retrieve these two fields on a separate cloud page, check the status and subscribe or unsubscribe according to the action.

I wouldn't advise storing subscription data against a Contact record. You are likely to incur technical debt in the long term and it's not good practice. Instead, I would advise you consider creating Campaigns for each 'subscription' and adding the Contact as a Campaign Member. And you can easily send to campaign members from Email Studio or Journey Builder.

However, if you insist on using the Contact record, then I've updated my code with two custom fields with the API names Subscribed__c and Subscription__c respectiviely. Subscribed__c is a checkbox field and Subscription__c is a picklist with values 'Newsletter' or 'Other'. When the page loads, the selected picklist values are pre-selected on the form.

Additional Notes

I'm not sure how you intend to allow Subscribers to globally opt-out unsubscribe from email, but if this is a requirement, then you would need to call the LogUnsubEvent object from the SOAP API (which you are probably better off calling in SSJS and WSProxy rather than AMPscript) which would unsubscribe the Subscriber and deselect the 'HasOptedOutOfEmail' flag on the Contact record. However, this is outside the scope of this code example.

Also, please be aware that this is code is provided in its simplest form. It's not how I would build this page (I would use AJAX instead and build in more comprehensive exception handling and logging) but I've kept it as simple as I can as you mentioned you are not a developer.


var @Id, @firstName, @lastName, @email, @subscribed, @subscription, @subscriberRows, @subscriberRow
set @Id = _subscriberKey 

/* if form was not sumbitted, get object record */
if RequestParameter("submitted") != true then

  /* get rowset */
  set @subscriberRows = RetrieveSalesforceObjects(
     "Id", "=", @Id )

  /* get row (there will only be 1) */
  set @subscriberRow = Row(@subscriberRows, 1)

  /* get fields */
  set @firstName = Field(@subscriberRow, "FirstName")
  set @lastName = Field(@subscriberRow, "LastName")
  set @email = Field(@subscriberRow, "Email")
  set @subscribed = Field(@subscriberRow, "Subscribed__c")
  set @subscription = Field(@subscriberRow, "Subscription__c")


/* form was sumbitted, update object record with form data */
  var @updateRecord
  set @firstname = RequestParameter("firstname")
  set @lastName = RequestParameter("lastname")
  set @email = RequestParameter("email")
  set @updateRecord = UpdateSingleSalesforceObject(
      "FirstName", @firstname,
      "LastName", @lastName,
      "Email", @email,
      "Subscribed__c", @subscribed,
      "Subscription__c", @subscription

<!DOCTYPE html>
      %%[ if @updateRecord == 1 then ]%%
         <p>Record Updated</p>
      %%[ elseif @updateRecord == 0 then ]%%
        <p>Update Failed</p>
      %%[ endif ]%%
      <h2>Update Your Details</h2>
      <form action="%%=RequestParameter('PAGEURL')=%%" method="post">
         <label>First name</label>
         <input type="text" name="firstname" value="%%=v(@firstName)=%%">
         <label>Last name</label>
         <input type="text" name="lastname" value="%%=v(@lastName)=%%">
         <input type="text" name="email" value="%%=v(@email)=%%">
         <input type="checkbox" value="subscribed" %%[IF @subscribed == true THEN]%%checked="checked"%%[ENDIF]%%>
        <select name="subscripiton">
           <option value="">Select one&hellip;</option>
           <option value="Newsletter" %%[IF @subscription == "Newsletter" THEN]%%selected%%[ENDIF]%%>Newsletter</option>
           <option value="Other" %%[IF @subscription == "Other" THEN]%%selected%%[ENDIF]%%>Other</option>
         <input name="submitted" type="hidden" value="true" />
         <input type="submit" value="Submit">
  • 1
    I have updated my answer. Jan 1, 2020 at 1:22
  • 1
    Adding a couple of custom fields on the Contact record is certainly the easiest option, but not the best IMHO. I would (a) create new campaigns for each subscription (setting the Type to 'Email Subscription' or similar), then (b) retrieve all campaigns that match the type from the CloudPage. Then you can use AMPscript CreateSalesforceObject function to create new Campaign Member records and UpdateSingleSalesforceObject to update existing records. Jan 1, 2020 at 2:50
  • 1
    Again, I really only provided the code as a starting point. SFSE isn't intended to be a free code writing service. Given the complexities and additional considerations (which are numerous), this really isn't the right project to learn AMPscript and I'd recommend getting someone else (either an experienced dev in your company or an external consultant) to build this properly and you can then learn from. I'm happy to assist further (for a fee), but this is as far as I can provide free community guidance on SFSE. Jan 1, 2020 at 2:51
  • 1
    Glad I could provide some guidance. Feel free to upvote if you found my answer helpful. Jan 1, 2020 at 3:55
  • 1
    @zuzannamj there is a HasOptedOutOfEmail field on the CampaignMember object (which is separate from the HasOptedOutOfEmail field on the Lead and Contact record). I'd consider using that, or the Status field as you suggest. May 13, 2020 at 2:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .