I had a discussion with a friend the other day about if hold is signified with a=sendonly or a=recvonly, which led me to revisiting the RFC to confirm, so here’s an overview of how “Call Hold” works in SIP.
By the Book
According to RFC 6337 a user can hold calls by sending a new SDP offer in an established session (Re-INVITE on active call), with an SDP payload of a=sendonly for each media stream the user want’s to hold.
The SIP Switch / PBX / UAS replies with an updated SDP where each media stream’s SDP contains a=recvonly.
So it’s both, depending on which leg you’re looking at.
In Common Practice
When a UAC puts a call in hold, it does so by sending a SIP re-INVITE, updating the SDP to include the attribute line “sendonly”

See the bottom line of the SDP is a=sendonly ? That’s denoting the call is to be put on hold,
If the call hold was sucesful the UAS sends back a 200 Ok, with the SDP attribute set to recvonly

The a=recvonly denotes the call has been held.
To retrieve the call another SIP re-invite is sent by the UAC, this time setting the media attribute back to sendrecv

If sucesful a 200 OK is sent by the UAS with the a=sendrecv also set.