I'm going to add an answer as a wiki. I think this is something that will change, certainly screenshots will change over time and should be updated as such rather than new answers added.
To enable Binary output from a lambda you have to disable "Use Lambda Proxy Integration" on the Integration Request page:

By changing this, it will knock out what you'd normally expect in the event object of your Lambda (easily accessible path parameters, body parameters etc), so you'll need to alter the Mapping Templates on the same page of the Integration Request.
For my own needs, I set the Request body passthrough to be When there are no templates defined (recommended) with a Content-Type of: application/pdf and a template of:
## See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
## This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
#if($foreach.hasNext),#end
#end
},
"requestContext" : {
"authorizer" : {
#foreach($key in $context.authorizer.keySet())
"$key" : "$util.escapeJavaScript($context.authorizer.get($key))"
#if($foreach.hasNext),#end
#end
},
"account-id" : "$context.identity.accountId",
"api-id" : "$context.apiId",
"api-key" : "$context.identity.apiKey",
"authorizer-principal-id" : "$context.authorizer.principalId",
"caller" : "$context.identity.caller",
"cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
"cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
"cognito-identity-id" : "$context.identity.cognitoIdentityId",
"cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
"http-method" : "$context.httpMethod",
"stage" : "$context.stage",
"source-ip" : "$context.identity.sourceIp",
"user" : "$context.identity.user",
"user-agent" : "$context.identity.userAgent",
"user-arn" : "$context.identity.userArn",
"request-id" : "$context.requestId",
"resource-id" : "$context.resourceId",
"resource-path" : "$context.resourcePath"
}
}

This should now pass through the things you would expect in the event parameter of your Lambda. You might need to change the names within the Mapping Template to match your needs, or within your code in your Lambda.
Your endpoint will still fail to output a PDF correctly though.
We should add a response to the Method Response, for my own purposes, I am adding a 200 response. I add a Response Header of "Content-Type" and a Response Body of "application/pdf" with an Model of "Empty".

At this point, if your Lambda is outputting: return pdfBuffer.toString('base64') you should start seeing the correct headers and base64 body within your curl/postman request:
curl -i --output - --location --request GET 'https://example.com/document-generation/soa/pdf/unitresult/1cc1eece-cf4e-e811-80e5-00155d210d92/2a174f81-a055-e511-80c2-00155d220a0c' \
--header 'Content-Type: application/pdf' \
--header 'Accept: application/pdf' \
--header 'Authorization: abc123
HTTP/2 200
content-type: application/pdf
content-length: 32502
date: Wed, 26 May 2021 09:58:15 GMT
x-amzn-requestid: blah blah
x-amz-apigw-id: anonymous
x-amzn-trace-id: all kinds of things
via: other stuff
x-amz-cf-pop: letters
x-cache: Miss from cloudfront
x-amz-cf-pop: letters
x-amz-cf-id: stuff
"JVBERi0xLjQKJdPr6..."
We now need to look at the Integration Response settings page, which is now enabled due to disabling Use Lambda Proxy Integration.
A 200 Method response status should already be setup, expand that and set the "Content handling" to Convert to binary (if needed). Expand Header Mappings and add a Response header of "Content-Type" with a Mapping value of "'application/pdf'".

If you rerun your curl or Postman request, you should now receive your PDF correctly.
If you need to access the PDF from a website on a different domain, you'll need to allow for CORS. To do this, you'll need to add an OPTIONS method to your PDF serving resource.
In the Integration Request for your new OPTIONS method, you'll need to set it to Mock.
In the Method Response for your OPTIONS method, you'll need to add:
- Access-Control-Allow-Headers
- Access-Control-Allow-Methods
- Access-Control-Allow-Origin
to the Response Headers for 200.
In the Integration Response for your OPTIONS method you'll need to add the following Header Mappings:
Response Header: Access-Control-Allow-Headers
Mapping value: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'
Response Header: Access-Control-Allow-Methods
Mapping value: 'OPTIONS, GET'
Response Header: Access-Control-Allow-Origin
Mapping value: '*'
If your PDF endpoint is using something other than GET. you will need to change the Mapping Value for Access-Control-Allow-Methods to match the method type e.g. 'OPTIONS, POST' if your pdf is served from a POST method.