you are right - using a hidden field is the "normal" way for this.
Don't forget to add this field to the "updatedControls" on your ajax manager.
The Ajax manager has a client event - OnResponseEnd - there you can trigger the results.
Last not least (to be totally OT) - if you only need to exchange simple values (no need for controls on the server) an async ajax webservice call is much "smaller". You can pass a string - and !!! return a string.
Of course not like a direct return value assignement - xx=CallTheService(strParam) does not work.
Instead you pass a "SuccessFunction" which gets called on return.
Here I posted a sample about this approach:
PS: if one of my posts answered your qestion - please "mark as answer"