List Followups
curl --request GET \
--url https://getbill.io/external-api/v1/followups \
--header 'Authorization: <authorization>'import requests
url = "https://getbill.io/external-api/v1/followups"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://getbill.io/external-api/v1/followups', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://getbill.io/external-api/v1/followups",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://getbill.io/external-api/v1/followups"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://getbill.io/external-api/v1/followups")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://getbill.io/external-api/v1/followups")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"error": false,
"data": [
{
"id": "abc123def456",
"debt_id": "xyz789ghi012",
"status": "deal_found",
"type": "call",
"call_date": "2024-01-22T10:30:00+00:00",
"scheduled_at": "2024-01-22T10:00:00+00:00",
"summary": "Successfully contacted debtor",
"notes": "Customer agreed to payment plan starting next month",
"call_id": "call_789456",
"audio_url": "https://s3.amazonaws.com/bucket/recordings/call_789456.mp3?X-Amz-Signature=...",
"pdf_url": null,
"duration_ms": 180000,
"disconnection_reason": "completed_successfully",
"direction": "outbound",
"phone_number_used": "+33800123456",
"is_retry": false,
"processed_at": "2024-01-22T10:35:00+00:00",
"triggered_payment": true,
"email_opened": false,
"email_open_count": 0,
"email_first_opened_at": null,
"email_clicked": false,
"email_click_count": 0,
"media_urls_expire_at": "2024-01-22T11:35:00+00:00"
}
],
"pagination": {
"total": 1247,
"page": 1,
"limit": 50,
"pages": 25
}
}
Followups API
List Followups
Retrieve a paginated list of followups for your company
GET
/
external-api
/
v1
/
followups
List Followups
curl --request GET \
--url https://getbill.io/external-api/v1/followups \
--header 'Authorization: <authorization>'import requests
url = "https://getbill.io/external-api/v1/followups"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://getbill.io/external-api/v1/followups', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://getbill.io/external-api/v1/followups",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://getbill.io/external-api/v1/followups"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://getbill.io/external-api/v1/followups")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://getbill.io/external-api/v1/followups")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"error": false,
"data": [
{
"id": "abc123def456",
"debt_id": "xyz789ghi012",
"status": "deal_found",
"type": "call",
"call_date": "2024-01-22T10:30:00+00:00",
"scheduled_at": "2024-01-22T10:00:00+00:00",
"summary": "Successfully contacted debtor",
"notes": "Customer agreed to payment plan starting next month",
"call_id": "call_789456",
"audio_url": "https://s3.amazonaws.com/bucket/recordings/call_789456.mp3?X-Amz-Signature=...",
"pdf_url": null,
"duration_ms": 180000,
"disconnection_reason": "completed_successfully",
"direction": "outbound",
"phone_number_used": "+33800123456",
"is_retry": false,
"processed_at": "2024-01-22T10:35:00+00:00",
"triggered_payment": true,
"email_opened": false,
"email_open_count": 0,
"email_first_opened_at": null,
"email_clicked": false,
"email_click_count": 0,
"media_urls_expire_at": "2024-01-22T11:35:00+00:00"
}
],
"pagination": {
"total": 1247,
"page": 1,
"limit": 50,
"pages": 25
}
}
Overview
This endpoint returns a paginated list of all followup activities for debts belonging to your company. You can filter by status, type, date range, and other criteria.Authentication
Requires a valid OAuth 2.0 access token with thefollowups:read scope.
Request
string
required
Bearer token for authentication
Query Parameters
integer
default:"1"
Page number for pagination
integer
default:"20"
Number of items per page (maximum 100)
string
Filter by followup status. Use simple string values:
on_hold, scheduled, in_progress, sent, delivered, deal_found, no_answer, deal_not_found, bad_behavior, failed, cancelledstring
Filter by followup type:
call, email, sms, whatsapp, voicemail, manual_call, physical, postmailstring
Filter followups from this date (YYYY-MM-DD)
string
Filter followups to this date (YYYY-MM-DD)
string
Filter followups for a specific debt (encrypted ID)
Example Request
curl -X GET "/external-api/v1/followups?status=delivered&type=call&limit=50" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
const params = new URLSearchParams({
status: 'delivered',
type: 'call',
limit: '50'
});
const response = await fetch(`/external-api/v1/followups?${params}`, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
}
});
const followups = await response.json();
Response
boolean
Always
false for successful requestsarray
Array of followup objects
Show followup object
Show followup object
string
Encrypted followup identifier
string
Encrypted debt identifier
string
Followup status:
on_hold, scheduled, in_progress, sent, delivered, deal_found, no_answer, deal_not_found, bad_behavior, failed, cancelledstring
Type of followup:
call, email, sms, whatsapp, voicemail, manual_call, physical, postmailstring
When the followup was executed (ISO 8601 format)
string
When the followup was scheduled (ISO 8601 format)
string
Brief summary of the followup
string
Detailed notes about the followup
string
External call ID from the provider
string
Pre-signed URL to the call recording (expires after 1 hour)
string
Pre-signed URL to any associated PDF document (expires after 1 hour)
integer
Duration in milliseconds (for calls)
string
Reason for call disconnection
string
Call direction:
inbound or outboundstring
Phone number used for the followup
boolean
Whether this is a retry attempt
string
Processing timestamp (ISO 8601 format)
boolean
Whether this followup directly triggered a successful payment
boolean
Whether the email was opened (for email followups)
integer
Number of times the email was opened
string
Timestamp of first email open (ISO 8601 format)
boolean
Whether a link in the email was clicked
integer
Number of times links in the email were clicked
string
When the pre-signed media URLs expire (ISO 8601 format). Only present if
audio_url or pdf_url are provided.object
Success Response
{
"error": false,
"data": [
{
"id": "abc123def456",
"debt_id": "xyz789ghi012",
"status": "deal_found",
"type": "call",
"call_date": "2024-01-22T10:30:00+00:00",
"scheduled_at": "2024-01-22T10:00:00+00:00",
"summary": "Successfully contacted debtor",
"notes": "Customer agreed to payment plan starting next month",
"call_id": "call_789456",
"audio_url": "https://s3.amazonaws.com/bucket/recordings/call_789456.mp3?X-Amz-Signature=...",
"pdf_url": null,
"duration_ms": 180000,
"disconnection_reason": "completed_successfully",
"direction": "outbound",
"phone_number_used": "+33800123456",
"is_retry": false,
"processed_at": "2024-01-22T10:35:00+00:00",
"triggered_payment": true,
"email_opened": false,
"email_open_count": 0,
"email_first_opened_at": null,
"email_clicked": false,
"email_click_count": 0,
"media_urls_expire_at": "2024-01-22T11:35:00+00:00"
}
],
"pagination": {
"total": 1247,
"page": 1,
"limit": 50,
"pages": 25
}
}
Error Responses
{
"error": true,
"message": "Authentication credentials are missing or invalid",
"code": 401
}
{
"error": true,
"message": "Required scope \"followups:read\" not found in token",
"code": 403
}
Rate Limiting
This endpoint is subject to rate limiting. See the Rate Limits documentation for details. Rate Limit: 1,000 requests per hourRelated Endpoints
- Get Followup - Get details of a specific followup
- Create Followup - Create a new followup
- Update Followup - Update an existing followup
- List Followups by Debt - Get followups for a specific debt