Field API, Field Attach API, Field Instance API, Field CRUD API OR Schema API?
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.