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
Davi D11801Davi D11801 

How to retrieve sandbox name using apex code?

While developing in Apex, I need to retrieve sandbox name in my code.  How do I do this in Apex?  Thanks in advance.
Sai Ram ASai Ram A
Organization myOrg = [Select o.WebToCaseDefaultOrigin, o.UsesStartDateAsFiscalYearName, o.UiSkin, o.TrialExpirationDate, o.SystemModstamp, o.Street, o.State, o.ReceivesInfoEmails, o.ReceivesAdminInfoEmails, o.PrimaryContact, o.PreferencesRequireOpportunityProducts, o.PostalCode, o.Phone, o.OrganizationType, o.Name, o.MonthlyPageViewsUsed, o.MonthlyPageViewsEntitlement, o.LastModifiedDate, o.LastModifiedById, o.LanguageLocaleKey, o.Id, o.FiscalYearStartMonth, o.Fax, o.Division, o.DefaultPricebookAccess, o.DefaultOpportunityAccess, o.DefaultLocaleSidKey, o.DefaultLeadAccess, o.DefaultContactAccess, o.DefaultCaseAccess, o.DefaultCampaignAccess, o.DefaultCalendarAccess, o.DefaultAccountAccess, o.CreatedDate, o.CreatedById, o.Country, o.ComplianceBccEmail, o.City From Organization o];

That will retrieve you the organization details in Apex Code.
FYI-https://www.salesforce.com/us/developer/docs/pages/Content/pages_variables_global_organization.htm

Thanks
BLearn
YuchenYuchen
It seems that "o.Name" will only give you the Organization Name instead of Sandbox Name. One approach to retrieve the Sandbox name is to get it through the username for that Sandbox, because Salesforce will always append the Sandbox name in the end of the username, so you can try this:

UserInfo.getUserName().substringAfterLast('.');
 
EnreecoEnreeco
You can also get the Server Instance from the Organization Object (https://www.salesforce.com/developer/docs/api/Content/sforce_api_objects_organization.htm), this could help in detecting the sandbox (unless all your sandboxes are in the same instance )
asish1989asish1989
Please go through this link 
http://salesforceworld4u.blogspot.in/2015/12/how-to-get-sandbox-name-in-apex.html
Jake BackuesJake Backues
It is possible with the SandboxPostCopy interface to get the Sandbox Name: https://www.mstsolutions.com/technical/run-script-after-sandbox-creation-and-refresh/
global class SandboxPostRefresh_AC implements SandboxPostCopy { 

    global void runApexClass(SandboxContext context) { 

        System.debug(context.organizationId()); 

        System.debug(context.sandboxId()); 

        System.debug(context.sandboxName()); 
    } 
}

 
Richard Brescia 1Richard Brescia 1

I did quite a bit of research on this and was unable to find an exceptable answer to this.  It was either getting from the Username or store it in Custom Settings/Metadata.  So this was my answer to this question by creating a public method you can store in your global routines for use where you need it.  It will dynamically pull from the currently available system information.

    public static String HostStr {
        get {
            if(HostStr == null) {
                Organization myOrg = [Select Id, Name From Organization];
                String myHostStr = System.Url.getSalesforceBaseUrl().getHost();
                Integer sandboxTag = myHostStr.indexOf(myOrg.Name.toLowerCase() + '--');
                if (sandboxTag == 0) sandboxTag = myOrg.Name.length() + 2; else sandboxTag = 0;
                
                //parse the string for the Sandbox name
                string returnstr = '';
                while (myHostStr.mid(sandboxTag,1).isAlpha()) {
                    returnstr += myHostStr.mid(sandboxTag,1);
                    sandboxTag += 1;
                }
                HostStr = (returnstr==myOrg.Name.toLowerCase() + 'portal'?myOrg.Name.toLowerCase():returnstr);
            }
            return HostStr;
        }
        set;
    }

I hope that someone else finds this to be helpful.

NZArchitectNZArchitect

Sai Ram A - this will not give what is required. it will return the company name.

Richard Brescia 1 - This code gives so much mis-information in 1 answer, not acceptable at all, overly heavy and and just generally weird, and does not answer the question, or provide a correct result.

So if this was my "My Domain" : "myCo--myBox.my.salesforce.com" then the above code would return "myCo", which is not what the question asked for. And what a very elaborate way to get the production  sub domain.

It should return myBox

If you want to know if it is a Sandbox, use "SELECT IsSandbox FROM Organization"

myHostStr.indexOf(myOrg.Name.toLowerCase() + '--'); will almost always return -1, because the org name is unlikely to be in the baseUrl
also immediately following you try to write th index straight back to 0 with if (sandboxTag == 0) sandboxTag = myOrg.Name.length() + 2; else sandboxTag = 0;

then a while loop to finally find the sandbox name OMG, it works but seriously.

Here is my rewrite of your code, the assumption is no "--" or "." in your my domain:

and that org info is helpful in otherways.

string hostStr='Production';
Organization myOrg = [Select Id, Name, instanceName, isSandbox From Organization];
system.debug(myOrg);
if(myOrg.isSandbox){
    String myHostStr = System.Url.getSalesforceBaseUrl().getHost();
    Integer startIndex = myHostStr.indexOf('--')+2;
    Integer endIndex = myHostStr.indexOf('.');
    hostStr = myHostStr.mid(startIndex,endIndex-startIndex);
}
return hostStr;
Which by the way is quite readable.

but even better because we don't need to query the org & utilising the getter:

String myHostStr = System.Url.getSalesforceBaseUrl().getHost();
Integer startIndex = myHostStr.indexOf('--')+2;
if(startIndex != 1){ //because if prod then -1 is returned  +2
    Integer endIndex = myHostStr.indexOf('.');
    return myHostStr.mid(startIndex,endIndex-startIndex);
}else
    return 'Production';
}

global class SandboxPostRefresh_AC implements SandboxPostCopy { code is nice option if you are that well organised.
use this option only if those values get stored in custom hierarchy settings, and if on every refresh you remember to run the apex at refresh time, because that apex cannot be instantiated during normal runtime.

the simpliest fastest answer is:

UserInfo.getUserName().substringAfterLast('.');
which works if you don't change the username. Best practice assumes you don't change the username.

so I like Yuchen's answer the best.

 

For others trying to organise community urls use a network query:

list<Network> communities = [SELECT Id, Name FROM Network WHERE status = 'Live'];
for(Network comm : communities){
    string community = comm.Name.toLowerCase();
    string loginURL = Network.getLoginUrl(comm.id);
    integer pointer = loginURL.indexOf(community);
    string domain = loginURL.left(pointer-1);
    string baseUrl = domain+'/'+community+'/';
    system.debug(community);
    system.debug(pointer);
    system.debug(LoginUrl);
    system.debug(domain);
    system.debug(baseUrl);
}

Fabien TaillonFabien Taillon
There is now an official solution that is out with the Spring' 22 release (https://help.salesforce.com/s/articleView?id=release-notes.rn_apex_domain_classes.htm&type=5&release=236).
You can use the new getSandboxName() method:
System.Domain d = System.DomainParser.parse(URL.getOrgDomainUrl());
System.debug(d.getSandboxName());
You can get more information about this new method in the Apex Reference Guide here (https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_class_System_Domain.htm#apex_System_Domain_getSandboxName).
There are also so other new and useful methods like getMyDomainName().