# PhoneBook API Documentation

Phone Book | Database Admin

## Introduction

The PhoneBook's API is used to dynamically respond to changes in search queries live on screen without the need of refreshing/reloading the page.
All requests to the API are done using the POST http method, and the data submitted will use JSON.
Every response from the API where a response is nessesary will return with a JSON string.

## Authentication

API's listed below with the following tag: (API Requires Authentication),
will need to have credentials passed for the first call. If authentication is successful a cookie will be set that can be used
for any subsequent calls to the API. If authentication fails, the result will be a 403 code. Some authentication plugins may not
require any credentials to be passed. E.g: (IIS with LDAP enabled).
If an API call requires authentication, add the following to the POST request header:

    username: allice
    password: pass123

## Request Structure

- api
  - search
    - offset
    - count
    - order
  - import
  - export
    - tags
    - number
    - numbers
      - includeTags
- schema
- stats
  - ping
  - count
  - feedback
  - results
- feedback
  - subjects
  - submit
- translations
  - list
  - set
  - remove
- misc
  - rebuild

## Search API

The search API method will respond with a list of phone numbers that best matches the list of search tags / conditions given.
When sending tags, the first tag sent will be used as a wildcard for searching. To disable the wildcard, send another tag with a blank value.
The search count will limit the results returned to the number provided.
The search offset will offset the filter anding algortithm. For example:
An offset of 0 will only return numbers that match all of the search tags.
An offset of 1 will return all numbers that match the search tags or all the search tags minus one.
For example if 3 tags are sent, the numbers returned would have to have matched all of the tags or 2 of the tags. The results would return with the most matching numbers first.
In the new API, the search offset will simply offset the results returned, it will no longer change how the search algorithm scores results.
The search order will determine which way the results are ordered. E.g: Not defined or 0 will sort ascending, and a value of 1 will sort descending.

#### POST Request Header

    api: search

    offset: 0
    count: 100

    search: {"SEARCH":{"TAGS":["manager"],"ORDER":{"number":"ASC"},"LIMIT":[0,100]},"OUTPUT":{"OPTIONS":["showAvailableTags"],"ATTRIBUTES":["number","description"]}}

#### POST JSON Search Request Syntax

    {
        "SEARCH": {
            "TAGS": [
                "manager"
            ],
            "ORDER": {
                "number": "ASC"
            },
            "LIMIT": [
                0,
                100
            ]
        },
        "OUTPUT": {
            "OPTIONS": [
                "showAvailableTags"
            ],
            "ATTRIBUTES": [
                "number",
                "description"
            ]
        }
    }

#### SEARCH Basic Conditions

Where "email" is "john.smith@contoso.com"

    {
        "SEARCH": {
            "email": "john.smith@contoso.com"
        }
    }

Where "number" is "8005882300"

    {
        "SEARCH": {
            "number": 8005882300
        }
    }

Where "modified" is greater than "1561901285"

    {
        "SEARCH": {
            "modified[>]": 1561901285
        }
    }

Where "modified" is greater than or equal to "1561901285"

    {
        "SEARCH": {
            "modified[>=]": 1561901285
        }
    }

Where "firstname" does not equal "john"

    {
        "SEARCH": {
            "firstname[!]": "john"
        }
    }

Where "created" is between "1561900000" and "1561901285"

    {
        "SEARCH": {
            "created[<>]": [
                1561900000,
                1561901285
            ]
        }
    }

Where "created" is not between "1561900000" and "1561901285"

    {
        "SEARCH": {
            "created[><]": [
                1561900000,
                1561901285
            ]
        }
    }

#### SEARCH Wildcard Conditions

Where "lastname" contains "ill"

Results: miller, williams, willson

    {
        "SEARCH": {
            "lastname[~]": "ill"
        }
    }

Where "firstname" ends with "on"

Results: brandon, cameron, mason

    {
        "SEARCH": {
            "firstname[~]": "~on"
        }
    }

Where "firstname" is three characters long with an "o" in the middle

Results: bob, tom

    {
        "SEARCH": {
            "firstname[~]": "_o_"
        }
    }

Where "firstname" is three characters long with an "s" or "p" at the begining

Results: sam, pam

    {
        "SEARCH": {
            "firstname[~]": "[sp]am"
        }
    }

Where "firstname" is three characters long and does not contain an "s" or "p" at the begining

Results: sam, pam Exclude: cam, bam

    {
        "SEARCH": {
            "firstname[~]": "[!cb]am"
        }
    }

#### WHERE Complex Conditions

Where ( "email" equals "john.smith@contoso.com" and "number" equals "8005882300" ) or ("created" is less than "1561901285" )

    {
        "SEARCH": {
            "AND": {
                "email": "john.smith@contoso.com",
                "number": 8005882300
            },
            "OR": {
                "created[<]": 1561901285
            }
        }
    }

Where "email" starts with "@contoso.com" or "@contoso.org"

    {
        "SEARCH": {
            "email[~]": {
                "OR" [
                    "%@contoso.com",
                    "%@contoso.org"
                ]
            }
        }
    }

#### SEARCH Order Conditions

Where results are ordered by "firstname"

    {
        "SEARCH": {
            "ORDER": "firstname"
        }
    }

Where results are ordered by "firstname" in ascending order, than secondly by "lastname" in descending order.

    {
        "SEARCH": {
            "ORDER": {
                "firstname": "ASC",
                "lastname": "DESC"
            }
        }
    }

#### SEARCH Limits and Offsets

Where the number of results is limited to 100.

    {
        "SEARCH": {
            "LIMIT": 100
        }
    }

Get 100 results starting at the 200th result.

    {
        "SEARCH": {
            "LIMIT": [
                200,
                100
            ]
        }
    }

#### OUTPUT | OPTIONS | ATTRIBUTES

Dictates the data presented in the search output.

    {
        "OUTPUT": {
            "OPTIONS": [
                "showAvailableTags",     //Displays tags that can be used to further the search of the results.
                "showObjectTags"         //Displays tags associated with the resulting objects.
            ],
            "ATTRIBUTES": [              //List of schema attributes to show in the object results.
                "number",
                "description"
            ]
        }
    }

#### POST JSON Response Example

    {
        "tags": [
            "example",
            "tags",
        ],
        "objects": {
            "49698a4ebf": {
                "number": "1234",
                "description": "Example Number",
                "tags": [
                    "example",
                    "tags"
                ]
            }
        }
    }

#### POST JSON Live Demo

{ "SEARCH": { "TAGS": [ "manager" ], "ORDER": { "number": "ASC" }, "LIMIT": [ 0, 100 ] }, "OUTPUT": { "OPTIONS": [ "showAvailableTags" ], "ATTRIBUTES": [ "number", "description" ] } }

## Import API

API Requires Authentication

The import API allows numbers to be imported into the database using JSON.
This method allows for number editing and deleting as well.
When editing a number using the import API, you must first export the number you are going to edit, then modify the JSON (except for the number), then import the JSON using this API.
To delete a number, submit an empty number in one of the following ways:

    [
        {
            "number": "1234"
        }
    ]

    {
        "49b4604ae1": []
    }

    {
        "1234": []
    }

This API only responds with Fatal PHP errors.

#### POST Request Header

    api: import
    import: {"1234":{"description":"Test Number","tags":["example","tags"]}}

#### POST JSON Request Syntax Examples

    [
        {
            "number": "1234",
            "description": "Test Number",
            "tags": [
                "example",
                "tags"
            ]
        }
    ]

    {
        "49b4604ae1": {
            "description": "Test Number",
            "tags": [
                "example",
                "tags"
            ]
        }
    }

    {
        "1234": {
            "description": "Test Number",
            "tags": [
                "example",
                "tags"
            ]
        }
    }

#### POST JSON Live Demo

Sending this data will save to the database.
legacy:
[ { "number": "1234", "description": "Test Number", "tags": [ "example", "tags" ] } ]

## Export API

The Export API is split into three one method:
The tags method will export all tags at one time.
The number method will export a number's data from the provided number.
The numbers method will export all numbers.

#### POST Request Headers

    api: export
    export: number
    number: 1234

    api: export
    export: tags

    api: export
    export: numbers
    numbers: [1234, 5678]

    api: export
    export: numbers
    includeTags: 1
    numbers: [1234, 5678]

    api: export
    export: numbers
    numbers: [2834fa80ac, 3e834d4674]

    api: export
    export: objects
    includeTags: 1
    objects: [2834fa80ac, 3e834d4674]

#### POST Live Demo

export:
includeTags:
number:
["2834fa80ac", "3e834d4674"]

## Schema API

This API returns the current schema in json format. This is the only method that uses the GET HTTP method.

#### GET Request

./schema.cfg.json

#### GET Live Demo

## Statistics API

The statistics API will return stats about active sessions, phone lookup counts, and lookup tags.
The ping method will register a session on the system.
The count method will return a JSON object containing counts of various statistics, for example:

    {
        "objects": 100,                      //Objects stored in the database (Phone Numbers)
        "sessions": 10,                      //Current sessions in the last 5 minutes.
        "statistics": 10,                    //Statistic events gathered in the last hour.
        "tags": 1000,                        //Tags stored in the database. (Search Terms)
        "tags_objects": 10000,               //Tag to Object cross references in the database.
        "translations": 30,                  //Translation instructions stored in the database.
        "average_results_returned": 10,      //The average result amount reported back from Phone Book clients.
        "average_response_speed": 0.00025,   //The average response speed of the API as reported from the Phone Book clients.
        "top_search_queries": {              //The top 100 search queries (key) with how many times they have been searched (value) in the last hour.
            "example": 5,
            "tags": 3
        }
    }

The feedback method will accept a JSON string with a few properties:
apispeed: which is the delay between when the last API request was sent and then received.
count: which is the number of objects returned from the last API search request.
query: which is an array of tags used in the last API search request.
These results are then compiled into the database to be processed by some other system or client.
The results method will return the compiled list of feedback queries in reverse chronological order.

#### POST Request Headers

    api: stats
    stats: ping

    api: stats
    stats: count

    api: stats
    stats: results

    api: stats
    stats: feedback
    feedback: {"apispeed":0.00025,"count":10,"query":["example","tags"]}

#### POST Live Demo

stats:
{ "apispeed": 0.00025, "count": 10, "query": [ "example", "tags" ] }

## Feedback API

The feedback API will send an SMTP email to the configured email with whatever is submitted via this API.

The subjects api will return a JSON array with the allowed subjects for the feedback request.

The submit api requires two extra fields, subject and body. This api will send an email to the configured recipient.

#### POST Request Headers

    api: feedback
    feedback: subjects

    api: feedback
    feedback: submit
    subject: [string]
    body: [string]

#### POST Live Demo

feedback:
subject:
body:

## Translations API

API Requires Authentication

Only the "set" and "remove" api's require authentication. The "list" api is public.

The translations api is used to set and remove translation instructions the import API uses when importing new objects.

The list api will return all translations as a JSON array.

The set api takes a from and to parameter. The "from" parameter is the translation of what the tag is when it is imported via the API, and the "to" parameter is what the tag(s) (space delimited) will be translated into when stored in the database.
The "from" parameter must have a value. The "to" parameter can be blank (meaning that a tag will be removed when translated).

The remove api will remove the specified instruction from the database.

#### POST Request Headers

    api: translations
    translations: list

    api: translations
    translations: set
    from: [string]
    to: [string]

    api: translations
    translations: remove
    from: [string]

#### POST Live Demo

translations:
from:
to:

## Misc API

API Requires Authentication

The rebuild api will purge and rebuild the object / tags index.

#### POST Request Headers

    api: misc
    misco: rebuild

#### POST Live Demo

misc: