custom service respond me : 401 Unauthorized: Missing required argument foo I have this custom service: 

function zbs_services_resources() {
  return array(
    'productQuestionForm' =&gt; array(
      'actions' =&gt; array(
        'send' =&gt; array(
          'help' =&gt; 'save a FOO entity via send form',
          'file' =&gt; array('file' =&gt; 'inc', 'module' =&gt; 'zbs'),
          'callback' =&gt; '_zbs_productQuestionForm_create',
          //'access arguments' =&gt; array('note resource create'),
          //'access arguments append' =&gt; FALSE,
          'args' =&gt; array(
              array(
                'name' =&gt; 'foo',
                'type' =&gt; 'struct',
                'description' =&gt; 'The FOO to create',
                'source' =&gt; 'data',
                'optional' =&gt; false,
              ),
            ),
        ),
      )
    )

  );
}


And this little jQuery code in a simple html test file: 

$.ajax({
    url: "/rest1/productQuestionForm/send",
    headers: { 'Content-Type': 'application/json','X-CSRF-Token':'MY_WORKING_TOKEN' },
    success: function (res) {
      alert("success");
      console.log(res);
    },
    data : {
      'foo' : 'pippo',
      "type":"page",
      "title":"Page submitted via entity JSON REST",
      "body": {
          "value": "&lt;p&gt;test&lt;/p&gt;\n",
          "format": "filtered_html"
      }
    },
    type: 'post',
    dataType: 'json',
  });


But when I load the simple test html page I see this in developer suite for the POST url:  


  401 Unauthorized: Missing required argument foo


Where am I doing wrong?
The problem is the mismatch between the data type you define for foo ('struct'), and what you pass with JavaScript (a string). If you are going to pass a string, then your hook implementation should be the following one.

function zbs_services_resources() {
  return array(
    'productQuestionForm' =&gt; array(
      'actions' =&gt; array(
        'send' =&gt; array(
          'help' =&gt; 'save a FOO entity via send form',
          'file' =&gt; array('file' =&gt; 'inc', 'module' =&gt; 'zbs'),
          'callback' =&gt; '_zbs_productQuestionForm_create',
          //'access arguments' =&gt; array('note resource create'),
          //'access arguments append' =&gt; FALSE,
          'args' =&gt; array(
              array(
                'name' =&gt; 'foo',
                'type' =&gt; 'string',
                'description' =&gt; 'The FOO to create',
                'source' =&gt; 'data',
                'optional' =&gt; false,
              ),
            ),
        ),
      )
    )
  );
}


'source' =&gt; 'data' is perfectly fine, as shown in the example at hook_services_resources(), but notice what the documentation says.


  In the case of 'data' unless you put things in an array, you will get passed to your functions. 'source' =&gt; array('data' =&gt; 'nid') will pass them off as a single variable; 'source' =&gt; array('data') will give you all argument values to each argument.