I am building an API which will be serviced by Lambda functions but I need these to be asynchronous so rather than connecting the API-Gateway directly to the Lambda function
I am just speculating (haven't tried this myself), but I think you are not sending the message correctly...
Based on AWS's documentation here (http://docs.aws.amazon.com/sns/latest/api/API_Publish.html), you need to POST the message in what seems to be the application/x-www-form-urlencoded
encoding like this:
POST http://sns.us-west-2.amazonaws.com/ HTTP/1.1
...
Action=Publish
&Message=%7B%22default%22%3A%22This+is+the+default+Message%22%2C%22APNS_SANDBOX%22%3A%22%7B+%5C%22aps%5C%22+%3A+%7B+%5C%22alert%5C%22+%3A+%5C%22You+have+got+email.%5C%22%2C+%5C%22badge%5C%22+%3A+9%2C%5C%22sound%5C%22+%3A%5C%22default%5C%22%7D%7D%22%7D
&TargetArn=arn%3Aaws%3Asns%3Aus-west-2%3A803981987763%3Aendpoint%2FAPNS_SANDBOX%2Fpushapp%2F98e9ced9-f136-3893-9d60-776547eafebb
&SignatureMethod=HmacSHA256
&AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE
&SignatureVersion=2
&Version=2010-03-31
&Signature=vmqc4XRupKAxsDAdN4j4Ayw5LQljXMps3kss4bkDfCk%3D
&Timestamp=2013-07-18T22%3A44%3A09.452Z
&MessageStructure=json
That is, the message body looks the way a browser would encode form data. Your message can be JSON formatted, but still needs to be encoded as if it was a form field (an awkward analogy :)).
Also, based on the common parameters documentation (http://docs.aws.amazon.com/sns/latest/api/CommonParameters.html), you have a number of additional required fields (the usual access key, signature and so on).
You have not specified what language you are writing your API Gateway in - there might be an AWS SDK for it that you can use, instead of trying to manually compose the REST requests).