Can the Metadata API Be Invoked from Apex?

Question
While researching Metadata API usage within Apex, I found conflicting information about whether it is possible to invoke Salesforce’s own Metadata API directly from Apex. Some sources claim it is strictly forbidden, while others suggest it can be done using specific techniques.
A Force.com MVP once stated:
“You can’t call out to any Salesforce web services from within Salesforce. You can only call out to external web services.”
However, there are reports that CRUD-based Metadata API calls (such as creating custom objects or fields) can be executed within Apex. Given this uncertainty, I would like to know:
Has anyone successfully invoked the Metadata API from Apex?
If so, what is the process for authenticating and performing a create()
operation?
What are the limitations of this approach?
Answer
Yes, it is possible to invoke the Metadata API from Apex, but with certain limitations. You can perform basic CRUD operations like creating custom objects and fields, but Apex cannot handle zipped metadata packages, which are required for many other Metadata API functions.
Apex also cannot directly consume the Metadata API WSDL via WSDL2APEX
due to schema type extensions. Instead, developers typically send raw SOAP messages using HTTPRequest
.
Code Example: Creating a Custom Object Using the Metadata API
HTTP h = new HTTP();
HTTPRequest req = new HTTPRequest();
req.setMethod('POST');
req.setHeader('Content-Type', 'text/xml');
req.setHeader('SOAPAction', 'create');
String b = '<?xml version="1.0" encoding="UTF-8"?>';
b += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
b += '<soapenv:Header>';
b += '<ns1:SessionHeader soapenv:mustUnderstand="0" xmlns:ns1="http://soap.sforce.com/2006/04/metadata">';
b += '<ns1:sessionId>' + UserInfo.getSessionId() + '</ns1:sessionId>';
b += '</ns1:SessionHeader>';
b += '</soapenv:Header>';
b += '<soapenv:Body>';
b += '<create xmlns="http://soap.sforce.com/2006/04/metadata">';
b += '<metadata xsi:type="ns2:CustomObject" xmlns:ns2="http://soap.sforce.com/2006/04/metadata">';
b += '<fullName>sample__c</fullName>';
b += '<deploymentStatus>Deployed</deploymentStatus>';
b += '<description>Created by the Metadata API</description>';
b += '<enableActivities>true</enableActivities>';
b += '<label>Sample Object</label>';
b += '<nameField>';
b += '<displayFormat>AN-{0000}</displayFormat>';
b += '<label>Sample__c Name</label>';
b += '<type>AutoNumber</type>';
b += '</nameField>';
b += '<pluralLabel>Sample Objects</pluralLabel>';
b += '<sharingModel>ReadWrite</sharingModel>';
b += '</metadata>';
b += '</create>';
b += '</soapenv:Body>';
b += '</soapenv:Envelope>';
req.setBody(b);
req.setCompressed(false);
req.setEndpoint('https://na12-api.salesforce.com/services/Soap/m/25.0'); // Update for your instance
HTTPResponse resp = h.send(req);
System.debug(resp.getBody());
Code Explanation
- HTTP Request Setup:
Creates anHTTPRequest
and sets it toPOST
.
Sets the required headers, includingSOAPAction
andContent-Type
. - SOAP Message Construction:
The XML request body (b
) contains a SOAP envelope.
The<SessionHeader>
includes the session ID (UserInfo.getSessionId()
) to authenticate the request. - Sending the Request:
The request is sent to the Metadata API endpoint (https://na12-api.salesforce.com/services/Soap/m/25.0
), which must be updated for the correct Salesforce instance.
The response is logged usingSystem.debug(resp.getBody());
.
Considerations and Limitations
While this approach works for CRUD operations, there are some challenges:
Asynchronous Nature: Metadata API calls do not complete immediately, so additional logic is needed to check the request status.
WSDL Limitations: WSDL2APEX
does not work well with the Metadata API due to its use of a super type (Metadata
). This requires sending raw SOAP messages instead.
Salesforce Restrictions: Salesforce does not officially support calling its own APIs from Apex, meaning future updates could break this approach.
A workaround is to integrate this logic into a Visualforce page with an actionPoller
to monitor operation success. Despite its limitations, this proves that invoking the Metadata API from within Apex is indeed possible for simple CRUD operations.
Real-Time Project-Based Salesforce Course to Kick Start Your Career
Our Salesforce course is structured to provide a comprehensive understanding of the Salesforce platform, equipping you with the essential skills to excel in the CRM industry. The curriculum covers key modules such as Salesforce Admin, Developer, and AI, blending theoretical knowledge with hands-on experience. Through real-world projects and interactive exercises, you’ll gain the expertise needed to solve complex business challenges using Salesforce solutions. Our expert instructors ensure you develop both technical proficiency and industry-relevant insights to succeed in the Salesforce ecosystem.
Beyond technical training, our Salesforce Training in Florida offers personalized mentorship, certification support, and interview preparation to boost your career opportunities. You’ll gain access to extensive study resources, hands-on project work, and continuous guidance throughout your learning journey. By the end of the program, you’ll be fully prepared for certification exams and equipped with real-world problem-solving skills that employers seek. Kick-start your Salesforce career today—enroll in a Free Demo now!