SIP Fundamentals

Common SIP Headers (Explained)

Every SIP message is a list of headers (one per line) followed by an optional body (typically SDP). A handful of headers appear in nearly every request and reply — understanding them is the difference between guessing and debugging. This page covers the headers you will actually see, what each does, and the gotchas that bite people in production.

Anatomy of a SIP request

INVITE sip:[email protected] SIP/2.0          # Request-Line
Via: SIP/2.0/TLS 198.51.100.1:5061;branch=z9hG4bK-abc # routing path
Max-Forwards: 70                                       # loop prevention
From: "Acme Sales" <sip:[email protected]>;tag=12345
To:   <sip:[email protected]>
Call-ID: [email protected]                         # unique per call
CSeq: 1 INVITE                                         # method counter
Contact: <sip:[email protected]:5061;transport=tls>
P-Asserted-Identity: <tel:+15551234567>                # trusted caller-ID
User-Agent: AcmePBX/4.2
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, REGISTER
Supported: replaces, 100rel, timer
Content-Type: application/sdp
Content-Length: 240

<SDP body here>

Mandatory headers (always present)

HeaderWhat it does
Via:The path the request took. Each proxy adds its own Via on the way out; replies follow Via in reverse to come back. The branch parameter is a transaction ID. Stack all the Vias you see — that is your call routing path.
From:Who initiated the dialog. Includes a tag parameter (random) that identifies this dialog half. Display name + URI, e.g. "Acme" <sip:user@host>;tag=abc.
To:The dialog target. The original To: from INVITE has no tag; the 200 OK reply adds the callee's tag — that pair (From-tag + To-tag + Call-ID) becomes the dialog ID.
Call-ID:A globally unique string identifying the call. Stays constant for the entire dialog (INVITE through BYE). Format: random@host. Use this in logs to correlate every message in a call.
CSeq:Command Sequence: a method name + integer counter. Increments per request within a dialog (INVITE=1, BYE=2, etc.). Lets you tell apart re-transmissions from new requests.
Max-Forwards:Hop counter. Decremented at each proxy. Reaches 0 → 483 Too Many Hops. Always set to 70.
Contact:Where to send the next request in this dialog (re-INVITE, BYE, ACK). Different from From/To in that Contact must be reachable right now — not a logical identity. Wrong Contact = mid-call BYEs going to a black hole.

Identity / Caller-ID headers

HeaderWhat it does
P-Asserted-Identity (PAI, RFC 3325)The carrier-asserted "real" caller-ID. Trusted between carriers in the same trust domain. Most carriers (DIDHub included) read PAI rather than From: for billing and STIR/SHAKEN signing. Format: <tel:+15551234567> or <sip:+15551234567@host>.
P-Preferred-Identity (PPI)Caller's preferred identity. The proxy may use it to set PAI — or override it.
Privacy: (RFC 3323)Caller wants anonymity. Common values: id (hide PAI), none, session. Use Privacy: id instead of leaving PAI blank.
Identity: (RFC 8224)STIR/SHAKEN signature. JWS token signing the calling number with the carrier's ES256 key. See STIR/SHAKEN.
Remote-Party-ID (RPID)Older Cisco-flavored caller-ID assertion. Largely replaced by PAI. You will still see it from older Cisco gear.

Routing & forwarding

HeaderWhat it does
Record-Route:Proxies that want to stay in the path for the rest of the dialog add their URI here. Subsequent requests (BYE etc.) traverse the same proxies in order. Without it, mid-dialog requests bypass proxies that need to see them (e.g. SBCs, billing proxies).
Route:The forced routing path for the next hop. Set from the inverse of Record-Route on the reply.
Diversion:Redirected call — the original number before forwarding. Lets the destination see "Bob forwarded a call from Alice to you". Used by Teams and PBXs for the "redirected from" UI. Multiple Diversion headers stack the chain.
History-Info: (RFC 7044)Modern replacement for Diversion. Carries the full redirection history with reason codes. Microsoft Teams supports both.
Refer-To:For call transfer (REFER method). Tells the receiver where to redirect.
Replaces:For attended transfer / call pickup — "this INVITE replaces the existing call X". RFC 3891.

Authentication

HeaderWhat it does
WWW-Authenticate:On 401 Unauthorized: server tells the client what auth scheme + realm + nonce to use.
Proxy-Authenticate:Same, but from a proxy in the path (paired with 407).
Authorization:Client's digest response. Username, realm, nonce, response hash. See SIP Authentication.
Proxy-Authorization:Authorization for a proxy hop, not the final endpoint.

Session control

HeaderWhat it does
Allow:Methods this endpoint understands. Standard set: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, REGISTER, NOTIFY, SUBSCRIBE, REFER, PRACK, UPDATE. Endpoints reject unsupported methods with 405.
Supported:SIP extensions implemented (e.g. replaces, 100rel, timer, path). The peer may use any of them.
Require:Extensions the peer must support. If they don't, they reply 420 Bad Extension.
Session-Expires:SIP session timer (RFC 4028). If no re-INVITE refresh in N seconds, both sides terminate. Common value 1800.
Min-SE:Minimum session refresh interval the endpoint will accept.
Expires:On REGISTER: how long the binding lives. On INVITE: how long until the offer expires. Common: 3600 for REGISTER, 180 for INVITE.

Body / content

HeaderWhat it does
Content-Type:MIME type of the body. application/sdp for INVITE, application/dtmf-relay for INFO DTMF, multipart/mixed for combined bodies.
Content-Length:Body byte count. Required on TCP/TLS, optional on UDP.
Accept:Body types this endpoint can parse. application/sdp + maybe ISUP variants.
Reason: (RFC 3326)On BYE / CANCEL: why the call ended. Reason: Q.850;cause=16;text="Normal Clearing" — lets you see the underlying PSTN cause.

Transport / NAT

HeaderWhat it does
Via: ...;rportRFC 3581. Tells the receiver to add the source port it observed back into the Via — lets the originator know what NAT mapped its port to. Essential behind NAT.
Via: ...;received=<ip>Filled in by the receiver: "I saw this packet come from THIS IP", used for return-routing through NAT.
Path:For REGISTER: tells the registrar to relay subsequent requests through specific edge proxies. Used by IMS, mobile networks.
Service-Route:Server-side equivalent of Path: tells the client which proxies to traverse for outbound calls.

Operational / debugging

HeaderWhat it does
User-Agent:Client software identifier. Useful for support tickets — "all calls from SnomD375/8.7 have this bug".
Server:Same, but on responses from servers.
X-FS-Sending-Message / X-Asterisk-...Vendor-specific debug headers. Disable in production — some leak internal info, none are interoperable.
P-Charge-Info:Carrier billing info. Some wholesale interconnects use this; most ignore it.
Date:Server's clock at message time. Some endpoints (Cisco) reject responses with skewed dates.

Common gotchas

How to read SIP traces

  1. Pick a single Call-ID and grep for it — that's one call.
  2. Order by CSeq within that Call-ID.
  3. Match request/response pairs by CSeq number + method.
  4. For routing, walk the Via stack: the first Via was added by the most recent hop.
  5. For caller-ID issues, compare From: to PAI to Identity (STIR/SHAKEN) — one of those is what billing actually sees.

Tools: Wireshark with the SIP dissector, pjsua's --log-level=5, FreeSWITCH sofia loglevel all 9, Asterisk pjsip set logger on.

References

Related terms

Ready to get a number?

Pick a DID in 130+ countries from $1.99/month. Activates instantly on most numbers.