CDR Variables and Disposition Values
CDR Variables and Disposition Values
Every Call Detail Record in Asterisk has the same set of fields, regardless of which backend stores them (CSV, SQLite, MySQL, PostgreSQL). This page is a quick lookup for what each field means, what the disposition and AMA flag values are, and the difference between duration and billsec, without wading through a storage setup guide to find it.
Disposition Values
disposition is the final state of the call. Older versions of Asterisk (and some CDR backends still, internally) represent it as an integer; the string form is what you will see in cdr show status, CSV files, and most database backends today.
| Integer | String | Meaning |
|---|---|---|
1 |
NO ANSWER |
Call rang but was never answered (timeout, caller hung up, no response) |
2 |
FAILED |
Call could not be placed (bad number, network error, congestion at the switch level) |
4 |
BUSY |
Destination returned busy |
8 |
ANSWERED |
Call was answered |
16 |
CONGESTION |
All circuits busy or destination unavailable |
NO ANSWER with no record
A disposition integer of 0 also maps to NO ANSWER, but marks a call for which no CDR record should actually be written (a NULL record). You will not normally see this value in stored data.
Read the raw integer instead of the string with the u option:
Set(CDR(disposition,u)=)
NoOp(Raw disposition: ${CDR(disposition,u)})
billsec vs duration
These two fields are the most commonly confused CDR fields:
duration- total time from when the call was dialed to when it ended, including ring time.billsec- time from when the call was answered to when it ended. This is what you bill for.
For an unanswered call, billsec is always 0 since there was no answer to start the billing clock. duration will still reflect however long the call rang.
Call rings for 8 seconds, answered, talks for 45 seconds, hangs up.
duration = 53
billsec = 45
AMA Flags
amaflags (Automatic Message Accounting flags) controls whether a record should be included in billing/accounting output.
| Integer | String | Meaning |
|---|---|---|
1 |
OMIT |
Exclude this record from accounting |
2 |
BILLING |
Include this record in accounting |
3 |
DOCUMENTATION |
Keep for reference, not for billing |
Deprecated on the CDR function
Reading or writing amaflags through CDR(amaflags) is deprecated. Use CHANNEL(amaflags) instead. The field still appears in stored CDR records under both old and new access methods.
Full Field Reference
| Field | Description |
|---|---|
clid |
Caller ID string |
src |
Source (calling) number |
dst |
Destination (dialed) number |
dcontext |
Destination context |
channel |
Originating channel |
dstchannel |
Destination channel |
lastapp |
Last dialplan application executed |
lastdata |
Arguments passed to that application |
start |
Time the call started |
answer |
Time the call was answered |
end |
Time the call ended |
duration |
Total call time in seconds, including ring |
billsec |
Answered time only, in seconds |
disposition |
Final call state: see table above |
amaflags |
Accounting flag: see table above |
accountcode |
Account code set on the channel |
uniqueid |
Unique identifier for the channel |
linkedid |
Links related channels together (transfers, parking) |
userfield |
Free-form field you can set from the dialplan |
peeraccount |
Account code of the bridged peer |
sequence |
CDR sequence number |
Of these, only accountcode, userfield, and (deprecated) amaflags can be written from the dialplan. Everything else is read-only.
; Read fields
NoOp(Disposition was: ${CDR(disposition)})
NoOp(Billed seconds: ${CDR(billsec)})
; Write the fields that are writable
Set(CDR(accountcode)=sales)
Set(CDR(userfield)=callback-requested)
Use the f option to get billsec or duration as a floating point value, and the u option to get raw, unprocessed values (epoch timestamps instead of formatted dates, integer disposition and amaflags instead of strings):
NoOp(Raw start time: ${CDR(start,u)})
NoOp(Billsec as float: ${CDR(billsec,f)})
CDRs are read-only after the bridge tears down
Once Dial() returns and the bridge between two channels is torn down, the CDR can no longer be modified. Set custom fields before that point.
See Also
- CDR() - full dialplan function syntax
- Call Detail Records (CDR) - Storage Backend Guide - setting up SQLite, MySQL, or PostgreSQL storage for these fields
User Notes
Know a tip or gotcha for this topic? Share it below and help others.
Contribute a note
Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.