API reference

A small, RESTful JSON API for moving data in and out of Myphoner: users, lists, leads, calls and webhooks.

Base URL
https://<your_subdomain>.myphoner.com/api/v2
Also available as
Markdown for scripts and AI agents, and llms.txt
On this page

Getting started#

Authentication#

Every request carries an API key in the Authorization header. The account key is found in Myphoner under Manage, then Configure, then Integrations.

Each user also has a personal API key with the same access rights as that user. It lives on the user's preferences page under Credentials.

Example
curl https://<your_subdomain>.myphoner.com/api/v2/lists \
  -H "Accept: application/json" \
  -H 'Authorization: Token "<your_api_key>"'

Treat the key like a password

Anyone who knows your API key can read and change your account through the API. Keep it out of client-side code and public repositories.

Rate limits#

The API allows 60 requests per minute and 300 requests per 5 minutes. Above that the server answers 429 Too Many Requests.

A 429 response carries a Ratelimit-Reset header with the timestamp at which the next request may be made. Wait until at least that time, and back off exponentially if you keep hitting the limit. Clients that ignore 429 responses lose data.

Conventions#

Requests and responses are JSON. Send Accept: application/json and Content-type: application/json on every request.

Resources link to each other through location paths such as /api/v2/leads/98765. Prepend your account subdomain to turn a path into a full URL.

The examples on this page use curl and the fictional demo subdomain. Replace the subdomain, the key and the ids with your own and they can be pasted straight into a terminal.

Manipulating leads and events through the API does not trigger webhooks.

Users#

Invite a user#

POST/api/v2/users

Creates a user and sends them an invitation. The user counts toward your subscription once they accept.

Request
curl -X POST https://demo.myphoner.com/api/v2/users \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{
    "accept_charge_upon_invitation_acceptance": "1",
    "user": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john.doe@example.com",
      "listing_ids": ["28885", "29455"]
    }
  }'
Response
{
  "id": 6941,
  "first_name": "John",
  "last_name": "Doe",
  "email": "john.doe@example.com",
  "created_at": "2017-11-08T10:04:27.822Z",
  "updated_at": "2017-11-08T10:04:27.822Z"
}

Parameters

ParameterDescription
accept_charge_upon_invitation_acceptance
stringrequired
Must be "1". Confirms that you understand a new user raises the subscription fee once the invitation is accepted.
user[email]
stringrequired
Email address the invitation is sent to.
user[first_name]
string
user[last_name]
string
user[agent]
boolean
Give the user the Agent role. Default true.
user[users_admin]
boolean
Give the user the User manager role. Default false.
user[lists_admin]
boolean
Give the user the Data manager role. Default false.
user[analyst]
boolean
Give the user the Analyst role. Default false.
user[supervisor]
boolean
Give the user the Supervisor role. Default false.
user[listing_ids]
array of integers
Ids of the lists the user can work when they have the Agent role.

Lists#

List all lists#

GET/api/v2/lists

Request
curl https://demo.myphoner.com/api/v2/lists \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
Response
[
  {
    "id": 15288,
    "name": "Campaign 1",
    "location": "/api/v2/lists/15288",
    "created_at": "2016-11-15T12:36:28.024Z",
    "locked_on_defaults": true,
    "leads_count": 5
  },
  {
    "id": 4146,
    "name": "Campaign 2",
    "location": "/api/v2/lists/4146",
    "created_at": "2015-08-20T11:11:14.394Z",
    "locked_on_defaults": false,
    "leads_count": 5093
  }
]

Parameters

ParameterDescription
locked_on_defaults
boolean
When true or 1, only lists that guarantee the default fields are returned.

Create a list#

POST/api/v2/lists

Request
curl -X POST https://demo.myphoner.com/api/v2/lists \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{
    "list": {
      "name": "New Campaign",
      "columns_attributes": {
        "0": { "label": "Name", "kind": "none" },
        "1": { "label": "Phone", "kind": "phone" }
      }
    }
  }'
Response
{
  "id": 29999,
  "name": "New Campaign",
  "location": "/api/v2/lists/29999",
  "created_at": "2017-11-08T10:19:19.643Z",
  "locked_on_defaults": false,
  "leads_count": 0,
  "categories": {}
}

Parameters

ParameterDescription
list[name]
stringrequired
Name of the list.
list[columns_attributes]
object
Fields of the list, keyed by position: {"0": {"label": "Name", "kind": "none"}, "1": {"label": "Phone", "kind": "phone"}}. Each entry takes label, kind and optionally visible. Fields are ordered by their key. kind is one of none (text), phone, email, url, boolean, integer, date, text (multi-line), options or address.
list[description]
string
Call script shown to agents while working the list.
list[user_ids]
array of integers
Ids of agents that get access to the list.
list[call_back_categories]
string
Comma-separated sub-categories for call backs.
list[winner_categories]
string
Comma-separated sub-categories for winners.
list[loser_categories]
string
Comma-separated sub-categories for losers.
list[archive_categories]
string
Comma-separated sub-categories for archived leads.
list[skip_categories]
string
Comma-separated sub-categories for skips.
list[prepend_phone]
boolean
list[inline_identifiers]
boolean
list[show_avatars]
boolean
list[lock_on_defaults]
boolean
list[queue_new_before_call_backs]
boolean
list[queue_new_before_due]
boolean
list[duplicates_match_on_phone]
boolean
list[duplicates_match_on_email]
boolean
list[duplicates_match_on]
string

Retrieve a list#

GET/api/v2/lists/:id

Request
curl https://demo.myphoner.com/api/v2/lists/15288 \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
Response
{
  "id": 15288,
  "name": "Campaign 1",
  "location": "/api/v2/lists/15288",
  "created_at": "2016-11-15T12:36:28.024Z",
  "locked_on_defaults": true,
  "leads_count": 5,
  "categories": {
    "call_back": ["sooner", "later"],
    "winner": ["bigger", "smaller"]
  }
}

List the columns of a list#

GET/api/v2/lists/:id/columns

Returns the fields of a list. The key of each column is the name to use when creating, updating or finding leads.

Request
curl https://demo.myphoner.com/api/v2/lists/15288/columns \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
Response
[
  {
    "id": 188750,
    "key": "first_name",
    "label": "First Name",
    "type": "unicode",
    "input_type": "string",
    "required": false
  },
  {
    "id": 188759,
    "key": "birthday",
    "label": "Birthday",
    "type": "datetime",
    "input_type": "date",
    "required": false
  }
]

List the leads in a list#

GET/api/v2/lists/:id/leads

Leads are returned newest first by created_at, so you can sync your own records by fetching pages until you meet a lead you already know.

Request
curl https://demo.myphoner.com/api/v2/lists/15288/leads \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
Response
[
  {
    "id": 13722815,
    "location": "/api/v2/leads/13722815",
    "url": "https://demo.myphoner.com/work/leads/13722815",
    "list_name": "Campaign 1",
    "list_location": "/api/v2/lists/15288",
    "primary_identifier": "Craig Tillman",
    "secondary_identifier": "nunc nulla",
    "tertiary_identifier": "mauris erat eget",
    "state": "new",
    "category": null,
    "scheduled_for": null,
    "claimed_by": null,
    "claimed_at": null,
    "detected_duplicates": [],
    "ignored_duplicates": [],
    "created_at": "2016-11-15T12:37:25.331Z",
    "last_updated": "2016-11-15T12:37:25.331Z",
    "lead_data": {
      "first_name": "Craig",
      "last_name": "Tillman",
      "full_name": "Craig Tillman",
      "company_name": "mauris erat eget",
      "title": "nunc nulla",
      "e_mail": "non.justo.Proin@ipsumnunc.ca",
      "mobile_phone": "1 35 195 6007-0909",
      "work_office_phone": "1 57 733 2671-8905",
      "birthday": "1980-06-12 20:10:36"
    }
  }
]

Parameters

ParameterDescription
per_page
integer
Leads per page. Default 50.
page
integer
Page number. Default 1.
order
string
Set to last_updated_first to sort by last_updated descending instead of created_at.

Retrieve list statistics#

GET/api/v2/lists/:id/stats

Request
curl https://demo.myphoner.com/api/v2/lists/29455/stats \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
Response
{
  "id": 29455,
  "name": "5000leads",
  "location": "/api/v2/lists/29455",
  "created_at": "2017-10-26T09:34:00.043Z",
  "locked_on_defaults": false,
  "leads_count": 5099,
  "leads_counts": {
    "new": { "uncategorised": 5060, "total": 5060 },
    "call_back": {
      "bad_time": 1,
      "positive": 3,
      "no_answer": 6,
      "voicemail": 2,
      "gatekeeper": 0,
      "uncategorised": 16,
      "total": 28
    },
    "won": { "uncategorised": 4, "total": 4 },
    "lost": { "uncategorised": 5, "total": 5 },
    "archived": { "uncategorised": 2, "total": 2 },
    "total": 5099
  }
}

Leads#

Create a lead#

POST/api/v2/lists/:id/leads

Keys in lead are the column keys of the list. Fetch them with list the columns of a list.

Request
curl -X POST https://demo.myphoner.com/api/v2/lists/15288/leads \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"first_name": "John", "last_name": "Doe", "mobile_phone": "12345678"}}'
  • The detected_duplicates and ignored_duplicates keys hold arrays of lead ids. After uploading an entire new list this information can take up to an hour to settle, depending on the size of the list, because duplicate detection runs in the background. A single lead created through the API has duplicate detection done within a couple of minutes.

Retrieve a lead#

GET/api/v2/leads/:id

Returns a lead in the same shape as list the leads in a list.

Request
curl https://demo.myphoner.com/api/v2/leads/13722811 \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
  • The detected_duplicates and ignored_duplicates keys hold arrays of lead ids. After uploading an entire new list this information can take up to an hour to settle, depending on the size of the list, because duplicate detection runs in the background. A single lead created through the API has duplicate detection done within a couple of minutes.

Update a lead#

PATCH/api/v2/leads/:id

Keys in lead are the column keys of the list. Fetch them with list the columns of a list.

Request
curl -X PATCH https://demo.myphoner.com/api/v2/leads/13722820 \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"full_name": "John Doe", "company_name": "Doe Inc."}}'

Responds with 204 No Content on success.

Find leads by field#

GET/api/v2/lists/:id/leads/find

Exact match on one or more fields of the list. By default all supplied fields must match; pass matchall=false to match any of them.

Request
curl "https://demo.myphoner.com/api/v2/lists/15288/leads/find?mobile_phone=15324083898652" \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'

Parameters

ParameterDescription
<field_key>
string
Value to match. Repeat with different column keys to match on several fields.
matchall
boolean
Set to false to combine conditions with OR instead of AND.
  • The detected_duplicates and ignored_duplicates keys hold arrays of lead ids. After uploading an entire new list this information can take up to an hour to settle, depending on the size of the list, because duplicate detection runs in the background. A single lead created through the API has duplicate detection done within a couple of minutes.

Search leads#

GET/api/v2/leads/search

Free-text search across lead data and activity logs, like the search field inside Myphoner.

Request
curl "https://demo.myphoner.com/api/v2/leads/search?query=Houston&list_ids=812,4146" \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
Response
{
  "total": 2,
  "leads": []
}

Parameters

ParameterDescription
query
stringrequired
The search string.
list_ids
string
Comma-separated list ids to scope the search to.
per_page
integer
Leads per page. Default 50.
page
integer
Page number. Default 1.
  • The detected_duplicates and ignored_duplicates keys hold arrays of lead ids. After uploading an entire new list this information can take up to an hour to settle, depending on the size of the list, because duplicate detection runs in the background. A single lead created through the API has duplicate detection done within a couple of minutes.

Mark a lead as winner#

POST/api/v2/leads/:id/winner

Request
curl -X POST https://demo.myphoner.com/api/v2/leads/13722820/winner \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"call_back_in": "10", "scheduled_for": "2016-06-04 08:04:55 UTC", "comment": "My comment", "category": ""}}'

Responds with 204 No Content on success.

Parameters

All parameters are optional.

ParameterDescription
call_back_in
integer
Minutes until the scheduled call back.
scheduled_for
datetime
Time of the call back as YYYY-MM-DD HH:MM:SS UTC. Takes precedence over call_back_in when both are present. See the getting started guide for how a schedule behaves on leads that are not marked for call back.
comment
string
Text inserted as a comment on the winner event.
category
string
Category of the winner event. Must match an existing category exactly, including case.

Mark a lead for call back#

POST/api/v2/leads/:id/call_back

Request
curl -X POST https://demo.myphoner.com/api/v2/leads/13722820/call_back \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"call_back_in": "10", "scheduled_for": "2016-06-04 08:04:55 UTC", "comment": "My comment", "category": ""}}'

Responds with 204 No Content on success.

Parameters

All parameters are optional.

ParameterDescription
call_back_in
integer
Minutes until the scheduled call back.
scheduled_for
datetime
Time of the call back as YYYY-MM-DD HH:MM:SS UTC. Takes precedence over call_back_in when both are present. See the getting started guide for how a schedule behaves on leads that are not marked for call back.
comment
string
Text inserted as a comment on the call back event.
category
string
Category of the call back event. Must match an existing category exactly, including case.

Mark a lead as loser#

POST/api/v2/leads/:id/loser

Request
curl -X POST https://demo.myphoner.com/api/v2/leads/13722820/loser \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"call_back_in": "10", "scheduled_for": "2016-06-04 08:04:55 UTC", "comment": "My comment", "category": ""}}'

Responds with 204 No Content on success.

Parameters

All parameters are optional.

ParameterDescription
call_back_in
integer
Minutes until the scheduled call back.
scheduled_for
datetime
Time of the call back as YYYY-MM-DD HH:MM:SS UTC. Takes precedence over call_back_in when both are present. See the getting started guide for how a schedule behaves on leads that are not marked for call back.
comment
string
Text inserted as a comment on the loser event.
category
string
Category of the loser event. Must match an existing category exactly, including case.

Archive a lead#

POST/api/v2/leads/:id/archive

Request
curl -X POST https://demo.myphoner.com/api/v2/leads/13722820/archive \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"call_back_in": "10", "scheduled_for": "2016-06-04 08:04:55 UTC", "comment": "My comment", "category": ""}}'

Responds with 204 No Content on success.

Parameters

All parameters are optional.

ParameterDescription
call_back_in
integer
Minutes until the scheduled call back.
scheduled_for
datetime
Time of the call back as YYYY-MM-DD HH:MM:SS UTC. Takes precedence over call_back_in when both are present. See the getting started guide for how a schedule behaves on leads that are not marked for call back.
comment
string
Text inserted as a comment on the archive event.
category
string
Category of the archive event. Must match an existing category exactly, including case.

Delegate or claim a lead#

PATCH/api/v2/leads/:id/delegate

Request
curl -X PATCH https://demo.myphoner.com/api/v2/leads/13722820/delegate \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"delegate_to": "1250"}}'

Responds with 204 No Content on success.

Parameters

ParameterDescription
delegate_to
integer or stringrequired
Id or email of the user that should hold the claim on the lead.

Move a lead to another list#

PATCH/api/v2/leads/:id/migrate

Request
curl -X PATCH https://demo.myphoner.com/api/v2/leads/13722820/migrate \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"lead": {"to_list_id": "15288"}}'

Responds with 204 No Content on success.

Parameters

ParameterDescription
to_list_id
integerrequired
Id of the destination list. May be the current list, which is useful when you only want to release a claimed lead.
give_back_leads
string
"1" releases the lead if it is claimed. "0" or omitted leaves the claim as is.

Calls#

A call is created when an agent dials from Myphoner. Subscribe to the new_call or new_recording webhook to be told when one is available, then fetch it here.

Retrieve a call#

GET/api/v2/calls/:id

Request
curl https://demo.myphoner.com/api/v2/calls/12345 \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'
Response
{
  "location": "/api/v2/calls/12345",
  "user_email": "agent@example.com",
  "destination_number": "+447700900123",
  "duration": 11,
  "started_at": "2026-09-16T09:31:41.000Z",
  "caller_id": { "number": "+442079460000", "name": "Sales line" },
  "direction": "outbound",
  "disposition": "voicemail",
  "state": "completed",
  "lead_id": 98765,
  "event_id": 54321,
  "lead": "/api/v2/leads/98765",
  "list": "/api/v2/lists/42",
  "recordings": [
    { "started_at": "2026-09-16T09:31:47.000Z", "url": "https://recordings.example.com/abc.wav" }
  ]
}

Response fields

FieldDescription
location
string
Path of this call.
user_email
string
Email of the agent who made the call.
destination_number
string
Number that was dialled.
duration
integer
Length of the call in seconds. 0 for unanswered and failed attempts.
started_at
string
When the call started, ISO 8601 in UTC.
caller_id
object
The outbound caller ID actually used, as {"number": string or null, "name": string or null}. This is the number the recipient saw. With Smart CIDs it varies per call. Always present.
direction
string
One of outbound, inbound, transfer, local or automated.
disposition
string or null
One of busy, failed, invalid_number, normal, no_answer, temp_unavail or voicemail. normal is a connected call the agent ended as a conversation. voicemail is set when the agent uses the voicemail hangup or a Voicemail category while connected. null until the call has been processed.
state
string
One of initiated, calling, active or completed.
lead_id
integer or null
Id of the lead this call belongs to. Same lead as the lead link.
event_id
integer or null
Id of the disposition event on the lead that this call belongs to. null while the call is not yet linked to a disposition.
lead
string or null
Path of the lead.
list
string or null
Path of the list the lead is in.
recordings
array
Recordings of the call, each with started_at and a url to the audio file. Empty when the call was not recorded.
  • Unanswered and failed attempts are returned too, with duration 0 and a disposition such as no_answer or busy.
  • To attach a lead outcome to a specific call, use event_id rather than matching on timestamps.
  • The new_call webhook fires only once a call is linked to a lead. Inbound calls are tracked separately and do not fire new_call. A missed inbound callback re-queues the lead and fires the call_back webhook instead.

Webhooks#

Subscribe to events such as a new winner, a call back or a finished call and Myphoner sends an HTTP POST to a URL of your choice the moment they happen. The notification tells you where to fetch the full resource.

Webhooks fire on activity inside Myphoner. Changes made through the API do not trigger them.

Events#

The event parameter of a subscription takes one of these values.

EventFires whenScope
winnerThe Winner action was used on a lead.list
loserThe Loser action was used on a lead.list
archiveThe Archive action was used on a lead.list
call_backThe Call back action was used on a lead.list
textA text message was sent to a lead.list
inbound_textA text message was received from a lead.list
new_eventAny new event, including all of the above, except unclaim and migration.list
new_commentA comment was added to a lead, in any state.list
lead_createdAn agent created a lead.list
lead_updatedAn agent changed the lead data of a lead.list
new_callA call was completed and linked to a lead.list, account
new_recordingA recorded call was completed.list, account

Subscribe to events on a list#

POST/api/v2/lists/:id/webhook

Request
curl -X POST https://demo.myphoner.com/api/v2/lists/15288/webhook \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"webhook": {"target_url": "https://yourdomain.com/path/to/endpoint", "event": "winner"}}'

Responds with 201 Created on success.

Parameters

ParameterDescription
webhook[target_url]
stringrequired
URL on your domain that receives the POST described in receive a notification.
webhook[event]
stringrequired
One of the events.
  • The response is the JSON representation of the webhook. Save its id; you need it to unsubscribe.

Subscribe to events account-wide#

POST/api/v2/webhooks

Only new_call and new_recording can be subscribed account-wide.

Request
curl -X POST https://demo.myphoner.com/api/v2/webhooks \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"' \
  -d '{"webhook": {"target_url": "https://yourdomain.com/path/to/endpoint", "event": "new_recording"}}'

Responds with 201 Created on success.

Parameters

ParameterDescription
webhook[target_url]
stringrequired
URL on your domain that receives the POST described in receive a notification.
webhook[event]
stringrequired
new_call or new_recording.
  • The response is the JSON representation of the webhook. Save its id; you need it to unsubscribe.

Receive a notification#

POST/your/target_urlsent by Myphoner to your server

Myphoner sends this request to the target_url of the subscription. The body names the resource to fetch, which is a lead for lead events and a call for new_call and new_recording.

Request
curl -X POST https://yourdomain.com/path/to/endpoint \
  -H "Content-Type: application/json" \
  -d '{"resource_url": "https://demo.myphoner.com/api/v2/leads/13722820"}'

Parameters

ParameterDescription
resource_url
string
URL of the lead or call the event relates to.
  • Respond with a 200 status. The body is ignored.

Responding to errors

Respond with 410 Gone when something is permanently wrong and the subscription should be removed. Any other 4xx or 5xx response is treated as temporary and ignored.

Delete a webhook#

DELETE/api/v2/webhook/:id

Request
curl -X DELETE https://demo.myphoner.com/api/v2/webhook/1234 \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -H 'Authorization: Token "<your_api_key>"'

Responds with 200 OK on success.

Parameters

ParameterDescription
id
integerrequired
Id of the webhook, returned when you subscribed.