The UserTerritory record does not support direct DML with Apex, as it states in the docs.

I am trying to delete using Partner SOAP API but unable to delete the records. My code is below :

HTTP h = new HTTP();
HTTPRequest req = new HTTPRequest();
req.setHeader('Content-Type', 'text/xml');
req.setHeader('SOAPAction', 'delete');            
String b = '<?xml version="1.0" encoding="UTF-8"?>';
b += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:urn="urn:partner.soap.sforce.com">';
b += '<soapenv:Header>';
b += '<ns1:SessionHeader soapenv:mustUnderstand="0" xmlns:ns1="http://partner.soap.sforce.com">';
b += '<ns1:sessionId>' + UserInfo.getSessionId() + '</ns1:sessionId>';
b += '</ns1:SessionHeader>';
b += '</soapenv:Header>';
b += '<soapenv:Body>';
b += '<urn:delete>';
b += '<urn:ids><b>a6En0000000ZiIN</b></urn:ids>';
b += '</urn:delete>';
b += '</soapenv:Body>';
b += '</soapenv:Envelope>';            
HTTPResponse resp = h.send(req);

Please help if someone know about it.

  • So you are making an API call to a different org? If so, a lot easier to just do this with REST API, IMO.
    – pchittum
    Oct 20, 2015 at 9:30
  • If @Peter is correct and you are making this call to a different org, you would also need to use a sessionId from a login into that org. The SessionId from UserInfo.getSessionId() will only work for your current org.
    – martin
    Oct 20, 2015 at 9:42
  • @GhanshyamSaini, I see that you are new to SFSE and to this type of Q&A forum. I'd strongly suggest you read the help topic on how to ask questions to get an idea of how you can improve your question. salesforce.stackexchange.com/help/how-to-ask
    – pchittum
    Oct 20, 2015 at 9:45
  • 1
    No @Peter. This api call on same org to delete the userTerritory records. Oct 20, 2015 at 9:45
  • In that instance you don't need the API. Or rather, Apex already has a data persistence layer built in.
    – pchittum
    Oct 20, 2015 at 9:46

2 Answers 2


It could be that the endpoint is wrong. In my experience, the /m/ uri is always for the metadata api. In the partner api WSDL for my org, the service endpoint is:


Where you would replace test with the location of your instance. ie for me, ap1 or soon to be ap4. Ideally this shouldn't be hard-coded in case you also find yourself facing an org split.

  • I changed two lines and it works fine -b += '<urn:ids>a6En0000000EiIN</urn:ids>'; Oct 20, 2015 at 9:59
  • I changed two lines and working fine - b += '<urn:ids>a6En0000000EiIN</urn:ids>'; and req.setEndpoint('https://<instance>.salesforce.com/services/Soap/u/29.0'); thanks @martin Oct 20, 2015 at 10:04
  • @GhanshyamSaini good to hear. Glad I could help.
    – martin
    Oct 20, 2015 at 10:04

It is not clear what language this API call is being written for. But based on the presence of System.debug() it leads me to believe that this is Apex.

And if it is Apex, then the first question to ask is this:

Why are you making an API call to the SOAP API?

Apex as a programming language is tightly coupled with the data persistence layer. Such that the APIs for accessing the db are already present. So if I want to delete a single record in Apex it is as easy as this:

UserTerritory myUT = new UserTerritory();
myThingy.Id = 'a6En0000000ZiIN';
delete myUT;

That is literally all you need, however that's not very good code.

I common mistake of newer developers is to take a snippet of code like that and stick it in a for loop like this:

//this is really bad code, do not ever do this in real life: 
for (Id idToDelete: myListOfIds){
  UserTerritory myUT = new UserTerritory();
  myUT.Id = idToDelete;
  delete myUT; 
//end of really bad code you should never use

Trouble is, Apex has a concept called a governor limit. The multi tenant architecture loans your environment some resources to do some work. Governor limits are the way the platform meters your work to ensure you don't overuse those resources. To what you will normally want to do is what we call "bulkify". Even if today, it seems you would only want to delete one of these records, it isn't a bad idea to bulkify now, and it is really just a tiny amount of extra work for you (and the platform).

List<UserTerritory> recsToDelete = new List<UserTerritory>();

for (Id idToDelete: myListOfIds){
  UserTerritory myUT = new UserTerritory();
  myUT.Id = idToDelete;

delete recsToDelete;

A lot more easy than making a call to a SOAP API, isn't it?

And it also doesn't consume any of your org's API requests per 24 hours.

Another way to think of it is this: Apex is the way we surface our APIs internally to developers in a Salesforce environment (we also call Salesforce environments "orgs"). If the code needs to run in a Salesforce org on a Salesforce org, that is Apex. And Apex being tightly coupled with the environment has a lot of helpers to make it easy to interact with the database.

There are a number of additional things that you will want to do of course to handle exceptions. But the very nature of this question tells me that you're pretty new to Apex and to Salesforce. I'd suggest taking some time to learn the environment using the trailhead learning tool. There is one learning trail that deals specifically with Apex and the database. That would be a good place to start.

  • UserTerritory object not allowed to DML so can't delete with apex. See documentation on sObjects That Don’t Support DML Operations. So we need to call api and can do this. Oct 23, 2015 at 7:46
  • That was the context information I was missing in your question above. I taken the liberty of updating the question to reflect this.
    – pchittum
    Oct 23, 2015 at 8:53

You must log in to answer this question.

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