Docs Dynamic Number Allocation

Dynamic Number Allocation (DNA)

The DNA API provisions tracking numbers on demand and routes inbound calls to a target_phone_number. Base URL: https://next.logimeter.com/v1/tns/. Tracking numbers are looked up by number (E.164) in the URL path.

PATCH is the recommended update method (partial). DELETE ends the tracking number immediately by setting end_stamp to now (returns 204 with no body; no request body is accepted). List endpoints are paginated (default page size 50, max 1000 via ?page_size=). Filter by Aggregator AI state with ?ai_enabled=true or ?ai_enabled=false.

Visibility: GET /v1/tns/ and GET /v1/tns/{number}/ only return tracking numbers where you are the rental_user on an active rental (lifespan contains now). A 404 on detail does not mean the number is unknown to Logimeter — use is_logimeter_tracking_number for a global existence check.

Endpoints

Tracking numbers

GET /v1/tns/ List active TNs where you are rental_user on an active rental (paginated)
POST /v1/tns/ Provision a new tracking number
GET /v1/tns/{number}/ Retrieve one tracking number (404 if not in your active list)
PATCH /v1/tns/{number}/ Partial update — features, target, end_stamp, call2lead, callbacks, etc.
PUT /v1/tns/{number}/ Full update (DRF — prefer PATCH for partial changes)
DELETE /v1/tns/{number}/ End tracking number immediately (sets end_stamp to now)

Utilities

GET /v1/tns/is_logimeter_tracking_number/{number}/ 200 if TN exists anywhere in Logimeter, 404 if not (no JSON body; not partner-scoped)
GET /v1/tn_prefixes/ Available ZA dialling prefixes with stock (flat string array)
GET /v1/global_tn_prefixes/{country_code}/ Available prefixes for country — ZA, GB, IE (nested array)

Request examples

GET — list tracking numbers

curl -s "https://next.logimeter.com/v1/tns/?ai_enabled=false" -H "Authorization: Token xxxxxxx_your_token_xxxxx"
await fetch('https://next.logimeter.com/v1/tns/?ai_enabled=false', { headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx' } });
requests.get('https://next.logimeter.com/v1/tns/', params={'ai_enabled': 'false'}, headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx'})

GET — retrieve one tracking number

curl -s "https://next.logimeter.com/v1/tns/27879437575/" -H "Authorization: Token xxxxxxx_your_token_xxxxx"
await fetch('https://next.logimeter.com/v1/tns/27879437575/', { headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx' } });
requests.get('https://next.logimeter.com/v1/tns/27879437575/', headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx'})

POST — provision tracking number

curl -sX POST "https://next.logimeter.com/v1/tns/" \
  -H "Authorization: Token xxxxxxx_your_token_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
  "target_phone_number": "27825555555",
  "company": {
    "name": "Trask Industries",
    "reference": "fec03257-9a55-4763-884f-e56fcf05cabb"
  },
  "reference": "lead-ref-001",
  "features": {
    "lead_alert_sms": ["27823334444", "27843334444"]
  }
}'
const response = await fetch('https://next.logimeter.com/v1/tns/', {
  method: 'POST',
  headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    target_phone_number: '27825555555',
    company: { name: 'Trask Industries', reference: 'fec03257-9a55-4763-884f-e56fcf05cabb' },
    reference: 'lead-ref-001',
    features: { lead_alert_sms: ['27823334444'] },
  }),
});
const tn = await response.json();
import requests

resp = requests.post(
    'https://next.logimeter.com/v1/tns/',
    headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx', 'Content-Type': 'application/json'},
    json={
        'target_phone_number': '27825555555',
        'company': {'name': 'Trask Industries', 'reference': 'fec03257-9a55-4763-884f-e56fcf05cabb'},
        'reference': 'lead-ref-001',
        'features': {'lead_alert_sms': ['27823334444']},
    },
)
resp.raise_for_status()
tn = resp.json()

PATCH — update features / routing

curl -sX PATCH "https://next.logimeter.com/v1/tns/27879437575/" \
  -H "Authorization: Token xxxxxxx_your_token_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
  "target_phone_number": "27825555555",
  "features": {
    "lead_alert_sms": ["27812344444", "27841234445"]
  },
  "end_stamp": "2026-12-31T00:00:00+02:00"
}'
await fetch('https://next.logimeter.com/v1/tns/27879437575/', {
  method: 'PATCH',
  headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    target_phone_number: '27825555555',
    features: { lead_alert_sms: ['27812344444'] },
  }),
});
requests.patch(
    'https://next.logimeter.com/v1/tns/27879437575/',
    headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx', 'Content-Type': 'application/json'},
    json={
        'target_phone_number': '27825555555',
        'features': {'lead_alert_sms': ['27812344444']},
    },
)

PUT — full update

curl -sX PUT "https://next.logimeter.com/v1/tns/27879437575/" \
  -H "Authorization: Token xxxxxxx_your_token_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
  "target_phone_number": "27825555555",
  "features": {
    "lead_alert_sms": ["27812344444", "27841234445"]
  },
  "end_stamp": "2026-12-31T00:00:00+02:00"
}'
await fetch('https://next.logimeter.com/v1/tns/27879437575/', {
  method: 'PUT',
  headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    target_phone_number: '27825555555',
    features: { lead_alert_sms: ['27812344444'] },
    end_stamp: '2026-12-31T00:00:00+02:00',
  }),
});
requests.put(
    'https://next.logimeter.com/v1/tns/27879437575/',
    headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx', 'Content-Type': 'application/json'},
    json={
        'target_phone_number': '27825555555',
        'features': {'lead_alert_sms': ['27812344444']},
        'end_stamp': '2026-12-31T00:00:00+02:00',
    },
)

DELETE — end tracking number

curl -sX DELETE "https://next.logimeter.com/v1/tns/27879437575/" -H "Authorization: Token xxxxxxx_your_token_xxxxx"
await fetch('https://next.logimeter.com/v1/tns/27879437575/', { method: 'DELETE', headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx' } });
requests.delete('https://next.logimeter.com/v1/tns/27879437575/', headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx'})

GET — check Logimeter TN exists (global)

curl -s -o /dev/null -w "%{http_code}" "https://next.logimeter.com/v1/tns/is_logimeter_tracking_number/27879437575/" -H "Authorization: Token xxxxxxx_your_token_xxxxx"
await fetch('https://next.logimeter.com/v1/tns/is_logimeter_tracking_number/27879437575/', { headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx' } });
requests.get('https://next.logimeter.com/v1/tns/is_logimeter_tracking_number/27879437575/', headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx'})

GET — ZA prefixes

curl -s "https://next.logimeter.com/v1/tn_prefixes/" -H "Authorization: Token xxxxxxx_your_token_xxxxx"
await fetch('https://next.logimeter.com/v1/tn_prefixes/', { headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx' } });
requests.get('https://next.logimeter.com/v1/tn_prefixes/', headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx'})

GET — global prefixes (Ireland)

curl -s "https://next.logimeter.com/v1/global_tn_prefixes/IE/" -H "Authorization: Token xxxxxxx_your_token_xxxxx"
await fetch('https://next.logimeter.com/v1/global_tn_prefixes/IE/', { headers: { Authorization: 'Token xxxxxxx_your_token_xxxxx' } });
requests.get('https://next.logimeter.com/v1/global_tn_prefixes/IE/', headers={'Authorization': 'Token xxxxxxx_your_token_xxxxx'})

Responses

200 OK

GET detail, PATCH, or PUT — tracking number object.

{
  "url": "https://next.logimeter.com/v1/tns/27879437575/",
  "id": 42,
  "number": "27879437575",
  "target_phone_number": "27825555555",
  "call_term_callbacks": ["https://ops.example.com/calls/"],
  "mcs_call_term_callbacks": [],
  "inbound": null,
  "recorded": false,
  "start_stamp": "2026-06-01T00:00:00+02:00",
  "end_stamp": null,
  "partner": {
    "name": "IX Online",
    "reference": "ix-partner-ref"
  },
  "company": {
    "id": 12727,
    "name": "Trask Industries (Pty) Ltd",
    "reference": "fec03257-9a55-4763-884f-e56fcf05cabb",
    "logimeter_reference": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "partner_company": {
    "id": 12727,
    "name": "Trask Industries",
    "reference": "fec03257-9a55-4763-884f-e56fcf05cabb",
    "logimeter_reference": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "features": {
    "lead_alert_email": ["mike@example.com"],
    "lead_alert_sms": ["278322334444"],
    "missed_call_alert_email": [],
    "missed_call_alert_sms": [],
    "call_summary_reports_email": [],
    "missed_call_response": {
      "text": "Sorry we missed your call.",
      "enabled": true
    },
    "meeting_tracker_enabled": false
  },
  "reference": "lead-ref-001",
  "stock_item": null,
  "call2lead": {
    "call2lead_enabled": false,
    "call2lead_ivr_in_office": null,
    "call2lead_ivr_out_of_office": null,
    "call2lead_out_of_office_number": ""
  },
  "enabled_product": "Lead Tracker",
  "dna_rental": true,
  "suspended": null,
  "suspension_comments": "",
  "ai_enabled": false,
  "brands": null
}
200 OK

GET list — paginated.

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [{
  "url": "https://next.logimeter.com/v1/tns/27879437575/",
  "id": 42,
  "number": "27879437575",
  "target_phone_number": "27825555555",
  "call_term_callbacks": ["https://ops.example.com/calls/"],
  "mcs_call_term_callbacks": [],
  "inbound": null,
  "recorded": false,
  "start_stamp": "2026-06-01T00:00:00+02:00",
  "end_stamp": null,
  "partner": {
    "name": "IX Online",
    "reference": "ix-partner-ref"
  },
  "company": {
    "id": 12727,
    "name": "Trask Industries (Pty) Ltd",
    "reference": "fec03257-9a55-4763-884f-e56fcf05cabb",
    "logimeter_reference": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "partner_company": {
    "id": 12727,
    "name": "Trask Industries",
    "reference": "fec03257-9a55-4763-884f-e56fcf05cabb",
    "logimeter_reference": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "features": {
    "lead_alert_email": ["mike@example.com"],
    "lead_alert_sms": ["278322334444"],
    "missed_call_alert_email": [],
    "missed_call_alert_sms": [],
    "call_summary_reports_email": [],
    "missed_call_response": {
      "text": "Sorry we missed your call.",
      "enabled": true
    },
    "meeting_tracker_enabled": false
  },
  "reference": "lead-ref-001",
  "stock_item": null,
  "call2lead": {
    "call2lead_enabled": false,
    "call2lead_ivr_in_office": null,
    "call2lead_ivr_out_of_office": null,
    "call2lead_out_of_office_number": ""
  },
  "enabled_product": "Lead Tracker",
  "dna_rental": true,
  "suspended": null,
  "suspension_comments": "",
  "ai_enabled": false,
  "brands": null
}
  ]
}
201 Created

POST — newly provisioned tracking number (same shape as GET detail; number is assigned by Logimeter).

{
  "url": "https://next.logimeter.com/v1/tns/27879437575/",
  "id": 42,
  "number": "27879437575",
  "target_phone_number": "27825555555",
  "call_term_callbacks": ["https://ops.example.com/calls/"],
  "mcs_call_term_callbacks": [],
  "inbound": null,
  "recorded": false,
  "start_stamp": "2026-06-01T00:00:00+02:00",
  "end_stamp": null,
  "partner": {
    "name": "IX Online",
    "reference": "ix-partner-ref"
  },
  "company": {
    "id": 12727,
    "name": "Trask Industries (Pty) Ltd",
    "reference": "fec03257-9a55-4763-884f-e56fcf05cabb",
    "logimeter_reference": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "partner_company": {
    "id": 12727,
    "name": "Trask Industries",
    "reference": "fec03257-9a55-4763-884f-e56fcf05cabb",
    "logimeter_reference": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "features": {
    "lead_alert_email": ["mike@example.com"],
    "lead_alert_sms": ["278322334444"],
    "missed_call_alert_email": [],
    "missed_call_alert_sms": [],
    "call_summary_reports_email": [],
    "missed_call_response": {
      "text": "Sorry we missed your call.",
      "enabled": true
    },
    "meeting_tracker_enabled": false
  },
  "reference": "lead-ref-001",
  "stock_item": null,
  "call2lead": {
    "call2lead_enabled": false,
    "call2lead_ivr_in_office": null,
    "call2lead_ivr_out_of_office": null,
    "call2lead_out_of_office_number": ""
  },
  "enabled_product": "Lead Tracker",
  "dna_rental": true,
  "suspended": null,
  "suspension_comments": "",
  "ai_enabled": false,
  "brands": null
}
204 No Content

DELETE — tracking number ended. No response body.

200 OK

is_logimeter_tracking_number — empty body when the number exists in Logimeter (any partner).

404 Not Found

GET /v1/tns/{number}/ — tracking number not in your active assigned list (may still exist in Logimeter).

404 Not Found

is_logimeter_tracking_number — number is not a Logimeter tracking number (empty body).

400 Bad Request

POST — no tracking number available for the requested prefix pool:

["No available Tracking Number found. Unable to assign Tracking Number."]
200 OK

GET /v1/tn_prefixes/ — flat array of available ZA prefix strings.

["087", "2781", "2782"]
200 OK

GET /v1/global_tn_prefixes/IE/ — nested array (one prefix per inner array).

[["3531"], ["3532"], ["5678"]]
400 Bad Request

GET /v1/global_tn_prefixes/ without country code:

{
  "detail": [
    "Need to pass any of the country codes in the URL mentioned here to proceed.",
    "URL: https://next.logimeter.com/v1/global_tn_prefixes/ZA",
    "Country codes: ZA, GB, IE"
  ]
}

Validation errors

ScenarioResponse
Missing companyNo company information sent.
Partner equals companyTracking Number Company cannot be the same as the Partner…
Invalid target numberTarget telephone number … is not valid for any supported country.
TN as targetTarget telephone number … is a Tracking Number and may not be used as a target telephone number.
No TN in prefix pool400["No available Tracking Number found. Unable to assign Tracking Number."]
Provisioning conflict (retry)400A Tracking Number could not be assigned for the given target phone number. This is a temporary error and the request may be repeated.
Missing sales_executive400 when lead_vehicle sent without sales_executive
Call2Lead enabled, no IVR{"Error": "Cannot enable Call2Lead without setting an in-hours IVR."}
Call2Lead, no out-of-hours{"Error": "Cannot enable Call2Lead without setting an out-of-hours IVR or number."}
Call2Lead IVR partner mismatch{"Error": "In Hours IVR Menu Partner: … does not match Rental Partner: …"} (similar for out-of-hours)
Call2Lead IVR company mismatch{"Error": "In Hours IVR Menu Partner: … and Company: … do not match Rental Partner: … and Company: …"}
end_stamp too soon{"end_stamp": "End stamp must be at least 1 day(s) after start date."}
Cannot create company403 Forbidden when partner lacks can_create_companies
User not linked to partner403 Forbidden on POST when authenticated user has no partner
end_stamp permission denied403 Forbidden on PATCH/PUT when partner cannot modify end_stamp for this TN
Country code mismatchTarget number needs to have the same country code as the country_code provided.
Unsupported country codeThe country code … is not supported
Global TN not permittedThe following company, …. cannot provision global tracking numbers
Global TN country not permitted… cannot provision global tracking numbers for …

end_stamp values are rounded up to the start of the next day in SAST (Africa/Johannesburg).

Writable fields (POST / PATCH / PUT)

FieldTypeRequiredDescription
companyobjectyes (POST){name, reference} — company that owns this TN. Created if permitted and reference is new. partner_company is an accepted alias with the same shape.
partner_companyobjectaliasWrite alias for company — same {name, reference} object.
target_phone_numberstringyes (POST)*Routing destination (E.164 or local format; 9–15 digits after normalisation). Must not be a tracking number. *Must be blank ("") when features.meeting_tracker_enabled is true.
prefixstringoptional3–4 digit prefix (POST only). Falls back to target prefix, then 087. Unavailable pool → 400. Not returned in responses.
referencestringoptionalYour lead/session reference for call matching across DNA requests. Returned on GET from the active rental.
featuresobjectoptionalAlert emails/SMS, missed-call response, meeting tracker — see appendix.
call_term_callbacksarrayoptionalURLs for call metadata webhooks. Writable on POST/PATCH/PUT; returned on GET.
mcs_call_term_callbacksarrayoptionalURLs for Missed Call Saver webhooks. Writable on POST/PATCH/PUT; returned on GET.
contactobjectoptional{name, reference} — sales contact for this TN (write only; not returned on GET).
lead_vehicleobjectoptionalLead context (POST only; not returned on GET). Requires sales_executive when provided — see appendix.
stock_itemobjectoptional{reference, details} — stock item metadata.
call2leadobjectoptionalcall2lead_enabled, IVR menu IDs, out-of-office number.
end_stampdatetimeoptionalSuspension date (ISO 8601). null = active indefinitely. Writable on PATCH/PUT only (DELETE sets to now automatically).
suspendedbooleanoptionalRental suspension flag (nullable). PATCH/PUT only.
suspension_commentsstringoptionalComments for suspension. PATCH/PUT only.
inboundbooleanoptionalWhether TN is for inbound calls (default null). POST only.
country_codestringoptionalISO country for global TN provisioning (e.g. GB, IE). POST only; not returned on GET. Requires company global-TN permission.
ai_enabledbooleanoptionalPartner external DNA only. Sets aggregator AI on rental. Omit to leave unchanged. Returned on GET.

Read-only fields (responses)

FieldTypeDescription
idintegerInternal tracking number ID.
numberstringProvisioned tracking number (E.164).
urlstringAPI URL for this resource.
start_stampdatetimeWhen the TN was first activated.
end_stampdatetimeSuspension date; null if active indefinitely.
recordedbooleanWhether calls are recorded.
partnerobjectAuthenticated partner reference ({name, reference}).
companyobjectCompany on the rental — name is the company legal name; includes id, reference, logimeter_reference.
partner_companyobjectPartner company reference — name is the PCR display name (may differ from company.name); includes id, reference, logimeter_reference.
referencestringLead/session reference from the active rental.
call_term_callbacksarrayCall metadata webhook URLs on the active rental.
mcs_call_term_callbacksarrayMissed Call Saver webhook URLs on the active rental.
featuresobjectRental feature flags and alert destinations — see appendix.
call2leadobjectCall2Lead configuration on the rental.
stock_itemobjectLinked stock item, if any.
enabled_productstringProduct name, e.g. Lead Tracker or Call2Lead type.
dna_rentalbooleantrue for Lead Tracker rentals.
suspendedbooleanRental suspension state (nullable).
suspension_commentsstringSuspension comments on the rental.
inboundbooleanWhether TN is for inbound calls (null if unknown).
ai_enabledbooleanCurrent aggregator AI setting.
brandsarrayBrand attribution on the rental, if configured.

Appendix: features object

FieldTypeDescription
lead_alert_emailstring[]Email addresses for lead alerts.
lead_alert_smsstring[]SMS numbers for lead alerts.
missed_call_alert_emailstring[]Email addresses for missed-call alerts.
missed_call_alert_smsstring[]SMS numbers for missed-call alerts.
call_summary_reports_emailstring[]Read-only in responses — not writable via API.
missed_call_responseobject{text, enabled} — auto-SMS to missed callers.
meeting_tracker_enabledbooleanWhen true, target_phone_number must be blank.

Appendix: lead_vehicle object

FieldTypeDescription
sales_executiveobjectRequired when lead_vehicle is sent — {id, name, surname}.
enquirystringbuy_vehicle (default), service, form, or insurance.
idstringYour unique lead ID.
received_timedatetimeWhen the lead was created (UTC).
source, prospect, vehicle, trade_inobjectFree-form key/value objects.

Appendix: call2lead object

FieldTypeDescription
call2lead_enabledbooleanEnable Call2Lead on this rental.
call2lead_ivr_in_officeintegerIVR menu ID for in-hours (required when enabled; must match rental partner/company).
call2lead_ivr_out_of_officeintegerIVR menu ID for out-of-hours (must match rental partner/company).
call2lead_out_of_office_numberstringFallback number when out-of-hours and no IVR.