Field API, Field Attach API, Field Instance API, Field CRUD API OR Schema API? I'm in my final semester for my degree in Computer Science, and we've been tasked with creating a project management system using Drupal. I thought this was great at first, we easily created a proof of concept using already built modules. And then I attempted to code. 

Basic Idea:
We thought about defining our own schema for entities, but the company needs a dynamic way of defining and sharing fields (like the entity / field API already does), so we decided to stick with the built in Entity / Field API. 

Entity types would be things like request, project, task, etc...

Fields would be things like select lists, questions for the request form (that could be transferred over to a project once the request was approved), and other text fields needed for the project.

I was thinking that using the field API to start with some of the needed select lists (that the admin can add/update/delete default values to) would work fine - because I defined these with the UI thinking man this is easy. Select lists such as legacy company, products, and other short lists related to telecom. But I cannot programmatically define a select list field with predefined values. How can I do this? I've googled, and searched, and followed this great article, but it does not delve much into select lists, and how to define default values, or any of the $options available for a select list [and neither do the API docs, they do not tell what values should be used, or even the default widget types].

Am I going about this all wrong? Maybe I should just create some good old crud classes and be done with it. The only problem with this is that it would be extremely difficult to make the system as dynamic as they want, or would it?
Personally I wouldn't bother doing it yourself, Drupal has it all set up for you and it's just a matter of working out the format it wants data in and you can use all the goodness of the entity/field system.

The following function is one I use all the time. Given an existing entity type, field name and bundle it will produce the code you need to run to create said field instance:

function __export_field($entity_type, $field_name, $bundle_name) {
  $info_config = field_info_field($field_name);
  $info_instance = field_info_instance($entity_type, $field_name, $bundle_name);
  unset($info_config['id']);
  unset($info_instance['id'], $info_instance['field_id']);
  include_once DRUPAL_ROOT . '/includes/utility.inc';
  $output = "field_create_field(" . drupal_var_export($info_config) . ");\n";
  $output .= "field_create_instance(" . drupal_var_export($info_instance) . ");";
  drupal_set_message("&lt;textarea rows=30 style=\"width: 100%;\"&gt;". $output .'&lt;/textarea&gt;');
}


For example, if you have a field called field_image attached to the standard article content type, you would export both the field creation code, and field instance creation code with this:

__export_field('node', 'field_image', 'article');


The code prints out to the standard drupal message area and can just be copied and pasted to wherever you need it.

For your specific needs, the value list for a select widget is added in the settings part of the field array, under allowed_values:

$field = array(
  'translatable' =&gt; '0',
  'entity_types' =&gt; array(),
  'settings' =&gt; array(
    'allowed_values' =&gt; array(
      1 =&gt; 'First Choice',
      2 =&gt; 'Second Choice'
    )
  ),
  // etc...
);


If you haven't seen it already check out the Examples module, there's loads of example code in there to help with entity/field manipulation.