How to Get Record Type ID in Salesforce Apex (Complete Guide for Beginners)

If you have worked in Salesforce Apex for some time, I am sure you have faced this situation.

You are writing Apex code. Maybe you are creating a new Account record. Or maybe you are writing trigger logic. And suddenly, you realize that you need to assign a specific Record Type to the record.

And then the big question comes: How do I get the Record Type ID in Apex?

Should you hardcode it?
Should you write a SOQL query?
Should you use Schema methods?

In this article, I will explain how to get record type ID in Salesforce Apex. By the end of this guide, you will clearly understand:

  • What Record Type ID is
  • Why do we need it in Apex
  • All possible ways to get it
  • Which method should you use in real projects
  • And which methods you should avoid

Let’s start from the basics.

What Is a Record Type in Salesforce?

A Record Type in Salesforce is a feature that allows you to divide records of the same object into different categories based on business needs.

Even though all records belong to the same object, they may behave differently depending on the Record Type assigned to them.

For example, in the Account object, a company may want to manage Customer Accounts differently from Partner Accounts. Both are Accounts, but their business processes, page layouts, and picklist values may differ.

In Salesforce, Record Types are used to control:

  • Different business processes
  • Different picklist values
  • Different page layouts
  • Different user experiences

For example, in the Account object, you may have:

  • Customer Account
  • Partner Account
  • Distributor Account

When you create a Record Type, Salesforce internally generates a unique 18-character ID for it. This ID is how Salesforce identifies the record type in the database.

Even if two Record Types have similar names in different orgs, their IDs will always be different. That is why copying an ID from one org and using it in another org does not work.

Why Do We Need Record Type ID in Apex?

There are many real-world scenarios where you need Record Type ID:

  • When Creating Records in Apex If you want to create an Account with a specific Record Type, you must assign the RecordTypeId field.
  • When Writing Trigger Logic You may want different logic for different Record Types. For example:
    • If Record Type is Customer → Apply discount logic
    • If Record Type is Partner → Skip discount logic
  • When writing SOQL queries, you may want to filter records based on Record Type.
  • When Writing Test Classes You must create records with proper Record Types in test methods.

In Apex code, when we create or update a record and want to assign a Record Type, we cannot use a label such as “Salesforce Technologies”. Salesforce does not understand labels in Apex logic.

It only understands the RecordTypeId field, which must contain the 18-character ID. Therefore, understanding how to dynamically fetch this ID is very important for writing production-ready Apex code.

Record Type ID in Salesforce Apex

Get Record Type ID in Salesforce Apex

Below, I will explain the different methods for retrieving the record type ID from the Salesforce object, including the output and code details.

Method 1: Get Record Type ID Using a SOQL Query in Apex

This is the best approach, and it’s a great starting point if you’re new to Salesforce Apex. You simply query the RecordType object.

public class Demo {   

public static void RecordType() {

RecordType rt = [
SELECT Id, DeveloperName, SObjectType
FROM RecordType
WHERE SObjectType = 'Employees__c'
AND DeveloperName = 'Salesforce_Technologies'
LIMIT 1
];

Id employeeRtId = rt.Id;

System.debug('SObject Type: ' + rt.SObjectType);
System.debug('Developer Name: ' + rt.DeveloperName);
System.debug('Record Type ID: ' + employeeRtId);
}
}

In this code, we are querying the standard object called RecordType. It stores information about all Record Types across all objects.

In the WHERE condition, we are filtering by SObjectType = ‘Employees__c’. This means we only want Record Types that belong to the Employees object.

Next, we filter by DeveloperName = ‘Salesforce_Technologies’. The Developer Name is the API name of the Record Type. The label can be changed by an admin, but the Developer Name usually remains fixed.

We use LIMIT 1 because Developer Name is unique per object. We expect only one record to be returned.

Finally, we use System.debug statements to print the values in the debug log. These debug statements are very useful when you are testing in the Developer Console.

Get Record Type ID in Salesforce Apex

Although this method works correctly, it consumes one SOQL query. Salesforce limits SOQL queries to 100 per transaction.

If your trigger already uses many queries, adding one more just for Record Type ID is not efficient. In large systems, optimizing SOQL queries is crucial to avoid governor limit errors.

Method 2: Using Schema Describe with Developer Name in Apex

Now, let us look at the best method that does not use SOQL.

public class Demo {   
   
    public static void RecordType() {

       Schema.RecordTypeInfo rtInfo = Schema.SObjectType.Employees__c
    .getRecordTypeInfosByDeveloperName()
    .get('Salesforce_Technologies');

	if (rtInfo != null) {
    
    Id employeeRtId = rtInfo.getRecordTypeId();
    
    System.debug('Developer Name: ' + rtInfo.getDeveloperName());
    System.debug('Record Type ID: ' + employeeRtId);
    System.debug('Is Active: ' + rtInfo.isActive());
    
	} else {
    	System.debug('Record Type not found.');
	}
    }
}

In this code, we are not querying the database. Instead, we are using something called Schema Describe. The Schema Describe API allows us to access metadata about objects and fields without using SOQL.

First, Schema.SObjectType.Employees__c provides metadata about the Employees object. This is not querying data. It is just accessing the object definition.

Next, getRecordTypeInfosByDeveloperName() returns a Map. A Map is a collection of key-value pairs. In this case:

  • Key = Developer Name (String)
  • Value = RecordTypeInfo object

We then use .get(‘Salesforce_Technologies’) to fetch the specific RecordTypeInfo object from the Map.

The RecordTypeInfo object contains many useful methods, such as:

  • getRecordTypeId()
  • getName()
  • isActive()
  • isAvailable()

We check if rtInfo is not null before using it. This is very important. If the Developer Name is wrong or the Record Type does not exist in that org, rtInfo will be null.

If we do not check, the code will throw a NullPointerException. This method is efficient, safe, and does not consume SOQL. Salesforce internally caches this metadata during the transaction.

Schema Describe with Developer Name in Salesforce Apex

Method 3: Get Record Type ID Dynamically in Apex

Now let’s say you’re building a utility class or a generic helper where you don’t know the object type at compile time.

You need to look up the Record Type ID dynamically at runtime. This is where Schema.getGlobalDescribe() comes in.

The method Schema.getGlobalDescribe() returns a Map that contains all objects in your Salesforce org.

In simple words, it gives you metadata information about every standard and custom object available in that org. Once you have that Map, you can fetch any object dynamically using its API name.

Let us now carefully review the code.

public class Demo {   
   
    public static Id getRecordTypeId(String objectApiName, String developerName) {
    
    System.debug('Received Object API Name: ' + objectApiName);
    System.debug('Received Developer Name: ' + developerName);
    
    Map<String, Schema.SObjectType> globalDescribeMap = Schema.getGlobalDescribe();
    
    Schema.SObjectType sObjType = globalDescribeMap.get(objectApiName);
    
    if (sObjType == null) {
        System.debug('Invalid Object API Name. Object not found.');
        return null;
    }
    
    Schema.DescribeSObjectResult describeResult = sObjType.getDescribe();
    
    Map<String, Schema.RecordTypeInfo> rtInfoMap = 
        describeResult.getRecordTypeInfosByDeveloperName();
    
    Schema.RecordTypeInfo rtInfo = rtInfoMap.get(developerName);
    
    if (rtInfo != null) {
        System.debug('Record Type Found.');
        System.debug('Record Type ID: ' + rtInfo.getRecordTypeId());
        return rtInfo.getRecordTypeId();
    } else {
        System.debug('Record Type not found for given Developer Name.');
        return null;
    }
  }
} 
Get Record Type ID Dynamically in Salesforce Apex

Method 4: Build a Reusable Record Type Utility Class in Apex

If you’re working in a large org with multiple Record Types across multiple objects, you don’t want to scatter describe calls everywhere. A utility class that caches the results is the cleanest solution.

public class RecordTypeUtil {

    // Cache structure:
    // Key = Object API Name
    // Value = Map of Developer Name and Record Type ID
    private static Map<String, Map<String, Id>> cachedRecordTypeIds = 
        new Map<String, Map<String, Id>>();

    public static Id getRecordTypeId(String objectApiName, String developerName) {
        
        System.debug('Requested Object: ' + objectApiName);
        System.debug('Requested Developer Name: ' + developerName);
        
        // Load cache only if not already loaded
        if (!cachedRecordTypeIds.containsKey(objectApiName)) {
            
            System.debug('Loading Record Types into cache...');
            
            Map<String, Schema.RecordTypeInfo> rtMap =
                Schema.getGlobalDescribe()
                .get(objectApiName)
                .getDescribe()
                .getRecordTypeInfosByDeveloperName();
            
            Map<String, Id> rtIds = new Map<String, Id>();
            
            for (String rtName : rtMap.keySet()) {
                rtIds.put(rtName, rtMap.get(rtName).getRecordTypeId());
            }
            
            cachedRecordTypeIds.put(objectApiName, rtIds);
        }
        
        Id result = cachedRecordTypeIds.get(objectApiName).get(developerName);
        
        System.debug('Returning Record Type ID from cache: ' + result);
        
        return result;
    }
}

This class uses a static Map called cachedRecordTypeIds. Static means it stays in memory during the entire transaction.

The structure of this Map is:

Object Name → (Developer Name → Record Type ID)

When the method is called for the first time on an object, it loads all the object’s Record Types and stores them in memory.

From that point onward, if the method is called again for the same object, it does not call describe again. It directly returns the value from memory.

This improves performance because:

  • Describe call runs only once per object
  • Future calls are faster
  • Resource usage is reduced

This is a very clean and scalable approach.

How to call it anywhere in your org:

Id oppRecordTypeId = RecordTypeUtil.getRecordTypeId('Opportunity', 'New_Business');
Id caseRecordTypeId = RecordTypeUtil.getRecordTypeId('Case', 'Service_Request');

System.debug('Opportunity RT ID: ' + oppRecordTypeId);
System.debug('Case RT ID: ' + caseRecordTypeId);

Method 5: Getting Other Record Type Info in Apex(Name, Label, Developer Name)

Sometimes you have the Record Type ID but need to know the label or Developer Name. Here’s how to flip it around using getRecordTypeInfosById():

public class Demo {   
   
    public static void RecordType() {

       Id rtId = '0125i000000iafzAAA';

        Map<Id, Schema.RecordTypeInfo> rtInfoById = Schema.SObjectType.Employees__c.getRecordTypeInfosById();
            
        
        Schema.RecordTypeInfo rtInfo = rtInfoById.get(rtId);
        
        if (rtInfo != null) {
            
            System.debug('Label: ' + rtInfo.getName());
            System.debug('Developer Name: ' + rtInfo.getDeveloperName());
            System.debug('Is Active: ' + rtInfo.isActive());
            
        } else {
        System.debug('Record Type not found for given ID');
    }
  }
}

This is super useful when you’re debugging or when you have a Record Type ID from a record and need to branch logic based on the Developer Name.

Getting Other Record Type Info in Salesforce Apex

Which Method Should You Use to Get Record Type ID in Apex?

Here’s how I think about it:

  • Quick SOQL query → fine for Developer Console scripts, not for production Apex code
  • getRecordTypeInfosByName() → avoid it; too fragile since labels can change
  • getRecordTypeInfosByDeveloperName() → use this as your default for single-object lookups
  • Dynamic Apex with getGlobalDescribe() → use this when the object type isn’t known at compile time
  • Utility class with caching → use this in any large-scale project with multiple Record Types

The key rule I follow: never hardcode a Record Type ID, and never use the label if the Developer Name is available. Developer Names are stable, no-SOQL, and make your code portable across environments.

Quick Recap of Useful Methods on RecordTypeInfo

Once you have a Schema.RecordTypeInfo object, here are the methods you’ll use most often:

  • .getRecordTypeId() — returns the 18-character Record Type ID
  • .getName() — returns the display label
  • .getDeveloperName() — returns the API/Developer Name
  • .isActive() — returns true if the Record Type is currently active
  • .isAvailable() — returns true if the Record Type is available to the running user
  • .isDefaultRecordTypeMapping() — returns true if this is the default Record Type

Conclusion

I hope you have an idea of why Record Type ID is important in Salesforce Apex and why we should never hardcode it.

In this article, we explored different ways to fetch Record Type ID using SOQL, Schema methods, dynamic Apex, and utility classes. By using Developer Name and proper null checks, you can write safe, reusable, and production-ready Apex code.

You may like to read:

Agentforce in Salesforce

DOWNLOAD FREE AGENTFORCE EBOOK

Start with AgentForce in Salesforce. Create your first agent and deploy to your Salesforce Org.

Salesforce flows complete guide

FREE SALESFORCE FLOW EBOOK

Learn how to work with flows in Salesforce with 5 different real time examples.