As the title says, is it possible to get dynamically get the creation date of custom metadata using Apex?

I would like to know, for instance, which fields were created since 03/01/2016, in which objects, without having to manually look into each object's description page.

3 Answers 3


You can find this information in the Setup Audit Trail. The Section column will have a value of Custom Objects. The rows you want will look something like:

Date            3/14/2016 1:28:43 PM MDT
User            [email protected]
Action          Created custom field FieldName (Text) on Custom Object
Section         Custom Objects
Delegate User
  • This is very useful. But isn't there a way to do this using Apex? Commented Mar 14, 2016 at 20:10
  • 1
    @RenatoOliveira You would probably need to install something to manipulate the Metadata API. Why does it need to be Apex?
    – Adrian Larson
    Commented Mar 14, 2016 at 20:12
  • It would be easier for what I wanted to achieve. Simple as that. Having the ability to query for user-specific changes, for example, in a query. But I guess that log would also do. Commented Mar 14, 2016 at 20:16

You could also use Tooling API Objects to get the Created Date of metadata (not all but some supported ones).

For example, executing a sample query in query editor tab of developer console will be like this.

select DeveloperName, CreatedDate from CustomObject where CreatedDate < TODAY

NOTE: Make sure to check the 'Use Tooling API' checkbox beside 'Execute' button.

  • 2
    Um, CreatedDate > Today will always be false, for any record in any system.
    – Adrian Larson
    Commented Mar 14, 2016 at 20:44

To query the Tooling API via Apex to gather these results, see Salesforce Field Auditor for a full solution and the following code snippet for a general method of sending the query, deserializing the JSON response into a map and then using the map to access the individual data points.

        // QUERY 2 - Get the Id, InlineHelpText, CreatedBy.Name, LastModified.Name, CreatedDate, LastModifiedDate on all CUSTOM fields of this object
        req.setEndpoint(instanceName + '/services/data/v48.0/tooling/query/?q=Select+Id,InlineHelpText,CreatedDate,LastModifiedDate,LastModifiedBy.Name,CreatedBy.Name+from+CustomField+Where+TableEnumOrId=\'' + objectId + '\'');
        HttpResponse res2 = h.send(req); 
        responseBody = res2.getBody();
        // Deserialize the response into an object and create a FieldAuditData object for each record in our response
        Map<String, Object> payload2 = (Map<String, Object>)JSON.deserializeUntyped(responseBody);
        for (Object data : (List<Object>)payload2.get('records'))
            Map<String, Object> record = (Map<String, Object>)data;
            Object createdByObject = (Object)record.get('CreatedBy');
            Map<String, Object> createdByMap = (Map<String, Object>)createdByObject;
            String createdName = (String) createdByMap.get('Name');
            Object lastModifiedByObject = (Object)record.get('LastModifiedBy');
            Map<String, Object> LastModifiedByMap = (Map<String, Object>)LastModifiedByObject;
            String lastModifiedName = (String) LastModifiedByMap.get('Name');
            // the ID for Custom field adds 3 characters to the end so they get removed here so that it matches its record from FieldDefinition query
            String fieldId = (String)record.get('Id');
            String formalizedFieldId = objectId + '.' + fieldId.substring(0,fieldId.length() - 3);
                FieldAuditData f = results.get(formalizedFieldId);
                f.helpText = (String)record.get('InlineHelpText');
                f.createdDate = formatDateTime((String)record.get('CreatedDate'));
                f.lastModifiedDate = formatDateTime((String)record.get('LastModifiedDate'));
                f.lastModifiedBy = lastModifiedName;
                f.createdBy = createdName;

You must log in to answer this question.

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