Returning or use form data using a hook?

If you want to allow users to “manipulate it before it gets sent off to the API” I would suggest using a filter instead of an action.

if ( ! empty( $p['form_data'] ) ) {
    parse_str( $p['form_data'], $fd );
    if ( ! empty( $fd['list-id'] ) ) {
        // Create and store the variables needed to add a new subscriber        
        $email  = false;
        $lid  = empty( $fd['list-id'] );
        $api  = 'api_key';
        $mv = array();
        $optin  = 'true';

        // Add custom hook, to capture user submitted data
        $p['form_data'] = apply_filters( 'get_form_data', $p['form_data'] );
    }
}

This will be the code that enables users to manipulate this data.

function catch_user_data( $data ) {
    $user_email = $data['email'];
    update_user_meta( '1' , 'user_email', $user_email );
    return str_replace( 'find-something', 'replace-it', $data );
}
add_filter( 'get_form_data' , 'catch_user_data' );

More reading:
http://codex.wordpress.org/Function_Reference/apply_filters
http://codex.wordpress.org/Glossary#Action
http://codex.wordpress.org/Glossary#Filter