NAV
php bash javascript

Info

Welcome to the generated API reference. Get Postman Collection

This API is being developed constantly with more endpoints being added regularly.

Authentication

All endpoints require authentication via the Authorization: Bearer {token} header. There are 2 ways to get the token:

Personal Access Tokens

  1. Log in to your EasyPractice account (or create a new account)
  2. Go to the Apps page and activate the API app.
  3. Go to the API Settings page
  4. In the Personal Access Tokens section click on the Create New Token button to generate a new token.
  5. Copy the new generated token. You will NOT be able to view it again, so keep it safe. In case you lose it, you can generate as many new tokens as you'd like.
  6. Add an Authorization header to your requests with the value of Bearer {token} where {token} is your token you copied earlier.

OAuth2 flow

We also support the standard OAuth2 flow for authenticating requests. Your app will be able to "Request access to EasyPractice", where the user will be able to either Authorize or Deny the request. This is a much more user-friendly approach, but requires more set up in advance.

If you would like to set up OAuth2 flow with our API, please get in touch with us at support@easypractice.net.

Clients

List clients.


Requires authentication Returns all of user's clients. Use the filter options provided to narrow down the results. For example: GET api/v1/clients?hasEmail&email=asc

Example request:


$client = new \GuzzleHttp\Client();
$response = $client->get("api/v1/clients", [
    'headers' => [
            "Authorization" => "Bearer {token}",
        ],
    'query' => [
            "active" => "1",
            "inactive" => "1",
            "has_email" => "1",
            "has_phone" => "1",
            "cpr" => "1205001234",
            "order_by_name" => "asc",
            "order_by_date" => "desc",
            "order_by_email" => "asc",
            "page_size" => "20",
            "page" => "4",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl -X GET -G "https://system.easypractice.net/api/v1/clients" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://system.easypractice.net/api/v1/clients");

    let params = {
            "active": "1",
            "inactive": "1",
            "has_email": "1",
            "has_phone": "1",
            "cpr": "1205001234",
            "order_by_name": "asc",
            "order_by_date": "desc",
            "order_by_email": "asc",
            "page_size": "20",
            "page": "4",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "data": [
        {
            "id": 1,
            "name": "John Smith",
            "email": "john@mydomain.dk",
            "phone": "61175736",
            "address": "159 Bailey Brooks",
            "zip": "W10 6DY",
            "city": "Copenhagen",
            "cpr": "1598431234",
            "notes": "Notes about John",
            "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/5ea799d8476cbe0b1965c39e7c7dbd99?d=mm&s=200",
            "created_at": "2019-04-16 11:54:42"
        },
        {
            "id": 2,
            "name": "Mary Williams",
            "email": "m.williams@mycompany.dk",
            "phone": "43612915",
            "address": "3 Mike Common",
            "zip": "NG34 9HJ",
            "city": "Copenhagen",
            "cpr": "3574261234",
            "notes": "",
            "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/5ea799d8476cbe0b1965c39e7c7dbd99?d=mm&s=200",
            "created_at": "2019-04-20 08:14:21"
        }
    ],
    "links": {
        "...": "..."
    },
    "meta": {
        "...": "..."
    }
}

HTTP Request

GET api/v1/clients

Query Parameters

Parameter Status Description
active optional Return only the active clients.
inactive optional Return only the inactive clients.
has_email optional Return only the clients with an email.
has_phone optional Return only the clients with phone number.
cpr optional Return only the clients with a given CPR number.
order_by_name optional =[asc|desc] Order results by name.
order_by_date optional =[asc|desc] Order results by creation date.
order_by_email optional =[asc|desc] Order results by email.
page_size optional (default: 10) The number of items per page.
page optional (default: 1) The page number.

Create client.


Requires authentication Creates a new client with the given data.

Example request:


$client = new \GuzzleHttp\Client();
$response = $client->post("api/v1/clients", [
    'headers' => [
            "Authorization" => "Bearer {token}",
            "Content-Type" => "application/json",
        ],
    'json' => [
            "name" => "John Doe",
            "email" => "john.doe@example.com",
            "ean" => "5789012345678",
            "phone" => "7380111233",
            "zip" => "M14 5PT",
            "city" => "Manchester",
            "cpr" => "0123456789",
            "notes" => "Some notes",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl -X POST "https://system.easypractice.net/api/v1/clients" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"name":"John Doe","email":"john.doe@example.com","ean":"5789012345678","phone":"7380111233","zip":"M14 5PT","city":"Manchester","cpr":"0123456789","notes":"Some notes"}'
const url = new URL("https://system.easypractice.net/api/v1/clients");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "name": "John Doe",
    "email": "john.doe@example.com",
    "ean": "5789012345678",
    "phone": "7380111233",
    "zip": "M14 5PT",
    "city": "Manchester",
    "cpr": "0123456789",
    "notes": "Some notes"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (201):

{
    "message": "Created",
    "data": {
        "id": 123,
        "name": "John Doe",
        "email": "john.doe@example.com",
        "ean": "5789012345678",
        "phone": "7380111233",
        "zip": "M14 5PT",
        "city": "Manchester",
        "cpr": "0123456789",
        "notes": "Some notes"
    }
}

Example response (422):

{
    "error": {
        "message": "The given data is invalid",
        "status_code": 422
    },
    "data": {
        "name": [
            "The Name field is required."
        ]
    }
}

HTTP Request

POST api/v1/clients

Body Parameters

Parameter Type Status Description
name string required The Name of the client.
email string optional The Email of the client.
ean string optional The EAN-number of the client.
phone string optional The Phone of the client without the country code.
zip string optional The Zip/Postcode of the client.
city string optional The City of the client.
cpr string optional The CPR of the client.
notes string optional The Notes of the client.

Show client.


Requires authentication Returns the client data for a given ID.

Example request:


$client = new \GuzzleHttp\Client();
$response = $client->get("api/v1/clients/1", [
    'headers' => [
            "Authorization" => "Bearer {token}",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl -X GET -G "https://system.easypractice.net/api/v1/clients/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://system.easypractice.net/api/v1/clients/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "id": 1,
    "name": "John Smith",
    "email": "john@mydomain.dk",
    "phone": "61175736",
    "address": "159 Bailey Brooks",
    "zip": "W10 6DY",
    "city": "Copenhagen",
    "cpr": "1598431234",
    "notes": "Notes about John",
    "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/5ea799d8476cbe0b1965c39e7c7dbd99?d=mm&s=200",
    "created_at": "2019-04-16 11:54:42"
}

Example response (404):

{
    "error": {
        "message": "Not Found",
        "status_code": 404
    }
}

HTTP Request

GET api/v1/clients/{client}

Update client.


Requires authentication Updates the client.

Example request:


$client = new \GuzzleHttp\Client();
$response = $client->put("api/v1/clients/1", [
    'headers' => [
            "Authorization" => "Bearer {token}",
            "Content-Type" => "application/json",
        ],
    'json' => [
            "name" => "John Doe",
            "email" => "john.doe@example.com",
            "ean" => "5789012345678",
            "phone" => "7380111233",
            "zip" => "M14 5PT",
            "city" => "Manchester",
            "cpr" => "0123456789",
            "notes" => "Some notes",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl -X PUT "https://system.easypractice.net/api/v1/clients/1" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"name":"John Doe","email":"john.doe@example.com","ean":"5789012345678","phone":"7380111233","zip":"M14 5PT","city":"Manchester","cpr":"0123456789","notes":"Some notes"}'
const url = new URL("https://system.easypractice.net/api/v1/clients/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "name": "John Doe",
    "email": "john.doe@example.com",
    "ean": "5789012345678",
    "phone": "7380111233",
    "zip": "M14 5PT",
    "city": "Manchester",
    "cpr": "0123456789",
    "notes": "Some notes"
}

fetch(url, {
    method: "PUT",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "message": "Updated",
    "data": {
        "id": 1,
        "name": "John Doe",
        "email": "john.doe@example.com",
        "ean": "5789012345678",
        "phone": "7380111233",
        "zip": "M14 5PT",
        "city": "Manchester",
        "cpr": "0123456789",
        "notes": "Some notes"
    }
}

Example response (422):

{
    "error": {
        "message": "The given data is invalid",
        "status_code": 422
    },
    "data": {
        "name": [
            "The Name field is required."
        ]
    }
}

HTTP Request

PUT api/v1/clients/{client}

PATCH api/v1/clients/{client}

Body Parameters

Parameter Type Status Description
name string required The Name of the client.
email string optional The Email of the client.
ean string optional The EAN-number of the client.
phone string optional The Phone of the client without the country code.
zip string optional The Zip/Postcode of the client.
city string optional The City of the client.
cpr string optional The CPR of the client.
notes string optional The Notes of the client.

Delete client.


Requires authentication Removes the client from the user's account and all of its associated data, such as bookings/journals/messages. Use with caution.

Example request:


$client = new \GuzzleHttp\Client();
$response = $client->delete("api/v1/clients/1", [
    'headers' => [
            "Authorization" => "Bearer {token}",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl -X DELETE "https://system.easypractice.net/api/v1/clients/1" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://system.easypractice.net/api/v1/clients/1");

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "DELETE",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "message": "Deleted"
}

HTTP Request

DELETE api/v1/clients/{client}

Invoices

List invoices.


Requires authentication Returns all of user's invoices. Use the filter options provided to narrow down the results. For example: GET api/v1/invoices?client_id=123

Example request:


$client = new \GuzzleHttp\Client();
$response = $client->get("api/v1/invoices", [
    'headers' => [
            "Authorization" => "Bearer {token}",
        ],
    'query' => [
            "client_id" => "54347",
            "paid" => "1",
            "unpaid" => "1",
            "order_by_number" => "asc",
            "page_size" => "20",
            "page" => "4",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl -X GET -G "https://system.easypractice.net/api/v1/invoices" \
    -H "Authorization: Bearer {token}"
const url = new URL("https://system.easypractice.net/api/v1/invoices");

    let params = {
            "client_id": "54347",
            "paid": "1",
            "unpaid": "1",
            "order_by_number": "asc",
            "page_size": "20",
            "page": "4",
        };
    Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));

let headers = {
    "Authorization": "Bearer {token}",
    "Accept": "application/json",
    "Content-Type": "application/json",
}

fetch(url, {
    method: "GET",
    headers: headers,
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "data": [
        {
            "id": 1,
            "draft": false,
            "client_id": 123,
            "number": 454,
            "date": "2019-04-20T00:00:00+01:00",
            "due_date": "2019-04-20T00:00:00+01:00",
            "executed_date": "2019-04-20T00:00:00+01:00",
            "paid_date": "2019-04-20T00:00:00+01:00",
            "sent": true,
            "sent_via_ean": false,
            "paid": true,
            "credited": false,
            "status": "paid",
            "clientname": "John Doe",
            "clientcpr": "123456-7890",
            "clientaddress": "54 Harry Lane",
            "clientzip": "1234",
            "clientcity": "Copenhagen",
            "payment_type": "card",
            "currency": "DKK",
            "total": 625,
            "lines": [
                {
                    "id": 23,
                    "invoice_id": 1,
                    "position": 0,
                    "amount": 1,
                    "price": 500,
                    "vat": true,
                    "vat_rate": 25,
                    "total_without_vat": 500,
                    "total": 625,
                    "text": "Client appointment",
                    "comment": "",
                    "booking_description": "Appointment Tuesday 16 April 2019, 16:05"
                }
            ]
        },
        {
            "id": 2,
            "draft": false,
            "client_id": 22,
            "number": 455,
            "date": "2019-05-01T00:00:00+01:00",
            "due_date": "2019-05-01T00:00:00+01:00",
            "executed_date": "2019-05-01T00:00:00+01:00",
            "paid_date": "2019-05-01T00:00:00+01:00",
            "sent": true,
            "sent_via_ean": false,
            "paid": true,
            "credited": false,
            "status": "paid",
            "clientname": "Jaimes Armsworth",
            "clientcpr": "121212-7890",
            "clientaddress": "4 Snow Street",
            "clientzip": "5454",
            "clientcity": "Copenhagen",
            "payment_type": "card",
            "currency": "DKK",
            "total": 1500,
            "lines": [
                {
                    "...": "..."
                },
                {
                    "...": "..."
                }
            ]
        }
    ],
    "links": {
        "...": "..."
    },
    "meta": {
        "...": "..."
    }
}

HTTP Request

GET api/v1/invoices

Query Parameters

Parameter Status Description
client_id optional Return only invoices belonging to this client ID.
paid optional Return only the paid invoices.
unpaid optional Return only the unpaid invoices.
order_by_number optional =[asc|desc] Order results by invoice number.
page_size optional (default: 10) The number of items per page.
page optional (default: 1) The page number.

Mark an invoice as paid


Requires authentication

Example request:


$client = new \GuzzleHttp\Client();
$response = $client->post("api/v1/invoices/1/mark-as-paid", [
    'headers' => [
            "Authorization" => "Bearer {token}",
            "Content-Type" => "application/json",
        ],
    'json' => [
            "date" => "2019-05-16",
            "payment_type" => "card",
            "amount" => "1500",
            "currency" => "DKK",
        ],
]);
$body = $response->getBody();
print_r(json_decode((string) $body));
curl -X POST "https://system.easypractice.net/api/v1/invoices/1/mark-as-paid" \
    -H "Authorization: Bearer {token}" \
    -H "Content-Type: application/json" \
    -d '{"date":"2019-05-16","payment_type":"card","amount":1500,"currency":"DKK"}'
const url = new URL("https://system.easypractice.net/api/v1/invoices/1/mark-as-paid");

let headers = {
    "Authorization": "Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "application/json",
}

let body = {
    "date": "2019-05-16",
    "payment_type": "card",
    "amount": 1500,
    "currency": "DKK"
}

fetch(url, {
    method: "POST",
    headers: headers,
    body: body
})
    .then(response => response.json())
    .then(json => console.log(json));

Example response (200):

{
    "message": "The Invoice 123 was marked as payed on 2019-05-20 with the payment method Card"
}

Example response (400):

{
    "error": {
        "message": "The Invoice 123 is already paid.",
        "status_code": 400
    }
}

Example response (422):

{
    "error": {
        "message": "The given data is invalid",
        "status_code": 422
    },
    "data": {
        "payment_type": [
            "The selected Payment type is invalid."
        ]
    }
}

HTTP Request

POST api/v1/invoices/{id}/mark-as-paid

Body Parameters

Parameter Type Status Description
date date required The Date of the payment.
payment_type string required The Payment method used. Available values: 'transfer', 'cash', 'card', 'other', 'mobile_pay' (Denmark only), 'health_insurance', 'swish' (Sweden only)
amount float required The Amount of the payment.
currency string required The Currency of the payment.

Errors

The EasyPractice API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is malformed or otherwise invalid. Please double check our API documentation for allowed request parameters.
401 Unauthorized -- Your API key is incorrect or has been revoked. Check the Authentation section on how to get an API token.
403 Forbidden -- You do not have access rights to the resource. Your API key might be limited to what you can access.
404 Not Found -- The resource was not found.
405 Method Not Allowed -- The HTTP method you used was incorrect and unsupported for the specific endpoint.
422 Unprocessable Entity -- Some or all data provided is invalid for the type of request. Please see the response data for clues about which of the data provided is invalid and why.
429 Too Many Requests -- You are making too many requests.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarially offline for maintanance. Please try again later.

Help

If you have any questions regarding our API, you can contact us at support@easypractice.net.

EasyPractice © 2016