The marked answer is correct here, but I can't comment on it. There's a couple "bugs" in it. The following changes were made to make it work with the object/array that gets exported when using field_group_load_field_group()
Specifically, I changed this line:
'format' => array('type' => 'fieldset'),
To:
'format' => array('type' => $group['format_type']),
And:
foreach ($group['fields'] as $field_name) {
To:
foreach ($group['children'] as $field_name) {
The final code:
/**
* Create a field group.
*
* The field_group module does not come with an API that can be used by other
* modules. This method fakes a Drupal new group form submission to create the
* new group.
*
* @param array $group
*/
function _field_group_create_group(array $group) {
drupal_load('module', 'field_group');
module_load_include('inc', 'field_group', 'field_group.field_ui');
$defaults = array(
'entity_type' => 'node',
'mode' => 'form',
'parent' => '',
// TODO: default to heaviest weight
'weight' => '',
'format' => array('type' => $group['format_type']),
'fields' => array()
);
$group = $group + $defaults;
$form = array(
'#entity_type' => $group['entity_type'],
'#bundle' => $group['bundle'],
'#view_mode' => $group['mode'],
'#groups' => array()
);
$form_state = array(
'values' => array(
'fields' => array(
'_add_new_group' => array(
'group_name' => $group['group_name'],
'label' => $group['label'],
'parent' => $group['parent'],
'parent_wrapper' => array('hidden_name' => '_add_new_group'),
'weight' => $group['weight'],
'format' => $group['format'],
)
)
)
);
foreach ($group['children'] as $field_name) {
$form_state['values']['fields'][$field_name] = array(
'parent' => '_add_new_group',
);
}
field_group_field_overview_submit($form, $form_state);
}