NeuroAgent

How to update token for telephony.externalcall.finish in Bitrix24

Solution for expired_token error when calling telephony.externalcall.finish in Bitrix24. Updating access token via refresh_token with code examples.

Question

How to update the token for the telephony.externalcall.finish method in Bitrix24?

When using Asterisk telephony, during the call to the telephony.externalcall.finish method, we receive the response: ‘error => expired_token, error_description => The access token provided has expired’.

As I understand it, we need to refresh the authorization token. But how can this be done if it’s a standard method token?

NeuroAgent

Handling ‘expired_token’ Error in Bitrix24 telephony.externalcall.finish Method

When encountering an ‘expired_token’ error when calling the telephony.externalcall.finish method in Bitrix24, you need to refresh the authorization token using the refresh_token. To do this, you must send a POST request to a special endpoint with parameters grant_type=refresh_token, refresh_token, client_id, and client_secret, which will return a new access_token and refresh_token.

Contents


Cause of expired_token error

The expired_token error occurs because the access token in Bitrix24 has a limited lifetime. As stated in the Bitrix24 documentation, the access token:

  • Is valid for only 1 hour (3600 seconds)
  • Becomes invalid after expiration
  • Requires updating using the refresh token

In your case, when calling telephony.externalcall.finish, the system determines that the provided access token has expired and rejects the request with the corresponding error.


How to refresh the token

Token refresh uses the OAuth 2.0 mechanism with a refresh token. The process includes the following steps:

  1. Save the refresh token - during the initial authorization, Bitrix24 returns both an access token and a refresh token, which you need to save

  2. Send a refresh request - use the special endpoint with the required parameters

  3. Process the response - in case of success, you’ll receive a new access token and refresh token

Important: The refresh token has a longer validity period - 28 days or until revoked, as indicated in Bitrix24 sources.


Example of token refresh

URL for token refresh

bash
https://[your_portal].bitrix24.com/oauth/token/

Request parameters

You need to send a POST request with the following parameters:

Parameter Value Required
grant_type refresh_token Yes
refresh_token Your refresh token Yes
client_id Your application ID Yes
client_secret Your application secret key Yes

Example request

bash
curl -X POST "https://yourcompany.bitrix24.com/oauth/token/" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=your_refresh_token" \
  -d "client_id=your_client_id" \
  -d "client_secret=your_client_secret"

Example response

json
{
  "access_token": "new_access_token",
  "refresh_token": "new_refresh_token",
  "expires_in": 3600,
  "domain": "yourcompany.bitrix24.com",
  "server_endpoint": "https://oauth.bitrix.info/rest/",
  "client_endpoint": "https://yourcompany.bitrix24.com/rest/",
  "member_id": "your_member_id",
  "application_token": "your_application_token"
}

As shown in Bedaya examples, this request returns the same structure as the initial token request.


Automatic refresh in code

Error handling in API calls

It’s recommended to implement error handling for expired_token with automatic token refresh:

python
import requests

class Bitrix24API:
    def __init__(self, portal, client_id, client_secret, refresh_token):
        self.portal = portal
        self.client_id = client_id
        self.client_secret = client_secret
        self.refresh_token = refresh_token
        self.access_token = None
        self.token_expires = 0
        
    def refresh_access_token(self):
        """Refreshes access token using refresh token"""
        url = f"https://{self.portal}.bitrix24.com/oauth/token/"
        data = {
            'grant_type': 'refresh_token',
            'refresh_token': self.refresh_token,
            'client_id': self.client_id,
            'client_secret': self.client_secret
        }
        
        response = requests.post(url, data=data)
        if response.status_code == 200:
            token_data = response.json()
            self.access_token = token_data['access_token']
            self.refresh_token = token_data['refresh_token']  # Update refresh token
            self.token_expires = time.time() + token_data['expires_in']
            return True
        return False
    
    def make_api_call(self, method, params=None):
        """Makes API call with automatic token refresh"""
        if not self.access_token or time.time() >= self.token_expires:
            if not self.refresh_access_token():
                raise Exception("Failed to refresh token")
        
        url = f"https://{self.portal}.bitrix24.com/rest/{method}.json"
        headers = {'Content-Type': 'application/json'}
        params = params or {}
        params['auth'] = self.access_token
        
        response = requests.get(url, headers=headers, params=params)
        result = response.json()
        
        if result.get('error') == 'expired_token':
            # Refresh token and retry the call
            if self.refresh_access_token():
                params['auth'] = self.access_token
                response = requests.get(url, headers=headers, params=params)
                result = response.json()
        
        return result

Usage for telephony.externalcall.finish

python
# Initialize API
bitrix = Bitrix24API(
    portal="yourcompany",
    client_id="your_client_id", 
    client_secret="your_client_secret",
    refresh_token="your_refresh_token"
)

# Call telephony.externalcall.finish method
try:
    result = bitrix.make_api_call("telephony.externalcall.finish", {
        'USER_ID': 1,
        'CALL_ID': 'call123',
        'TIME': 120,
        'DISPOSITION': 'answered'
    })
    print("Result:", result)
except Exception as e:
    print("Error:", e)

As seen in pybitrix24 library examples, modern Bitrix24 API clients implement automatic token refresh.


Handling recommendations

1. Token storage

  • Save the refresh token in a secure location (not in code)
  • Regularly update the access token before it expires
  • Handle errors expired_token in your application logic

2. Refresh frequency

  • Proactively refresh tokens - 5-10 minutes before expiration
  • Monitor token lifetime in your system
  • Implement retry logic for authentication errors

3. Security

  • Use HTTPS for all requests to Bitrix24 API
  • Store secret keys in environment variables or secure storage
  • Limit scope of requested permissions

4. Logging

  • Log token refresh events
  • Log authentication errors for analysis
  • Monitor remaining time on refresh token

As noted in the documentation, proper use of refresh_token allows applications to access the REST API without user involvement, which is critical for automated systems such as integration with Asterisk.


Sources

  1. Refreshing Authorization For External Applications - Bitrix24
  2. Examples - Bitrix24 OAuth
  3. OAuth 2.0 automatic extension - Bitrix24 Training
  4. Access the Bitrix24 API - Bedaya
  5. GitHub - pybitrix24 refresh tokens example
  6. GitHub - 2BAD/bitrix client implementation

Conclusion

  • The expired_token error means the access token has expired and requires refresh through the refresh token
  • Token refresh is performed by a POST request to /oauth/token/ with parameters grant_type=refresh_token, refresh_token, client_id, and client_secret
  • Automate the token refresh process in your code for uninterrupted API operation
  • Store the refresh token securely and update it when receiving new values
  • Implement error handling for expired_token with retries after token refresh

For integration with Asterisk, it’s recommended to add automatic token refresh logic to event handlers to avoid call interruptions due to expiration of authorization data.