There're two parts: Content-Type of the data sent and Accept header for content version/format negotiation.
By default grape accepts all content-types that you throw at it, so you can do forms, JSON, whatever. If it has a parser it will parse the body and offer the API the data inside params. A lot of this behavior is implemented in Rack, not even in Grape, so I think the best solution is to just shortcut it. I did it in a before block.
If I am missing a scenario, add a spec that fails to your example and lets try to iterate on it until all the issues are resolved. I am not against supporting such behavior out of the box in Grape, we'll have to see what the DSL looks like.