Is it possible to get a list of key prefixes for all Metadata types in Salesforce org. Not the standard objects or custom objects, but Metadata types e.g. AccountSettings, ApexPage, CustomObject etc (listed here: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_types_list.htm). Thank you!

1 Answer 1


You can't generally get the key prefixes of some objects (those that are not describe-able), but I've devised a workaround that actually (mosty) does just this. Here's the code:


<apex:page controller="describe">
        #output {
            display: table;
        #output div {
            display: table-row;
        #output div span {
            display: table-cell;
            padding: 2px;
    var temp, parent;
    function processResults(data) {
        var index = 0, row, key, value;
        if(data) {
            while(index < data.validKeys.length) {
                row = document.createElement("div");
                key = document.createElement("span");
                value = document.createElement("span");
        } else {
            data = { nextValue: 0 };
        if(data.nextValue!=null) {
            {!$RemoteAction.describe.getList}(data.nextValue, processResults);
        if(data.nextValue==null) {
            data.nextValue = 262144;
        document.getElementById("progress").value = data.nextValue;
        row = document.getElementById("valuepercent");
        if(row.firstChild) row.removeChild(row.firstChild);
        key = parseInt(data.nextValue)/262144;
        key = Math.floor(key*10000)/100;
    window.addEventListener("load", function() { temp = document.getElementById("output"); parent = temp.parentNode; temp.parentNode.removeChild(temp); processResults(null); }, true);

    <progress value="0" max="262143" id="progress"/>
    <span id="valuepercent"></span>
    <div id="output">




global class describe {
    global class KeyValuePair {
        global String key, value;
        global KeyValuePair(String k, String v) {
            key = k;
            value = v;
    global class Result {
        global Integer nextValue;
        global KeyValuePair[] validKeys;

        global Result() {
            validKeys = new KeyValuePair[0];

    @RemoteAction global static Result getList(Integer firstIndex) {
        Result result = new Result();
        String[] base62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        Integer a = (firstIndex & 258048) >> 12, b = (firstIndex & 4032) >> 6, c = (firstIndex & 63);
        while(Limits.getCpuTime()<1000) {
            try {
                String key = base62[a]+base62[b]+base62[c];
                Id value = Id.valueOf(key+'000000000000');
                result.validKeys.add(new KeyValuePair(key, String.valueOf(value.getSObjectType())));
            } catch(Exception e) { }
            if(c>62) {
                c = 0;
            if(b>62) {
                b = 0;
            if(a>62) {
                result.nextValue = null;
            result.nextValue = (a<<12)+(b<<6)+c;
        return result;

This code basically brute-forces every key prefix by way of Id.getSObjectType() to describe every single object in the system. It provides a very basic table that allows you to find any type of object that has a stable key prefix. It even includes some tables that I'm pretty sure we shouldn't be able to know about but have nevertheless been exposed to us.

Note: AccountSettings is a specific example of something that apparently doesn't have any key prefix at all. These are probably stored in some specific table that is a meta-table (contains a large number of settings that are all lumped into one). I would guess that the Organization table probably contains this information, but there's no documentation of how this data is organized. Other tables, like CustomObject, are actually aliased to a different type; for example, CustomObject is internally called CustomEntityDefinition.

You must log in to answer this question.

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