Using the New Signup API to Manage Your Leads and Deployments!

Today, partners can use Trialforce to provision trials which is an easy and seamless way to turn prospects into paying customers. The new Signup Request API  takes this functionality to the next level.  It exposes a new SignupRequest object via the API and by simply adding records to this object, trials can be created. Since this is a standard object, it provides you with the full power of the platform. For example, it allows you to customize the signup process using workflows and track the status of trial signups. You can also run reports and analyze information on all signups, giving you more control over the signup process and visibility into your prospects. All of this is now possible with the new Signup API. You can find more details about the Signup API in the ISVForce guide here.

An additional benefit is that a partner can now capture more information from the user then ever before. The standard SignupRequest objects captures basic information about the prospect.  You can customize the SignupRequest object to capture and track more information about prospects to create better leads. I’m going to show you how to do this in the rest of this blog.

The ISV Business Org

The ISV Business Org is the org you use to run all business operations. It is where you have CRM in addition to ISV Platform Technologies like Trialforce Signup Requests, the License Management App (LMA) and the Channel Order App (COA). It is important to have your org configured this way to get the most value out of these tools.

How does the Signup Request API Work?

First, a user fills out a lead form on your website. When the form is submitted, the standard Salesforce SOAP/REST API is used to create a Signup Request record in the ISV Business Org. The Signup Request will contain all the information you captured about the person who signed up for the trial as well as the desired trial template. Once the Signup Request is created, a new Trialforce org will be provisioned based on the specified trial template. The Signup Request status will update to “Success” when the org is ready and the confirmation email has been sent out.

When the trial is provisioned the LMA automatically creates a Lead and License in the ISV Business Org. What we want to do is enrich the Lead we get from the LMA with the information we captured in the Trialforce Signup Request:

  1. Capture the additional information in the Signup Request.
  2. Merge this information with the existing Lead created by the LMA.

Setting it up

There are a few things you need to set up in your ISV Business Org to get all this working. These are summarized below:

  1. Enable the Signup Request API in your ISV Business Org. You can request this by logging a case in the Partner Portal.
  2. Create custom fields on the Signup Request object to capture the additional information you want to collect from leads.
  3. If needed, create custom fields on the Lead object to capture the additional information.
  4. Add a Trigger to copy the custom fields from the Signup Request to the Lead

Code Snippets

Here is some sample code for the trigger to help you get started. Please note that this is boilerplate code that WILL NOT work unless you modify it to suit your environment.

Trigger To Merge Custom Fields from Signup Request to Lead

Once the Signup Request is successful, find the corresponding Lead and enrich it with the custom fields.

trigger LeadEnrichment on SignupRequest (after update) {

//Create a list to hold all Lead records to update
    List<Lead> leadsToUpdate = new List<Lead>();
    Set<String> subscriberOrgIds = new Set<String>();

//Loop through each successful signup request made and create list of orgIds
for (signupRequest
        //Check SignupRequest status change
        if (sr.status == 'Success')
        if (sr.createdOrgId !=null)

List<sfLma__License__c> licenses  = [select sfLma__Subscriber_Org_ID__c, sfLma__Lead__c from sfLma__License__c where sfLma__Subscriber_Org_ID__c IN :subscriberOrgIds];   
Map<Id,Id> mapOrgIdToLeadId = new Map<Id,Id>();
    for (sfLma__License__c l:licenses)
        mapOrgIdToLeadId.put(l.sfLma__Subscriber_Org_ID__c, l.sfLma__Lead__c);

// Loop through each successful SignupRequest made and update corresponding Leads
for (signupRequest
        //Check signup request status change
        if (s.status == 'Success')
            Lead leadToUpdate = new Lead(id=mapOrgIdToLeadId.get(s.createdOrgId));
   = s.Country;
            leadToUpdate.Current_Solution__c = s.Current_Solution__c;
            leadToUpdate.Industry = s.Indusrty__c;
            leadToUpdate.NumberOfEmployees = (Integer)s.Employees__c;
            leadToUpdate.Phone = s.Phone__c;
            leadToUpdate.Product_Interest__c = s.Product_Interest__c;
            leadToUpdate.State = s.State__c;
            leadToUpdate.Street = s.Street__c;
            leadToUpdate.Title = s.Title__c;
            leadToUpdate.City = s.City__c;
            leadToUpdate.PostalCode = s.Postal_Code__c;

    // Update the records
    if(leadsToUpdate.size() > 0)
        update leadsToUpdate;

That’s it, you’re done! This feature is available with the Summer ’13 release. You can view the summer ’13 release notes here.

A special thanks to Naren Raghavan, Sebastiano Costanzo, Scott Effler and William Yeh, from the ISV Technical Enablement team, for putting together this documentation.

You can follow me on twitter @randyscase

tagged , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • Mitesh Sura

    Some clarification. Is this only for OEM partners who offer trial force? How about ISV who uses just the LMO?

    Currently SF will not create license record when prospects installs the app in their Sandbox and it becomes difficult to manage at that point. Can that be addressed with Sign Up API?

    Thank you for you time.


  • Paul Fox

    Thanks, this was really helpful.

    How do you write a test for this considering the createdOrgId and Status fields are not writeable?

    • Raees

      I have followed same one written test class and trigger after insert,update however facing issue status is not changing “In progress” to “Success” automatically. If I deactivate this trigger then status working fine.
      Can anybody help me out?


      • Dave Moroku

        It sounds like your trigger is failing or the SignupRequest is failing (perhaps missing parameters). The dumb thing is that there’s no way to tell because Force won’t log error messages in the ‘after update’ trigger in any place that you can see them (it runs under a different context.) Also, as I discovered today, you can’t send emails from the after update trigger either so you’re faced with a ‘guess and test’ development methodology.

        A possible test protocol would be to change your trigger to be ‘before delete’ in the short term. This will narrow down the issue. If the SignupRequest completes successfully, you can then test you trigger by deleting the SignupRequest – since this is executed in your Sys Admin context, you can use the debug log. Once it’s working, add ‘after update’ back to the trigger.

        he advantage of using ‘before delete’ is that all of the fields of the SignupRequest are populated whereas ‘after insert’ they are not.

        I’ve been pounding my head off my keyboard for some time with this process so good luck!

  • Seb Costanzo

    Good question, I believe the only way is to use data that already exists in the org. This is usually not allowed nor recommended but might be needed in cases such as this. So, you will need to create some signup request records and then write the Apex test to cover the trigger. You can find more info here: .
    Signup Request permissions (via API but should apply to Apex too) : .

    • Tom Maple

      Seb, can you be more specific about the Test class code that will work to cover the trigger? In the test I created, when trying to update a SignupRequest record, I get “System.TypeException: DML operation UPDATE not allowed on SignupRequest”. How else would you possibly get the ‘after update’ trigger to fire?

      • Moroku

        Hi Tom, I just had some feedback from the SF team about how to manage this and eventually got 100% test coverage (though it’s a little hokey).

        First, make your trigger after insert as well as after update.

        Then in your trigger test for the criteria you want i.e. status == success, createdOrgID != null (which should;t be true after insert but should after the final update)

        This then allows you test case to run after insert and the test code shows coverage.

        Having to insert additional, bogus code into production simply to fool the Test Coverage Gremlins in that you are doing the right thing is Not A Good Thing.

  • Dave Moroku

    Having the same problem as Tom here. It seems impossible to test an update trigger on a SignupRequest since we can’t force an update on the record.
    An insert of a new record will lead to an update (eventually) as OrgId and Status are changed by SF but the automated test coverage detection rules don’t allow this to count as a test.
    Of course this means we also can’t promote into production…

  • Raees

    Hello Team,

    Thank you for enabling this feature.
    We have already using LMA installed in production instance. Now, we are going to start Signup Request object. We have written trigger for the same and deployed into production. We are inserting record through web-service(SOAP UI). However, it is showing error code T-003 on Signup record means template no approved. But that template Id is approved by Salesforce.
    So, my question is how we can manage and solve this type of issue?

    Thanks & Regards,

    • Varun Chaddha

      Hi- I’m also having same T-003 error code. I wonder if there is separate way to get Template ID approved by salesforce for Signup Requests? Did you had any luck in resolving this issue?

  • Kunal Shah

    Can someone help me with the code for the web form? How does the page on my website interact with Salesforce to create a Signup Request record in the ISV Business Org?