function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion

Detect Sandbox in apex

Recently, I was writing some classes that needed to detect if the org they were in was a sandbox or not and determine which endpoint to call accordingly. Since there isn's an isSandbox method in Apex, I had to create my own. This will work in visualforce controllers/extensions and from standard classes. You can read the full details at


Code as follows


public String currentPod { 
            String server;
            if (ApexPages.currentPage() != null){ //called from VF page
            		server = ApexPages.currentPage().getHeaders().get('X-Salesforce-Forwarded-To');
            } else { //called via standard class
            		server = URL.getSalesforceBaseUrl().getHost();
            if ( server != null && server.length() > 0){
                server = server.substring(0 ,server.indexOf('.'));
            return server ; 

   public Boolean isSandbox {
            String pod = currentPod();
            if (pod != null && pod.length() > 0 && pod.toUpperCase().startsWith('C')){
                return true;
            return false;

What I've done in the past is create a formula field on the object I'm working with in apex and then I can access it at anytime, plus it is dynamic to sandbox or production servers.  The only time this won't work is if you are using My Domain since it is getting the server name, not your custom domain.


So in the Task scenario where I am creating an email alert about a new task, I have added a field called Server_URL to the Activity table with the following formula:



left($Api.Enterprise_Server_URL_25 , FIND("/", $Api.Enterprise_Server_URL_25, 9))


and then, in either my VF email template or the email object I create in apex, I can reference the to get the URL. 


Hope that helps.

If you need the Server URL in a non-request context peice of Apex code (Trigger, Batch Job, ETC) than I suggest using Custom Settings. You create a custom setting, and you can call it "Server Config" or something similar. Then, one time only, when you first create the environment, you manaully populate a string field on the Custom Setting and call it something like "Server URL" where you paste the URL from the address bar in your browser.

Then in all your custom Apex code, you can just retrieve the Server URL from your Custom Setting.


I think you missunderstand the use cases here.


One, getting the server url alone doesn't necessarily help you determine if you are in a sandbox or not. Using $Api.Enterprise_Server_URL_25 will not give you the same results across environments. For example, for standard/portal users you will get but while in sites you get The latter will not give you the pod name. 


Two, I wanted to get away from using Custom Settings because the admin had to go back and change the custom setting after every sandbox refresh and for each developer sandbox created. Thats a task I wanted to eliminate.




Thanks for posting.  A question for you... will this still work when an org is using the "my domain" feature?  I am thinking it would not, because the host returned would be the custom sub domain, but who knows.


FYI, I extended this approach to make it work even if the org is using the "my domain" feature... and to tell you what edition it is.  I posted the following recipe with all the code:


Hope that is helpful.

Use this : system.debug(''+UserInfo.getUserName().substringAfterLast('.com'));

for more info :
Sam KamenskySam Kamensky
UPDATE: As of Spring 2016 you can use the isSandbox field on the Organization object in order to tell whether or not the organization is a sandbox org or not
Salesforce DeveloperSalesforce Developer
Yes, you can query something like: 
[SELECT Id, IsSandbox  FROM Organization]