Six headers are mandatory in every SIP request: Via (records the path and carries the transaction branch), From and To (the logical parties, with tags), Call-ID (a unique call identifier), CSeq (a sequence number plus method) and Max-Forwards (a hop limit). Together Call-ID, From-tag and To-tag identify a dialog.
The six mandatory headers
RFC 3261 requires six header fields in every request. Via traces the route the request took and tells responses how to get back. From and To identify the logical originator and target of the request. Call-ID is a globally unique token shared by all messages of one call. CSeq orders requests within a dialog and names the method. Max-Forwards is a decrementing hop counter that prevents loops. Omit any of these and the message is invalid.
| Header | Purpose |
|---|---|
| Via | Records each hop; responses follow it back. Carries the transaction branch |
| From | Logical originator; carries a tag |
| To | Logical recipient; gains a tag in the response |
| Call-ID | Globally unique identifier for the whole call |
| CSeq | Sequence number + method; orders in-dialog requests |
| Max-Forwards | Hop limit (typically 70); prevents routing loops |
Via and the branch parameter
Each proxy that forwards a request inserts its own Via header at the top, building a stack that responses walk back down — a response is routed purely by following the Via list, so it retraces the request's path. The Via branch parameter identifies the transaction; since RFC 3261 it must begin with the fixed magic cookie z9hG4bK, which marks the branch as globally unique and RFC 3261-compliant. Matching responses and retransmissions to the right transaction depends on this value.
Tags, dialogs and transactions
Dialog identity is assembled from three pieces: the Call-ID plus the tag in From and the tag in To. The caller sets the From-tag when it sends the INVITE; the callee adds the To-tag in its response, and at that point the dialog is fully identified for both sides. Every later in-dialog request (re-INVITE, BYE) carries all three so it is associated with the right call. Transactions, by contrast, are matched by the Via branch and the method — a finer granularity than the dialog.
| Scope | Identified by |
|---|---|
| Dialog (the call) | Call-ID + From-tag + To-tag |
| Transaction (request+responses) | Via branch + request method |
| Request ordering in a dialog | CSeq number (increments per request) |
Contact, routing and other common headers
Beyond the mandatory six, several headers shape routing and capability. Contact gives a direct URI at which the sender can be reached for future requests — critical in REGISTER and in dialog-establishing messages. Record-Route lets a proxy stay in the signalling path for the whole dialog, and Route directs subsequent requests through those proxies. Expires bounds a registration or subscription. Allow, Supported and Require advertise and negotiate capabilities and extensions. Content-Type and Content-Length describe the body (usually SDP).
Via: SIP/2.0/UDP pc.example.com;branch=z9hG4bK74bf9 ← transaction id
From: Alice <sip:alice@example.com>;tag=9fxced76sl ← caller + From-tag
To: Bob <sip:bob@biloxi.com> ← callee (To-tag added in reply)
Call-ID: 3848276298220188511@pc.example.com ← whole-call id
CSeq: 1 INVITE ← sequence + method
Contact: <sip:alice@pc.example.com> ← where to reach the caller
Max-Forwards: 70 ← hop limitFrequently asked
What does the Via header do in SIP?
Via records the path a request takes: each proxy adds its own Via on top, and responses follow the Via stack back to the sender. Its branch parameter identifies the transaction, so responses and retransmissions are matched to the correct request.
What is the branch parameter z9hG4bK?
z9hG4bK is the mandatory magic cookie that a SIP branch parameter must start with under RFC 3261. It signals that the branch value is globally unique and RFC 3261-compliant, and it is the key used to match a response to its transaction.
How is a SIP dialog identified?
By the combination of Call-ID, the From-header tag and the To-header tag. The caller supplies the Call-ID and From-tag in the INVITE; the callee adds the To-tag in its response. All in-dialog requests carry the same three values.
What is the CSeq header for?
CSeq holds a sequence number and the request method, ordering requests within a dialog and letting each side detect retransmissions and out-of-order messages. The number increments with each new request; the method must match the request it labels.
What is the difference between Contact and To?
To is the logical target of the request and generally does not change. Contact is a concrete URI where the sender can actually be reached for subsequent requests. Proxies route on To/Request-URI, but later in-dialog requests are sent to the Contact.
Source specifications
The published standards this page is grounded in. Opens in a new tab.