Create a SharePoint Site (SPWeb) using REST in SPD 2013 Workflow


I have been struggling with an issue for several days, and it’s one I’ve been trying to solve for an upcoming SharePoint Saturday presentation. That issue is creating SharePoint sub sites/SPWebs automatically via the “Call HTTP Web Service” action in SharePoint Designer 2013 workflow. There were several sources of information that ultimately provided the solution, so I will be sure to credit those folks in this article.

There are several steps which are required to make this happen, and the coolest part is; this will work both on-premise and in Office 365/SharePoint Online!

The solution I was trying to provide was:

  1. Provide users a list for requesting project sites
  2. Provide an automated workflow to request approval for the requested site
  3. If approved, create the site automatically with the requested settings
  4. Provide the requesting user with an email notifying them of the approval

The List

The list is a simple Custom list created via the browser, although I did utilize InfoPath to customize the look & feel a little by providing prettier (read: Metro/Win8) colors, fonts and a picture button. The important pieces are obviously the Title, the Url, the Description and the Reason for Request. Using the business case that these are end-users requesting sites, you can see how understanding the reason for this site would be valuable.
IPForm

The Workflow

Obviously this is where all of the magic will happen. And of course this was the most challenging piece to get right. Special thank you shout out to Fabian Williams, Jim Bob Howard, Patrick Curran and Chris Givens – if it weren’t for the Twitter conversation we shared, I probably wouldn’t have figured this out! At least not without pulling a lot of my hair out…

In any case, here is how the workflow is configured:
FullWorkflow

Now to break down a few very important pieces:

The REST Url

The important piece here is the /_api/web/webinfos/add at the end of the URL, this is the REST endpoint we want to hit.
WFRestUrl

The Approval Task – just an example, do whatever you want here

Yes I am sending the task to the creator, this was for demo purposes only. In the real world this would be a good place to query and send to the users’ manager.
WFTaskBody

The Dictionary Variable

The Accept and Content-Type values should both be “application/json;odata=verbose”
WFVarDictionary

The Metadata Variable

The Value here should be “SP.WebInfoCreationInformation”
WFVarMetadata

The JSON Request Variable

These values should be:

  • Url | String | CurrentItem:WebUrl
  • Title | String | CurrentItem:WebTitle
  • Description | String | CurrentItem:WebDescription
  • Language | Integer | 1033
  • WebTemplate | String | sts#0
  • UseUniquePermissions | String | false
  • __metadata | Dictionary | Variable:Metadata

Note: The 3 that are pulling from CurrentItem are pulling from the list fields, just choose the right values here based on your list.

WFVarJsonRequest

The Parameters Variable

This is important, the value of the Parameters variable needs to be the JsonRequest dictionary variable you created previously.
WFVarParameters

The Call HTTP Web Service Action

Make sure you select the appropriate variables for each of the different pieces here…
WFVarCallHTTPWS

At the end of workflow I also send a few emails, one to myself to provide the JSON Result and another to the requestor to notify them of their new site.

Another note, it is NOT necessary to build the dictionary variables inside of the App Step; only the Call HTTP Web Service action needs to be there. I just happened to place mine in that block.

App Permissions

The most important piece to making this work is actually the App Permissions. In SharePoint 2010 we could use an Impersonation Step to actually mimic the “Full Control” rights that we’re going to give our workflow, but in 2013 that’s a little different. There is some great documentation on doing this, but essentially the steps are:

  1. Activate the “Workflow can use app permissions” Web-scoped feature
  2. Grant full control permissions to the workflow

Activating the feature is pretty simple, just navigate to Site Settings, then Site Features (not Site Collection Features). Find the feature and click Activate.
AppPermissionsFeature

Granting full control permissions to the workflow is a little more involved.

  1. Go to Site Settings
  2. Under Users and Permissions, click Site App Permissions
  3. Copy the client section of the App Identifier, which is after the “|” and before the “@”
  4. Go to the Grant permission to an app page, which must be manually navigated to by typing http://SiteUrl/_layouts/15/appinv.aspx
  5. GrantPermissionsToAnApp

  6. Paste the App Id that you copied in the previous step and click Lookup
  7. In the Permissions Request, paste the following XML.
    Note: These values are literal, no need to modify the sharepoint/content/sitecollection values!
  8. <AppPermissionRequests>
        <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="FullControl" />
    </AppPermissionRequests>
    
  9. Click Create, and then Trust It – this will allow the workflow to have full control of the site

Once that’s done, create an item, which should trigger your workflow (assuming you set yours to run on item creation), and upon receiving approval – you should have a new Site created in your Site Collection!
NewSubsite

And finally, as always I like to give credit where due. Most of what I used was found in this blog by Roger Eriksen. However, I couldn’t quite get it to work with his steps, so I noticed a Twitter conversation between Fabian and the others mentioned above – and after following his thread I was able to have my “Ah ha” moment when he mentioned that he had to wrap one variable inside another to get {‘__metadata’:{‘type’:’SP.List’} to come out properly. This was my issue, and by putting the whole JsonRequest variable inside the Parameters variable, my problem was solved. One last shout out is due to Matt Gibson, one of my very knowledgeable co-workers at Blue Chip; he gave me my first REST/Workflow challenge that ultimately inspired me to do this. Thanks Gibz!

Another day in ShareParadise!

35 thoughts on “Create a SharePoint Site (SPWeb) using REST in SPD 2013 Workflow

  1. Felix Weichert

    Hey Ryan,
    nais Block at first, thx 4.
    I have some Problems get things done in Office365. I did all steps like shown but for testing, i leave the Approval Task away. When i create a new item, the workflow runs smooth and finsh without any problems, but no site was created. Did u have any idea wheere the failure could be?

    Greetings and thx
    Felix

    • Ryan Dennis

      Hi Felix,
      Most of the trouble I had with getting it to work was around all of the dictionary variables and making sure they were constructed properly. Make sure those are perfect, and beyond that – the App Permissions MUST be done correctly as the workflow will need full control.
      Good luck!
      Ryan

  2. Sivaharan Rajkumar

    Hi Ryan,

    I think i got a simalar error as the one described above. Just comparing with what Roger Erikson has done ii think the Call HTTP service is slightly different. It seems you guys have swapped some of the dictionaries.

    Kind Regards,
    Siv

      • Asim Nadeem

        Thanks for reply, Now i follow all the steps and workflow completed successfully, but no site is created.

        Then i print “responseCode” variable in log from HTTP web service call. and the output is “Unauthorized” .

        Any idea why responseCode is Unauthorized.

      • Linda van Bakkum

        hi, I’m a bit new to this. But I read your blog and I’m wondering were your use the RESTurl. I see the variable declared and set, but I don’t see that you use the restUrl anywhere else. Which Url do I need to pass in the call? Do I need to add _api/web/infos/add after the url in the call?

        Thanks,

        Linda

  3. Ryan Dennis

    Asim,

    Based on the fact that you’re seeing “Unauthorized”, it seems like a permissions issue somewhere along the line. Make sure you have activated the app step permissions feature and also that you have added an entry for the AppPermissionRequests to look exactly like what is listed above in the article.
    This was what got me. I kept putting in the actual site url i.e. ‘http://mycompany.sharepoint.com’ but it should in fact be entered just like above with ‘http://sharepoint/content/sitecollection/web’.

    Good luck!
    RD

  4. spdirection

    Thank you for your post, Is there a way to have the sub site created under a specific site. For example the workflow would be on the top level site and I already have three sites under the top level; company A, Company B, Company C. I want to fill out a form with info and one piece of info would be the Company that this sub site should go under (Company B). So the workflow runs and instead of adding the site under the home it adds it as a sub site under Company B. Is that possible and can you point me in the right direction if it is?

    Thank you,

    • Ryan Dennis

      Thanks for your comment! Off the top of my head and without testing this scenario, the two things that come to mind are:

      1. App Permissions – you may need to change this to grant full control to the whole site collection, this way the workflow has the permissions it needs to create webs within the scope of the entire SPSite.
      2. The REST Url – you will probably want/need to dynamically build the URL based on the values in the form. That is, instead of just hardcoding the value to create the SPWeb under the root of the site collection, I would think you’d want to change the URL of the parent web depending on the Company value of the form.

      Hopefully those make sense, good luck!
      Ryan

  5. Jörg Purucker

    Thanks for the great post regarding this poor documented subject (REST actions with SPD Workflows). I kept getting “Unauthorized” errors in SharePoint Online until I changed the Scope attribute to “http://sharepoint/content/sitecollection” (without “web”).

  6. yvonne8927

    Workflow is working great! Thanks very much.
    How do I go about when I want the workflow to use a custom site-template?

    Kind regards
    Yvonne

  7. Fabian Ackeret

    Hi Ryan

    I’m using O365 but as a response content I always get this message: {“error”:{“code”:”-1, Microsoft.Data.OData.ODataException”,”message”:{“lang”:”en-US”,”value”:”An unexpected ‘PrimitiveValue’ node was found when reading from the JSON reader. A ‘StartObject’ node was expected.”}}}

    I’m pretty sure everything is like described in your post (except the approval wf). However, it still doesn’t work. Do you have an idea?

  8. thboot (@thboot)

    Ryan my workflow completes but the response code is ‘Bad Request” and the site is never created. I was able to get around unauthorized from the comments mentioned above. Any thoughts on Bad request? Thanks in advance!

  9. Shafaqat Ali

    I was having bad request issue and the problem was wrong template id for the web, I created a site and saved as template and used template id for new sites, everything was working fine, I made some changes in the template and deleted the old site template and updated the new one but workflow was still pointing to old template and I got 404 error, I updated the workflow with new id and it started working fine.

  10. ljt1227

    Great post, thanks! Question: is it possible to run this workflow on site collection “A” and have it create a new sub-site on site collection “B” of SharePoint Online? I have it running fine as long as all new sites are created on site collection “A”, but when I try to have it build a new site on a different site collection, I get “unauthorized”. I did go through and set the app permissions for Workflow on the other site collection “B” as instructed, but this did not solve the issue. What else could be causing the “unauthorized” result? Thanks.

  11. Fran Guay (@FranceCrjangel)

    I am trying to modify this to create a Group on a site if a item (Project Name) is entered into a list. aka, New project creates a new Project Approval Group based on the Project Name. I am getting Response Code1: BadRequest, with no other error on the workflow. What do I need to modify in this code to do this? Having a hard time determining what the api is for this.

  12. Brendan Weitzman

    Thanks Ryan, this is a great tutorial! On the offchance you’re still monitoring these comments (or someone else here has encountered the issue I’m having)… I’ve got this workflow up and running, and added an additional check at the beginning to validate if the requested URL exists. If the site is already there, the workflow runs a loop to increment the URL until the GET returns NotFound. So – no reason for the error “The web site address {URL} is already in use.”

    Problem is, on a small percentage of requests that error is still firing. The workflow sends me full debug details of every request, and for these ones that are erroring out everything appears to be working right until the POST call to create the site. And here’s the real kicker: When I inspect the site contents, the site that was NotFound at the start of the workflow and errored out for being already in use at the end of it has been created by the workflow!

    I’m going to keep gathering data and see if I can find a common thread between these glitchy occurrences, but wanted to see if anyone has ideas before I pull out what’s left of my hair.

  13. Raghuram Yaramati

    Hi,
    I am adding items to the list using Http POST.

    I am getting Badd request error when i check logs i found below mentioned exception

    URL ENd is _api/web/lists/getbyid(guid’4DD47937-277A-44D7-9785-11866594784F’)/Items

    Created metadata dictionary as type string SP.Data.ListnameListItem
    another dictionary named as Parameters with items
    __metadata value assigned above created metadata
    & Title some title name

    OData Exception Reading Entity Body: Microsoft.Data.OData.ODataException: Found a node of type ‘PrimitiveValue’ when starting to read the property value; however, a node of type ‘StartObject’ was expected. The ‘__metadata’ property must have an object value.

    Original error: Microsoft.SharePoint.Client.InvalidClientQueryException: Found a node of type ‘PrimitiveValue’ when starting to read the property value; however, a node of type ‘StartObject’ was expected. The ‘__metadata’ property must have an object value.

  14. Christopher Roux (@ChristepherRoux)

    Please help, am getting this error all the time:

    {“error”:{“code”:”-1, Microsoft.Data.OData.ODataException”,”message”:{“lang”:”en-US”,”value”:”The property ‘URL’ does not exist on type ‘SP.WebInfoCreationInformation’. Make sure to only use property names that are defined by the type.”}}}
    {“type”:”SP.WebInfoCreationInformation”}

Leave a comment