NAV
javascript bash php

Overview

Prerequisites

To enable API in the FreeScout you need to install API & Webhooks module.

All API requests should be made using UTF-8 encoding.

Authentication

API Key can be retrieved in "Manage » API & Webhoks".

There are three ways to authenticate using API Key to make API calls:

1) Pass API Key in "api_key" GET-parameter:

http://demo.freescout.net/api/conversations?api_key=c2ba609c687a3425402b9d881e5075db

2) Pass API Key as a username with a random password via HTTP Basic authentication:

Authorization: c2ba609c687a3425402b9d881e5075db randompassword

3) Pass API Key as "X-FreeScout-API-Key" HTTP header:

X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db

HTTP Methods

Method Meaning
GET Read one or more entities.
POST Create new entity.
DELETE Delete single entity.
OPTIONS Returns allowed HTTP methods and Access-Control-* headers for CORS preflight request.

Status Codes

Status Code Name Description
200 OK Request was successful and response contains data.
201 Created Resource was created. Response will contain either Location header or Resource-ID header. Usually for POST requests.
204 No Content Request was successful and response is empty. Typical response for PUT, PATCH and DELETE requests.
301 Moved permanently Requested entity existed under a different ID or path. Check the Location header.
400 Bad Request Client error - the request doesn’t meet all requirements, see error messages.
401 Not Authorized API Key is either not provided or not valid.
403 Access denied Your API Key is valid, but you are denied access - the response should contain details.
404 Not Found Resource was not found - it doesn’t exist or it was deleted.
405 Method Not Allowed This error indicates that you are using incorrect HTTP method or incorrect API endpoint URL (allowed HTTP methods are URLs are described in this documentation for each API method) or you need to update API & Webhooks Module to the latest version (in older versions not all API methods were present).
409 Conflict Resource cannot be created because conflicting entity already exists.
412 Precondition failed The request was well formed and valid, but some other conditions were not met.
413 Request Entity Too Large The payload of the request is larger than limit of the web server or PHP.
415 Unsupported Media Type The API is unable to work with the provided payload.
500 Internal Server Error Whoops, looks like something went wrong on our end.
504 Gateway Timeout The API call timed-out. It is safe to retry the request after a short delay.

Date Format

All dates in the API are displayed and expected to be in ISO 8601 format in the UTC timezone:
YYYY-MM-DDThh:mm:ssZ ("Z" is the designator for the zero UTC offset).

Example: 2020-01-02T23:00:00Z

Errors

Example of the error response is presented on the right side (or below).

    
{
    "message": "Bad request",
    "errorCode": "BAD REQUEST",
    "_embedded": {
        "errors": [
            {
                "path": "subject",
                "message": "may not be empty",
                "source": "JSON"
            },
            {
                "path": "status",
                "message": "Expected one of these: 'active', 'spam', 'open', 'closed', 'pending'",
                "rejectedValue": "Wrong",
                "source": "JSON"
            }
        ]
    }
}

    
{
    "message": "Bad request",
    "errorCode": "BAD REQUEST",
    "_embedded": {
        "errors": [
            {
                "path": "subject",
                "message": "may not be empty",
                "source": "JSON"
            },
            {
                "path": "status",
                "message": "Expected one of these: 'active', 'spam', 'open', 'closed', 'pending'",
                "rejectedValue": "Wrong",
                "source": "JSON"
            }
        ]
    }
}

    
{
    "message": "Bad request",
    "_embedded": {
        "errors": [
            {
                "path": "subject",
                "message": "may not be empty",
                "source": "JSON"
            },
            {
                "path": "status",
                "message": "Expected one of these: 'active', 'spam', 'open', 'closed', 'pending'",
                "rejectedValue": "Wrong",
                "source": "JSON"
            }
        ]
    }
}

Conversations

Create Conversation

This method creates a conversation in a mailbox with at least one thread.

Example request:

const url = new URL("https://demo.freescout.net/api/conversations");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "type": "email",
    "mailboxId": 1,
    "subject": "Hi there",
    "customer": {
        "email": "mark@example.org"
    },
    "threads": [
        {
            "text": "This is the message from a user",
            "type": "message",
            "user": 7
        },
        {
            "text": "This is the note from a user",
            "type": "note",
            "user": 7
        },
        {
            "text": "This is the message from a customer",
            "type": "customer",
            "cc": [
                "antony@example.org"
            ],
            "customer": {
                "email": "mark@example.org",
                "firstName": "Mark"
            }
        }
    ],
    "imported": false,
    "assignTo": 15,
    "status": "active",
    "customFields": [
        {
            "id": 37,
            "value": "Some text"
        },
        {
            "id": 18,
            "value": 3
        }
    ],
    "createdAt": "2020-03-16T14:07:23Z",
    "closedAt": "2020-03-16T14:07:23Z"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X POST "https://demo.freescout.net/api/conversations" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"type":"email","mailboxId":1,"subject":"Hi there","customer":{"email":"mark@example.org"},"threads":[{"text":"This is the message from a user","type":"message","user":7},{"text":"This is the note from a user","type":"note","user":7},{"text":"This is the message from a customer","type":"customer","cc":["antony@example.org"],"customer":{"email":"mark@example.org","firstName":"Mark"}}],"imported":false,"assignTo":15,"status":"active","customFields":[{"id":37,"value":"Some text"},{"id":18,"value":3}],"createdAt":"2020-03-16T14:07:23Z","closedAt":"2020-03-16T14:07:23Z"}'

$client = new \GuzzleHttp\Client();
$response = $client->post("https://demo.freescout.net/api/conversations", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "type" => "email",
                    "mailboxId" => "1",
                    "subject" => "Hi there",
                    "customer" => array(
   'email' => 'mark@example.org',
),
                    "threads" => array (
  0 => 
  array(
     'text' => 'This is the message from a user',
     'type' => 'message',
     'user' => 7,
  ),
  1 => 
  array(
     'text' => 'This is the note from a user',
     'type' => 'note',
     'user' => 7,
  ),
  2 => 
  array(
     'text' => 'This is the message from a customer',
     'type' => 'customer',
     'cc' => 
    array (
      0 => 'antony@example.org',
    ),
     'customer' => 
    array(
       'email' => 'mark@example.org',
       'firstName' => 'Mark',
    ),
  ),
),
                    "imported" => "",
                    "assignTo" => "15",
                    "status" => "active",
                    "customFields" => array (
  0 => 
  array(
     'id' => 37,
     'value' => 'Some text',
  ),
  1 => 
  array(
     'id' => 18,
     'value' => 3,
  ),
),
                    "createdAt" => "2020-03-16T14:07:23Z",
                    "closedAt" => "2020-03-16T14:07:23Z",
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

HTTP/1.1 201 Created
Resource-ID: 35

HTTP Request

POST api/conversations

Body Parameters

Parameter Type Required Description
type string (required) Conversation type: email, phone, chat (after importing "chat" conversation, support agent replies will not reach customer linked to the conversation, as connection to customer's messenger can't be imported).
mailboxId number (required) ID of a mailbox where the conversation is being created.
subject string (required) Conversation’s subject.
customer object (required) Customer associated with the conversation. Customer object must contain a valid customer id or an email address: { "id": 123 } or { "email": "mark@example.org" }. If the id field is defined, the email will be ignored. If the id is not defined, email is used to look up a customer. If a customer does not exist, a new one will be created. If a customer is matched either via id or email field, the rest of the optional fields is ignored. When creating a phone conversation "firstName" or "phone" can be passed instead of "email".
threads object (required) Conversation threads. There has to be least one thread in a conversation. Newest threads go first.
imported boolean When imported is set to true (boolean value without quotes), no outgoing emails or notifications will be generated, auto reply will not be sent to the customer.
assignTo number User ID to assign new conversation to.
status string Conversation status: active, pending, closed.
customFields object Conversation custom fields.
createdAt string Conversation date (ISO 8601 date time format).
closedAt string When the conversation was closed, only applicable for imported conversations (ISO 8601 date time format).

Get Conversation

Example request:

const url = new URL("https://demo.freescout.net/api/conversations/1");

    let params = {
            "embed": "threads",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/conversations/1?embed=threads" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/conversations/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "embed" => "threads",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "id": 1,
    "number": 3,
    "threadsCount": 2,
    "type": "email",
    "folderId": 11,
    "status": "closed",
    "state": "published",
    "subject": "Refund",
    "preview": "Could you please refund my recent payment...",
    "mailboxId": 15,
    "assignee": {
        "id": 9,
        "type": "user",
        "firstName": "John",
        "lastName": "Doe",
        "email": "johndoe@example.org"
    },
    "createdBy": {
        "id": 11,
        "type": "customer",
        "email": "customer@example.org"
    },
    "createdAt": "2020-03-15T22:46:22Z",
    "updatedAt": "2020-03-15T22:46:22Z",
    "closedBy": 14,
    "closedByUser": {
        "id": 14,
        "type": "user",
        "firstName": "John",
        "lastName": "Doe",
        "photoUrl": "https:\/\/support.example.org\/storage\/users\/5a10629fd2bae86563892b191f6677e7.jpg",
        "email": "johndoe@example.org"
    },
    "closedAt": "2020-03-16T14:07:23Z",
    "userUpdatedAt": "2020-03-16T14:07:23Z",
    "customerWaitingSince": {
        "time": "2020-07-24T20:18:33Z",
        "friendly": "10 hours ago",
        "latestReplyFrom": "customer"
    },
    "source": {
        "type": "email",
        "via": "customer"
    },
    "cc": [
        "fox@example.org"
    ],
    "bcc": [
        "fox@example.org"
    ],
    "customer": {
        "id": 91,
        "type": "customer",
        "firstName": "Rodney",
        "lastName": "Robertson",
        "photoUrl": "https:\/\/support.example.org\/storage\/customers\/7a10629fd2bae86563892b191f6677e7.jpg",
        "email": "rodney@example.org"
    },
    "customFields": [
        {
            "id": 22,
            "name": "Amount",
            "value": "7",
            "text": ""
        },
        {
            "id": 23,
            "name": "Currency",
            "value": "1",
            "text": "USD"
        }
    ],
    "_embedded": {
        "threads": [
            {
                "id": 17,
                "type": "customer",
                "status": "active",
                "state": "published",
                "action": {
                    "type": "changed-ticket-assignee",
                    "text": "John Doe assigned conversation to Mark",
                    "associatedEntities": []
                },
                "body": "Thank you very much!",
                "source": {
                    "type": "email",
                    "via": "customer"
                },
                "customer": {
                    "id": 91,
                    "type": "customer",
                    "firstName": "Rodney",
                    "lastName": "Robertson",
                    "photoUrl": "https:\/\/support.example.org\/storage\/customers\/7a10629fd2bae86563892b191f6677e7.jpg",
                    "email": "rodney@example.org"
                },
                "createdBy": {
                    "id": 91,
                    "type": "customer",
                    "firstName": "Rodney",
                    "lastName": "Robertson",
                    "photoUrl": "https:\/\/support.example.org\/storage\/customers\/7a10629fd2bae86563892b191f6677e7.jpg",
                    "email": "rodney@example.org"
                },
                "assignedTo": {
                    "id": 14,
                    "type": "user",
                    "firstName": "John",
                    "lastName": "Doe",
                    "photoUrl": "https:\/\/support.example.org\/storage\/users\/5a10629fd2bae86563892b191f6677e7.jpg",
                    "email": "johndoe@example.org"
                },
                "to": [
                    "test@example.org"
                ],
                "cc": [
                    "fox@example.org"
                ],
                "bcc": [
                    "fox@example.org"
                ],
                "createdAt": "2020-06-05T20:18:33Z",
                "openedAt": "2020-06-07T10:01:25Z",
                "_embedded": {
                    "attachments": [
                        {
                            "id": 71,
                            "fileName": "example.pdf",
                            "fileUrl": "https:\/\/support.example.org\/storage\/attachment\/7\/3\/1\/example.pdf?id=71&token=c5135450a05cc47d7aa3333d8a3e7831",
                            "mimeType": "application\/pdf",
                            "size": 2331
                        }
                    ]
                }
            }
        ],
        "timelogs": [
            {
                "id": 498,
                "conversationStatus": "pending",
                "userId": 1,
                "timeSpent": 219,
                "paused": false,
                "finished": true,
                "createdAt": "2021-04-21T13-24-01Z",
                "updatedAt": "2021-04-21T13-43-10Z"
            },
            {
                "id": 497,
                "conversationId": 1984,
                "conversationStatus": "active",
                "userId": 1,
                "timeSpent": 711,
                "paused": false,
                "finished": true,
                "createdAt": "2021-04-21T13-22-09Z",
                "updatedAt": "2021-04-21T13-43-10Z"
            }
        ],
        "tags": [
            {
                "id": 57,
                "name": "overdue"
            },
            {
                "id": 39,
                "name": "refund"
            }
        ]
    }
}

HTTP Request

GET api/conversations/{conversationId}

Query Parameters

Parameter Required Description
embed Pass comma separated values to include extra data: threads, timelogs, tags. Default: threads.

List Conversations

Request parameters can be used to filter conversations. By default conversations are sorted by createdAt (from newest to oldest): ?sortField=createdAt&sortOrder=desc

Example request:

const url = new URL("https://demo.freescout.net/api/conversations");

    let params = {
            "embed": "threads",
            "mailboxId": "123",
            "folderId": "57",
            "status": "active",
            "state": "deleted",
            "type": "email",
            "assignedTo": "35",
            "customerEmail": "john@example.org",
            "customerPhone": "777-777-777",
            "customerId": "17",
            "number": "359",
            "subject": "test",
            "tag": "overdue",
            "createdByUserId": "9",
            "createdByCustomerId": "10",
            "createdSince": "2021-01-07T12:00:03Z",
            "updatedSince": "2021-01-07T12:00:03Z",
            "sortField": "updatedAt",
            "sortOrder": "asc",
            "page": "1",
            "pageSize": "100",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/conversations?embed=threads&mailboxId=123&folderId=57&status=active&state=deleted&type=email&assignedTo=35&customerEmail=john%40example.org&customerPhone=777-777-777&customerId=17&number=359&subject=test&tag=overdue&createdByUserId=9&createdByCustomerId=10&createdSince=2021-01-07T12%3A00%3A03Z&updatedSince=2021-01-07T12%3A00%3A03Z&sortField=updatedAt&sortOrder=asc&page=1&pageSize=100" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/conversations", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "embed" => "threads",
            "mailboxId" => "123",
            "folderId" => "57",
            "status" => "active",
            "state" => "deleted",
            "type" => "email",
            "assignedTo" => "35",
            "customerEmail" => "john@example.org",
            "customerPhone" => "777-777-777",
            "customerId" => "17",
            "number" => "359",
            "subject" => "test",
            "tag" => "overdue",
            "createdByUserId" => "9",
            "createdByCustomerId" => "10",
            "createdSince" => "2021-01-07T12:00:03Z",
            "updatedSince" => "2021-01-07T12:00:03Z",
            "sortField" => "updatedAt",
            "sortOrder" => "asc",
            "page" => "1",
            "pageSize" => "100",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

{
    "_embedded": {
        "conversations": [
            {
                "id": 1,
                "number": 3,
                "threads": 2,
                "type": "email",
                "folderId": 11,
                "status": "closed",
                "state": "published",
                "subject": "Refund",
                "preview": "Could you please refund my recent payment...",
                "mailboxId": 15,
                "assignee": {
                    "id": 9,
                    "type": "user",
                    "firstName": "John",
                    "lastName": "Doe",
                    "email": "johndoe@example.org"
                },
                "createdBy": {
                    "id": 11,
                    "type": "customer",
                    "email": "customer@example.org"
                },
                "createdAt": "2020-03-15T22:46:22Z",
                "updatedAt": "2020-03-15T22:46:22Z",
                "closedBy": 14,
                "closedByUser": {
                    "id": 14,
                    "type": "user",
                    "firstName": "John",
                    "lastName": "Doe",
                    "photoUrl": "https:\/\/support.example.org\/storage\/users\/5a10629fd2bae86563892b191f6677e7.jpg",
                    "email": "johndoe@example.org"
                },
                "closedAt": "2020-03-16T14:07:23Z",
                "userUpdatedAt": "2020-03-16T14:07:23Z",
                "customerWaitingSince": {
                    "time": "2020-07-24T20:18:33Z",
                    "friendly": "10 hours ago",
                    "latestReplyFrom": "customer"
                },
                "source": {
                    "type": "email",
                    "via": "customer"
                },
                "cc": [
                    "fox@example.org"
                ],
                "bcc": [
                    "fox@example.org"
                ],
                "customer": {
                    "id": 91,
                    "type": "customer",
                    "firstName": "Rodney",
                    "lastName": "Robertson",
                    "photoUrl": "https:\/\/support.example.org\/storage\/customers\/7a10629fd2bae86563892b191f6677e7.jpg",
                    "email": "rodney@example.org"
                },
                "customFields": [],
                "_embedded": {
                    "threads": []
                }
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 1,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/conversations

Query Parameters

Parameter Required Description
embed Pass comma separated values to include extra data: threads, timelogs, tags.
mailboxId Filter conversations from a specific mailbox. Can contain multiple comma separated IDs.
folderId Filter conversations from a specific folder ID (filtering by Custom Folder ID provided by Custom Folders Module is not possible).
status Filter conversation by status (defaults to active): active, pending, closed, spam. Can contain multiple comma separated values.
state Filter conversation by state: draft, published, deleted.
type Filter conversation by type: email, phone, chat.
assignedTo Filter conversations by assignee id. Pass an empty value in order to get unassigned conversations.
customerEmail Filter conversations by customer email.
customerPhone Filter conversations by customer phone number.
customerId Filter conversations by customer ID.
number Look up conversation by conversation number.
subject Look up conversations containing a text in the subject.
tag Look up conversations by tag.
createdByUserId Filter conversations by a user who created it.
createdByCustomerId Filter conversations by a customer who created it.
createdSince Return only conversations created after the specified date.
updatedSince Return only conversations modified after the specified date.
sortField Sort the result by specified field: createdAt, mailboxId, number, subject, updatedAt, waitingSince.
sortOrder Sort order: desc (default), asc.
page Page number.
pageSize Page size (defaults to 50).

Update Conversation

Order of passed parameters (status, assignTo, etc.) determines the order in which changes are made.

Example request:

const url = new URL("https://demo.freescout.net/api/conversations/1");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "byUser": 33,
    "status": "active",
    "assignTo": 15,
    "mailboxId": 1,
    "customerId": 7,
    "subject": 0
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X PUT "https://demo.freescout.net/api/conversations/1" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"byUser":33,"status":"active","assignTo":15,"mailboxId":1,"customerId":7,"subject":0}'

$client = new \GuzzleHttp\Client();
$response = $client->put("https://demo.freescout.net/api/conversations/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "byUser" => "33",
                    "status" => "active",
                    "assignTo" => "15",
                    "mailboxId" => "1",
                    "customerId" => "7",
                    "subject" => "0",
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

PUT api/conversations/{conversationId}

Body Parameters

Parameter Type Required Description
byUser number ID of the user updating the conversation. Required when changing: "status", "assignTo" or "mailboxId".
status string Change conversation status: active, pending, closed, spam.
assignTo number Change conversation assignee to the user with the specified ID.
mailboxId number Move conversation to the mailbox with the specified ID.
customerId number Change conversation customer to the customer with the specified ID.
subject number Change conversation subject.

Delete Conversation

This method deletes a conversation forever.

Example request:

const url = new URL("https://demo.freescout.net/api/conversations/1");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X DELETE "https://demo.freescout.net/api/conversations/1" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->delete("https://demo.freescout.net/api/conversations/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

DELETE api/conversations/{conversationId}

Custom Fields

Update Custom Fields

Example request:

const url = new URL("https://demo.freescout.net/api/conversations/1/custom_fields");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "customFields": [
        {
            "id": 37,
            "value": "Test value"
        }
    ]
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X PUT "https://demo.freescout.net/api/conversations/1/custom_fields" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"customFields":[{"id":37,"value":"Test value"}]}'

$client = new \GuzzleHttp\Client();
$response = $client->put("https://demo.freescout.net/api/conversations/1/custom_fields", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "customFields" => array (
  0 => 
  array(
     'id' => 37,
     'value' => 'Test value',
  ),
),
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

PUT api/conversations/{conversationId}/custom_fields

Body Parameters

Parameter Type Required Description
customFields array (required) List of custom fields to be applied to the conversation. When updating a custom filed with type "Dropdown", in the value field you must provide a number (ID), not a textual value.

Customers

Create Customer

This method does not update existing customers. Method makes sure that the email address is unique and does not check uniqueness of other parameters. If the request contains email(s) and customers with all these emails already exist, no customer will be created.

If want to avoid creating duplicate customers with same "firstName", "lastName" and "phone", before executing this method use "List Customers" method to check if the customer already exists.

Example request:

const url = new URL("https://demo.freescout.net/api/customers");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "firstName": "Mark",
    "lastName": "Morrison",
    "phone": "777-777-777",
    "photoUrl": "https:\/\/example.org\/upload\/customer.jpg",
    "jobTitle": "Secretary",
    "photoType": "unknown",
    "address": {
        "city": "LA",
        "state": "California",
        "zip": "123123",
        "country": "US",
        "address": "1419 Westwood Blvd"
    },
    "notes": "Nothing special to say",
    "company": "Example, Inc",
    "emails": [
        {
            "value": "mark@example.org",
            "type": "home"
        }
    ],
    "phones": [
        {
            "value": "777-777-777",
            "type": "home"
        }
    ],
    "socialProfiles": [
        {
            "value": "@markexample",
            "type": "twitter"
        }
    ],
    "websites": [
        {
            "value": "https:\/\/example.org"
        }
    ]
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X POST "https://demo.freescout.net/api/customers" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"firstName":"Mark","lastName":"Morrison","phone":"777-777-777","photoUrl":"https:\/\/example.org\/upload\/customer.jpg","jobTitle":"Secretary","photoType":"unknown","address":{"city":"LA","state":"California","zip":"123123","country":"US","address":"1419 Westwood Blvd"},"notes":"Nothing special to say","company":"Example, Inc","emails":[{"value":"mark@example.org","type":"home"}],"phones":[{"value":"777-777-777","type":"home"}],"socialProfiles":[{"value":"@markexample","type":"twitter"}],"websites":[{"value":"https:\/\/example.org"}]}'

$client = new \GuzzleHttp\Client();
$response = $client->post("https://demo.freescout.net/api/customers", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "firstName" => "Mark",
                    "lastName" => "Morrison",
                    "phone" => "777-777-777",
                    "photoUrl" => "https://example.org/upload/customer.jpg",
                    "jobTitle" => "Secretary",
                    "photoType" => "unknown",
                    "address" => array(
   'city' => 'LA',
   'state' => 'California',
   'zip' => '123123',
   'country' => 'US',
   'address' => '1419 Westwood Blvd',
),
                    "notes" => "Nothing special to say",
                    "company" => "Example, Inc",
                    "emails" => array (
  0 => 
  array(
     'value' => 'mark@example.org',
     'type' => 'home',
  ),
),
                    "phones" => array (
  0 => 
  array(
     'value' => '777-777-777',
     'type' => 'home',
  ),
),
                    "socialProfiles" => array (
  0 => 
  array(
     'value' => '@markexample',
     'type' => 'twitter',
  ),
),
                    "websites" => array (
  0 => 
  array(
     'value' => 'https://example.org',
  ),
),
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

HTTP/1.1 201 Created
Resource-ID: 17

HTTP Request

POST api/customers

Body Parameters

Parameter Type Required Description
firstName string First name of the customer (max 40 characters).
lastName string Last name of the customer (max 40 characters).
phone string Phone number.
photoUrl string URL of the customer’s photo (max 200 characters).
jobTitle string Job title (max 60 characters).
photoType string Type of photo: unknown, gravatar, twitter, facebook, googleprofile, googleplus, linkedin.
address object Customer's address (country contains two-letter country code): { "city": "Los Angeles", "state": "California", "zip": "123123", "country": "US", "address": "1419 Westwood Blvd" }.
notes string Notes.
company string Company (max 60 characters).
emails object List of email entries: [ { "value": "mark@example.org", "type": "home" } ].
phones object List of phones entries: [ { "value": "777-777-777", "type": "home" } ].
socialProfiles object List of social profile entries: [ { "value": "@markexample", "type": "twitter" } ].
websites object List of website entries: [ { "value": "https:\/\/example.org" } ].

Get Customer

Example request:

const url = new URL("https://demo.freescout.net/api/customers/1");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/customers/1" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/customers/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "id": 75,
    "firstName": "Mark",
    "lastName": "Morrison",
    "company": "Example, Inc",
    "jobTitle": "Secretary",
    "photoType": "unknown",
    "photoUrl": "https:\/\/support.example.org\/storage\/customers\/7a10629fd2bae86563892b191f6677e7.jpg",
    "createdAt": "2020-07-23T12:34:12Z",
    "updatedAt": "2020-07-24T20:18:33Z",
    "notes": "Nothing special to say.",
    "customerFields": [
        {
            "id": 11,
            "name": "Age",
            "value": "25",
            "text": ""
        },
        {
            "id": 2,
            "name": "Gender",
            "value": "1",
            "text": "Male"
        }
    ],
    "_embedded": {
        "emails": [
            {
                "id": 1,
                "value": "mark@example.org",
                "type": "home"
            }
        ],
        "phones": [
            {
                "id": 0,
                "value": "777-777-777",
                "type": "home"
            }
        ],
        "social_profiles": [
            {
                "id": 0,
                "value": "@markexample",
                "type": "twitter"
            }
        ],
        "websites": [
            {
                "id": 0,
                "value": "https:\/\/example.org"
            }
        ],
        "address": {
            "city": "Los Angeles",
            "state": "California",
            "zip": "123123",
            "country": "US",
            "address": "1419 Westwood Blvd"
        }
    }
}

HTTP Request

GET api/customers/{customerId}

List Customers

Request parameters can be used to filter customers. By default customers are sorted by createdAt (from newest to oldest): ?sortField=createdAt&sortOrder=desc

Example request:

const url = new URL("https://demo.freescout.net/api/customers");

    let params = {
            "firstName": "John",
            "lastName": "Doe",
            "phone": "777-777-777",
            "email": "john@example.org",
            "updatedSince": "2021-01-07T12:00:03Z",
            "sortField": "firstName",
            "sortOrder": "asc",
            "page": "1",
            "pageSize": "100",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/customers?firstName=John&lastName=Doe&phone=777-777-777&email=john%40example.org&updatedSince=2021-01-07T12%3A00%3A03Z&sortField=firstName&sortOrder=asc&page=1&pageSize=100" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/customers", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "firstName" => "John",
            "lastName" => "Doe",
            "phone" => "777-777-777",
            "email" => "john@example.org",
            "updatedSince" => "2021-01-07T12:00:03Z",
            "sortField" => "firstName",
            "sortOrder" => "asc",
            "page" => "1",
            "pageSize" => "100",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

{
    "_embedded": {
        "customers": [
            {
                "id": 75,
                "firstName": "Mark",
                "lastName": "Morrison",
                "company": "Example, Inc",
                "jobTitle": "Secretary",
                "photoType": "unknown",
                "photoUrl": "https:\/\/support.example.org\/storage\/customers\/7a10629fd2bae86563892b191f6677e7.jpg",
                "createdAt": "2020-07-23T12:34:12Z",
                "updatedAt": "2020-07-24T20:18:33Z",
                "notes": "Nothing special to say.",
                "_embedded": {
                    "emails": [],
                    "phones": [],
                    "social_profiles": [],
                    "websites": [],
                    "address": {
                        "city": null,
                        "state": null,
                        "zip": null,
                        "country": null,
                        "address": null
                    }
                }
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 1,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/customers

Query Parameters

Parameter Required Description
firstName Filter customers by first name.
lastName Filter customers by last name.
phone Filter customers by phone number.
email Filter customers by email.
updatedSince Return only customers modified after the specified date.
sortField Sort the result by specified field: createdAt (default), firstName, lastName, updatedAt.
sortOrder Sort order: desc (default), asc.
page Page number.
pageSize Page size (defaults to 50).

Update Customer

Example request:

const url = new URL("https://demo.freescout.net/api/customers/1");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "firstName": "Mark",
    "lastName": "Morrison",
    "phone": "777-777-777",
    "photoUrl": "https:\/\/example.org\/upload\/customer.jpg",
    "jobTitle": "Secretary",
    "photoType": "unknown",
    "address": {
        "city": "LA",
        "state": "California",
        "zip": "123123",
        "country": "US",
        "address": "1419 Westwood Blvd"
    },
    "notes": "Nothing special to say",
    "company": "Example, Inc",
    "emails": [
        "mark@example.org",
        "admin@example.org"
    ],
    "emails_add": [
        "mark.new1@example.org",
        "mark.new2@example.org"
    ],
    "phones": [
        {
            "value": "777-777-777",
            "type": "home"
        }
    ],
    "socialProfiles": [
        {
            "value": "@markexample",
            "type": "twitter"
        }
    ],
    "websites": [
        {
            "value": "https:\/\/example.org"
        }
    ]
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X PUT "https://demo.freescout.net/api/customers/1" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"firstName":"Mark","lastName":"Morrison","phone":"777-777-777","photoUrl":"https:\/\/example.org\/upload\/customer.jpg","jobTitle":"Secretary","photoType":"unknown","address":{"city":"LA","state":"California","zip":"123123","country":"US","address":"1419 Westwood Blvd"},"notes":"Nothing special to say","company":"Example, Inc","emails":["mark@example.org","admin@example.org"],"emails_add":["mark.new1@example.org","mark.new2@example.org"],"phones":[{"value":"777-777-777","type":"home"}],"socialProfiles":[{"value":"@markexample","type":"twitter"}],"websites":[{"value":"https:\/\/example.org"}]}'

$client = new \GuzzleHttp\Client();
$response = $client->put("https://demo.freescout.net/api/customers/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "firstName" => "Mark",
                    "lastName" => "Morrison",
                    "phone" => "777-777-777",
                    "photoUrl" => "https://example.org/upload/customer.jpg",
                    "jobTitle" => "Secretary",
                    "photoType" => "unknown",
                    "address" => array(
   'city' => 'LA',
   'state' => 'California',
   'zip' => '123123',
   'country' => 'US',
   'address' => '1419 Westwood Blvd',
),
                    "notes" => "Nothing special to say",
                    "company" => "Example, Inc",
                    "emails" => array (
  0 => 'mark@example.org',
  1 => 'admin@example.org',
),
                    "emails_add" => array (
  0 => 'mark.new1@example.org',
  1 => 'mark.new2@example.org',
),
                    "phones" => array (
  0 => 
  array(
     'value' => '777-777-777',
     'type' => 'home',
  ),
),
                    "socialProfiles" => array (
  0 => 
  array(
     'value' => '@markexample',
     'type' => 'twitter',
  ),
),
                    "websites" => array (
  0 => 
  array(
     'value' => 'https://example.org',
  ),
),
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

PUT api/customers/{customerId}

Body Parameters

Parameter Type Required Description
firstName string First name of the customer (max 40 characters).
lastName string Last name of the customer (max 40 characters).
phone string Phone number.
photoUrl string URL of the customer’s photo (max 200 characters).
jobTitle string Job title (max 60 characters).
photoType string Type of photo: unknown, gravatar, twitter, facebook, googleprofile, googleplus, linkedin.
address object Customer's address (country contains two-letter country code): { "city": "Los Angeles", "state": "California", "zip": "123123", "country": "US", "address": "1419 Westwood Blvd" }.
notes string Notes.
company string Company (max 60 characters).
emails object List of emails (when this parameter is set the 'emails_add' parameter has no effect): [ "mark@example.org", "admin@example.org" ].
emails_add object Add emails to the customer: [ "mark.new1@example.org", "mark.new2@example.org" ].
phones object List of phones entries: [ { "value": "777-777-777", "type": "home" } ].
socialProfiles object List of social profile entries: [ { "value": "@markexample", "type": "twitter" } ].
websites object List of website entries: [ { "value": "https:\/\/example.org" } ].

Update Customer Fields

Example request:

const url = new URL("https://demo.freescout.net/api/customers/1/customer_fields");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "customerFields": [
        {
            "id": 37,
            "value": "Test value"
        }
    ]
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X PUT "https://demo.freescout.net/api/customers/1/customer_fields" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"customerFields":[{"id":37,"value":"Test value"}]}'

$client = new \GuzzleHttp\Client();
$response = $client->put("https://demo.freescout.net/api/customers/1/customer_fields", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "customerFields" => array (
  0 => 
  array(
     'id' => 37,
     'value' => 'Test value',
  ),
),
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

PUT api/customers/{customerId}/customer_fields

Body Parameters

Parameter Type Required Description
customerFields array (required) List of customer fields to be updated.

Mailboxes

List Mailboxes

Method returns mailboxes sorted by id. Request parameters can be used to filter mailboxes.

Example request:

const url = new URL("https://demo.freescout.net/api/mailboxes");

    let params = {
            "userId": "7",
            "page": "1",
            "pageSize": "100",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/mailboxes?userId=7&page=1&pageSize=100" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/mailboxes", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "userId" => "7",
            "page" => "1",
            "pageSize" => "100",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

{
    "_embedded": {
        "mailboxes": [
            {
                "id": 1,
                "name": "Demo Mailbox",
                "email": "support@support.example.org",
                "createdAt": "2020-08-09T10-09-00Z",
                "updatedAt": "2021-01-16T12-38-46Z"
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 1,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/mailboxes

Query Parameters

Parameter Required Description
userId Get maiboxes to which specified user has an access.
page Page number.
pageSize Page size (defaults to 50).

List Mailbox Custom Fields

Response Fields

Field Type Description
id number Custom field ID.
name string Name of the custom field.
type string Type of the custom field: singleline, multiline, dropdown, date, number
options object Contains options for dropdown custom fields.
required boolean Specifies if the custom field has to be filled.
sortOrder number Order of the custom field when displayed in the app.

Example request:

const url = new URL("https://demo.freescout.net/api/mailboxes/1/custom_fields");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/mailboxes/1/custom_fields" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/mailboxes/1/custom_fields", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "_embedded": {
        "custom_fields": [
            {
                "id": 18,
                "name": "Priority",
                "type": "dropdown",
                "options": {
                    "1": "Low",
                    "2": "Medium",
                    "3": "High"
                },
                "required": false,
                "sortOrder": 1
            },
            {
                "id": 19,
                "name": "Purchase Date",
                "type": "date",
                "options": null,
                "required": false,
                "sortOrder": 3
            },
            {
                "id": 37,
                "name": "Vendor",
                "type": "singleline",
                "options": "",
                "required": false,
                "sortOrder": 6
            },
            {
                "id": 38,
                "name": "Comments",
                "type": "multiline",
                "options": "",
                "required": false,
                "sortOrder": 7
            },
            {
                "id": 39,
                "name": "Amount",
                "type": "number",
                "options": "",
                "required": false,
                "sortOrder": 8
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 5,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/mailboxes/{mailboxId}/custom_fields

List Mailbox Folders

Example request:

const url = new URL("https://demo.freescout.net/api/mailboxes/1/folders");

    let params = {
            "userId": "7",
            "folderId": "3",
            "pageSize": "100",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/mailboxes/1/folders?userId=7&folderId=3&pageSize=100" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/mailboxes/1/folders", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "userId" => "7",
            "folderId" => "3",
            "pageSize" => "100",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "_embedded": {
        "folders": [
            {
                "id": 1681,
                "name": "Unassigned",
                "type": 1,
                "userId": null,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            },
            {
                "id": 1958,
                "name": "Mine",
                "type": 20,
                "userId": 145,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            },
            {
                "id": 1959,
                "name": "Starred",
                "type": 25,
                "userId": 145,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            },
            {
                "id": 1682,
                "name": "Drafts",
                "type": 30,
                "userId": null,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            },
            {
                "id": 1683,
                "name": "Assigned",
                "type": 40,
                "userId": null,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            },
            {
                "id": 1684,
                "name": "Closed",
                "type": 60,
                "userId": null,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            },
            {
                "id": 1685,
                "name": "Spam",
                "type": 80,
                "userId": null,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            },
            {
                "id": 1686,
                "name": "Deleted",
                "type": 110,
                "userId": null,
                "totalCount": 0,
                "activeCount": 0,
                "meta": null
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 24,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/mailboxes/{mailboxId}/folders

Query Parameters

Parameter Required Description
userId Get folders belonging to the specified user.
folderId Get specific folder.
pageSize Page size (defaults to 50).

Tags

List Tags

Method returns tags sorted by id.

Example request:

const url = new URL("https://demo.freescout.net/api/tags");

    let params = {
            "conversationId": "7",
            "page": "1",
            "pageSize": "100",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/tags?conversationId=7&page=1&pageSize=100" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/tags", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "conversationId" => "7",
            "page" => "1",
            "pageSize" => "100",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

{
    "_embedded": {
        "tags": [
            {
                "id": 1,
                "name": "overdue",
                "counter": 5,
                "color": 1
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 1,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/tags

Query Parameters

Parameter Required Description
conversationId Conversation ID.
page Page number.
pageSize Page size (defaults to 50).

Update Conversation Tags

This method allows to update tags for a conversation. The full list of tags must be sent in the request. If some tag specified does not exist it will be first created and then applied to the conversation. Any conversation tags which are not listed in the request will be removed. Send an empty list of tags to remove all tags.

Example request:

const url = new URL("https://demo.freescout.net/api/conversations/1/tags");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "tags": [
        "overdue",
        "refund"
    ]
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X PUT "https://demo.freescout.net/api/conversations/1/tags" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"tags":["overdue","refund"]}'

$client = new \GuzzleHttp\Client();
$response = $client->put("https://demo.freescout.net/api/conversations/1/tags", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "tags" => array (
  0 => 'overdue',
  1 => 'refund',
),
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

PUT api/conversations/{conversationId}/tags

Body Parameters

Parameter Type Required Description
tags array (required) List of tags (tag names) to be applied to the conversation.

Threads

Create Thread

This method adds a new customer reply, user reply or user note to a conversation.

Example request:

const url = new URL("https://demo.freescout.net/api/conversations/1/threads");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "type": "message",
    "text": "Plese let us know if you have any other questions.",
    "customer": {
        "email": "mark@example.org"
    },
    "user": 33,
    "imported": false,
    "status": "closed",
    "state": "published",
    "cc": [
        "anna@example.org",
        "bill@example.org"
    ],
    "bcc": [
        "bob@example.org",
        "andrea@example.org"
    ],
    "createdAt": "2020-03-16T14:07:23Z",
    "attachments": [
        {
            "fileName": "file.txt",
            "mimeType": "plain\/text",
            "data": "ZmlsZQ=="
        },
        {
            "fileName": "file2.txt",
            "mimeType": "plain\/text",
            "fileUrl": "https:\/\/example.org\/uploads\/file2.txt"
        }
    ]
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X POST "https://demo.freescout.net/api/conversations/1/threads" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"type":"message","text":"Plese let us know if you have any other questions.","customer":{"email":"mark@example.org"},"user":33,"imported":false,"status":"closed","state":"published","cc":["anna@example.org","bill@example.org"],"bcc":["bob@example.org","andrea@example.org"],"createdAt":"2020-03-16T14:07:23Z","attachments":[{"fileName":"file.txt","mimeType":"plain\/text","data":"ZmlsZQ=="},{"fileName":"file2.txt","mimeType":"plain\/text","fileUrl":"https:\/\/example.org\/uploads\/file2.txt"}]}'

$client = new \GuzzleHttp\Client();
$response = $client->post("https://demo.freescout.net/api/conversations/1/threads", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "type" => "message",
                    "text" => "Plese let us know if you have any other questions.",
                    "customer" => array(
   'email' => 'mark@example.org',
),
                    "user" => "33",
                    "imported" => "",
                    "status" => "closed",
                    "state" => "published",
                    "cc" => array (
  0 => 'anna@example.org',
  1 => 'bill@example.org',
),
                    "bcc" => array (
  0 => 'bob@example.org',
  1 => 'andrea@example.org',
),
                    "createdAt" => "2020-03-16T14:07:23Z",
                    "attachments" => array (
  0 => 
  array(
     'fileName' => 'file.txt',
     'mimeType' => 'plain/text',
     'data' => 'ZmlsZQ==',
  ),
  1 => 
  array(
     'fileName' => 'file2.txt',
     'mimeType' => 'plain/text',
     'fileUrl' => 'https://example.org/uploads/file2.txt',
  ),
),
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

HTTP/1.1 201 Created
Resource-ID: 25

HTTP Request

POST api/conversations/{conversationId}/threads

Body Parameters

Parameter Type Required Description
type string (required) Thread type: customer (customer reply), message (user reply), note (user note).
text string (required) The message text.
customer object Customer adding the thread (required if thread 'type' is 'customer'). Customer object must contain a valid customer id or an email address: { "id": 123 } or { "email": "mark@example.org" }. If the id field is defined, the email will be ignored. If the id is not defined, email is used to look up a customer. If a customer does not exist, a new one will be created. If a customer is matched either via id or email field, the rest of the optional fields is ignored.
user number ID of the user who is adding the thread (required if thread 'type' is 'message' or 'note').
imported boolean When imported is set to 'true', no outgoing emails or notifications will be generated.
status string Conversation status: active, pending, closed. Use this field to change conversation status when adding a thread. If not explicitly set, a customer reply will reactivate the conversation and support agent reply will make it pending.
state string Thread state: draft, published (default).
cc array List of CC email addresses.
bcc array List of BCC email addresses.
createdAt string Creation date to be used when importing conversations and threads in ISO 8601 date time format (can be used only when 'imported' field is set to true).
attachments array List of attachments to be attached to the thread. Attachment content can be passed in "data" parameter as BASE64 encoded string or as URL in "fileUrl" parameter.

Timelogs

List Conversation Timelogs

Get Time Tracking Module timelogs for a conversation. Timelogs are sorted from newest to oldest.

Example request:

const url = new URL("https://demo.freescout.net/api/conversations/1/timelogs");

    let params = {
            "page": "1",
            "pageSize": "100",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/conversations/1/timelogs?page=1&pageSize=100" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/conversations/1/timelogs", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "page" => "1",
            "pageSize" => "100",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

{
    "_embedded": {
        "timelogs": [
            {
                "id": 498,
                "conversationStatus": "pending",
                "userId": 1,
                "timeSpent": 219,
                "paused": false,
                "finished": true,
                "createdAt": "2021-04-21T13-24-01Z",
                "updatedAt": "2021-04-21T13-43-10Z"
            },
            {
                "id": 497,
                "conversationStatus": "active",
                "userId": 1,
                "timeSpent": 711,
                "paused": false,
                "finished": true,
                "createdAt": "2021-04-21T13-22-09Z",
                "updatedAt": "2021-04-21T13-43-10Z"
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 1,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/conversations/{conversationId}/timelogs

Query Parameters

Parameter Required Description
page Page number.
pageSize Page size (defaults to 50).

Users

Create User

This method does not update existing users. Method makes sure that the email address is unique and does not check uniqueness of other parameters. Method creates only regular Users and does not allow to create Administrators. No invitation email is being sent upon user creation. Created user does not have permissions to access any mailboxes by default.

Example request:

const url = new URL("https://demo.freescout.net/api/users");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "firstName": "John",
    "lastName": "Doe",
    "email": "johndoe@example.org",
    "password": "123456789",
    "alternateEmails": "johndoe777@example.org",
    "jobTitle": "Support agent",
    "phone": "777-777-777",
    "timezone": "Europe\/Paris",
    "photoUrl": "https:\/\/example.org\/upload\/customer.jpg"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X POST "https://demo.freescout.net/api/users" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"firstName":"John","lastName":"Doe","email":"johndoe@example.org","password":"123456789","alternateEmails":"johndoe777@example.org","jobTitle":"Support agent","phone":"777-777-777","timezone":"Europe\/Paris","photoUrl":"https:\/\/example.org\/upload\/customer.jpg"}'

$client = new \GuzzleHttp\Client();
$response = $client->post("https://demo.freescout.net/api/users", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "firstName" => "John",
                    "lastName" => "Doe",
                    "email" => "johndoe@example.org",
                    "password" => "123456789",
                    "alternateEmails" => "johndoe777@example.org",
                    "jobTitle" => "Support agent",
                    "phone" => "777-777-777",
                    "timezone" => "Europe/Paris",
                    "photoUrl" => "https://example.org/upload/customer.jpg",
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

HTTP/1.1 201 Created
Resource-ID: 17

HTTP Request

POST api/users

Body Parameters

Parameter Type Required Description
firstName string (required) First name of the user.
lastName string (required) Last name of the user.
email string (required) Email address.
password string User password.
alternateEmails string User alternate emails (comma separated).
jobTitle string Job title.
phone string Phone number.
timezone string User timezone. List of timezones: https://www.php.net/manual/en/timezones.php.
photoUrl string URL of the user's photo.

Get User

Example request:

const url = new URL("https://demo.freescout.net/api/users/1");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/users/1" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/users/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

{
    "id": 1,
    "firstName": "John",
    "lastName": "Doe",
    "email": "johndoe@example.org",
    "role": "admin",
    "alternateEmails": "johndoe777@example.org",
    "jobTitle": "Support agent",
    "phone": "+1867342345",
    "timezone": "Etc\/GMT-3",
    "photoUrl": "https:\/\/example.org\/upload\/customer.jpg",
    "language": "en",
    "createdAt": "2018-08-09T10-08-53Z",
    "updatedAt": "2020-12-22T14-54-35Z"
}

HTTP Request

GET api/users/{userId}

List Users

Request parameters can be used to filter users.

Example request:

const url = new URL("https://demo.freescout.net/api/users");

    let params = {
            "email": "johndoe@example.org",
            "page": "1",
            "pageSize": "100",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X GET -G "https://demo.freescout.net/api/users?email=johndoe%40example.org&page=1&pageSize=100" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->get("https://demo.freescout.net/api/users", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "email" => "johndoe@example.org",
            "page" => "1",
            "pageSize" => "100",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

{
    "_embedded": {
        "users": [
            {
                "id": 1,
                "firstName": "John",
                "lastName": "Doe",
                "email": "johndoe@example.org",
                "role": "admin",
                "alternateEmails": "johndoe777@example.org",
                "jobTitle": "Support agent",
                "phone": "+1867342345",
                "timezone": "Etc\/GMT-3",
                "photoUrl": "https:\/\/example.org\/upload\/customer.jpg",
                "language": "en",
                "createdAt": "2018-08-09T10-08-53Z",
                "updatedAt": "2020-12-22T14-54-35Z"
            }
        ]
    },
    "page": {
        "size": 50,
        "totalElements": 1,
        "totalPages": 1,
        "number": 1
    }
}

HTTP Request

GET api/users

Query Parameters

Parameter Required Description
email Look up user by email.
page Page number.
pageSize Page size (defaults to 50).

Delete User

This method deletes a user.

Example request:

const url = new URL("https://demo.freescout.net/api/users/1");

    let params = {
            "byUserId": "1",
            "assignTo": "assignTo[2]=7",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X DELETE "https://demo.freescout.net/api/users/1?byUserId=1&assignTo=assignTo%5B2%5D%3D7" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->delete("https://demo.freescout.net/api/users/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
    'query' => [
            "byUserId" => "1",
            "assignTo" => "assignTo[2]=7",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

DELETE api/users/{userId}

Query Parameters

Parameter Required Description
byUserId (required) ID of the user performing the deletion of the user.
assignTo Optional mapping array determining new assignee for conversations assigned to the user which is being deleted. Format: assignTo[MAILBOX_ID]=NEW_ASSIGNEE_ID.

Webhooks

Create Webhook

Example request:

const url = new URL("https://demo.freescout.net/api/webhooks");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Content-Type": "application/json",
    "Accept": "application/json",
}
let body = {
    "url": "https:\/\/example.org\/freescout",
    "events": [
        "convo.created"
    ]
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X POST "https://demo.freescout.net/api/webhooks" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db" \
    -H "Content-Type: application/json" \
    -d '{"url":"https:\/\/example.org\/freescout","events":["convo.created"]}'

$client = new \GuzzleHttp\Client();
$response = $client->post("https://demo.freescout.net/api/webhooks", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
            "Content-Type" => "application/json",
        ],
    'json' => [
                "url" => "https://example.org/freescout",
                    "events" => array (
  0 => 'convo.created',
),
            ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):

HTTP/1.1 201 Created
Resource-ID: 17

HTTP Request

POST api/webhooks

Body Parameters

Parameter Type Required Description
url string (required) URL that will be called when any of the events occur.
events array (required) List of events to track: convo.assigned, convo.created, convo.deleted, convo.moved, convo.status, convo.customer.reply.created, convo.agent.reply.created, convo.note.created, customer.created, customer.updated.

Delete Webhook

Example request:

const url = new URL("https://demo.freescout.net/api/webhooks/1");

let headers = {
    "X-FreeScout-API-Key": "c2ba609c687a3425402b9d881e5075db",
    "Accept": "application/json",
    "Content-Type": "application/json; charset=UTF-8",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));
curl -X DELETE "https://demo.freescout.net/api/webhooks/1" \
    -H "X-FreeScout-API-Key: c2ba609c687a3425402b9d881e5075db"

$client = new \GuzzleHttp\Client();
$response = $client->delete("https://demo.freescout.net/api/webhooks/1", [
    'headers' => [
            "X-FreeScout-API-Key" => "c2ba609c687a3425402b9d881e5075db",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (204):

HTTP/1.1 204 No Content

HTTP Request

DELETE api/webhooks/{webhookId}