Is it possible to know if a profile is custom via API?
Like an attribute "profile.isCustom".
Best Answer
The short answer is no.
Neither the sObject API nor the Metadata API includes the 'custom' boolean value in their footprint. We're discussing whether or not to include it in a future release, in fact, someone just asked me yesterday whether anyone actually uses this checkbox.
You could create a list view in the setup UI that filters based on the 'custom' checkbox and then use that list to enumerate your SOQL (where name <> "System Administrator"). But name is a difficult attribute to use for profiles in general to determine whether it's custom since it's possible for standard and custom profiles to have similar looking names (no __c to distinguish).
In the API, profile.name is actually the profile's label and doesn't follow normal API field behaviors. That label is used to generate the file name during a retrieve in the Metadata API but you'll notice that by using Daniel's package.xml definition to return all profiles, that the standard profiles are all predefined (e.g. System Administrator = Admin.profile) without any special 'standard' designation.
In the API, the profile Name attribute is also used to return the label of the profile. Unlike permission sets where we expose an API 'Name' attribute, profile only returns the equivalent of a label (SELECT Id,Label,Name, Profile.Name FROM PermissionSet WHERE isOwnedByProfile=true).
Sure, you can use the Metadata API. You want the create() call. Here's the sample xml to define the custom object from the documentation:
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<deploymentStatus>Deployed</deploymentStatus>
<description>just a test object with one field for eclipse ide testing</description>
<fields>
<fullName>Comments__c</fullName>
<description>add your comments about this object here</description>
<inlineHelpText>This field contains comments made about this object</inlineHelpText>
<label>Comments</label>
<length>32000</length>
<type>LongTextArea</type>
<visibleLines>30</visibleLines>
</fields>
<label>MyFirstObject</label>
<nameField>
<label>MyFirstObject Name</label>
<type>Text</type>
</nameField>
<pluralLabel>MyFirstObjects</pluralLabel>
<sharingModel>ReadWrite</sharingModel>
</CustomObject>
This field determines whether a permission set is a custom one or if
it is parented by a profile. This is made possible because for every
profile, there is one underlying permission set. That way, permissions
layer equally across permission sets without having to treat a profile
differently.
So, if you want to find the CRUD permissions of a profile you can do something like this:
SELECT Id, SObjectType, PermissionsRead, PermissionsCreate
FROM ObjectPermissions
WHERE parentid in (select id from permissionset where
PermissionSet.Profile.Name = 'System Administrator')
Best Answer
The short answer is no.
Neither the sObject API nor the Metadata API includes the 'custom' boolean value in their footprint. We're discussing whether or not to include it in a future release, in fact, someone just asked me yesterday whether anyone actually uses this checkbox.
You could create a list view in the setup UI that filters based on the 'custom' checkbox and then use that list to enumerate your SOQL (where name <> "System Administrator"). But name is a difficult attribute to use for profiles in general to determine whether it's custom since it's possible for standard and custom profiles to have similar looking names (no __c to distinguish).
In the API, profile.name is actually the profile's label and doesn't follow normal API field behaviors. That label is used to generate the file name during a retrieve in the Metadata API but you'll notice that by using Daniel's package.xml definition to return all profiles, that the standard profiles are all predefined (e.g. System Administrator = Admin.profile) without any special 'standard' designation.
In the API, the profile Name attribute is also used to return the label of the profile. Unlike permission sets where we expose an API 'Name' attribute, profile only returns the equivalent of a label (SELECT Id,Label,Name, Profile.Name FROM PermissionSet WHERE isOwnedByProfile=true).