Alterra.ai FAQ API
Alterra is a QnA engine that answers straightforward questions. Convert your static FAQ files, knowledge bases, user guides or canned responses to a question answering system. Using this API you may build your own conversational virtual agents and messenger bots, use it for site search or embed it in sales or support workflows. You may integrate it with live chat, call center, or tech support solutions. You may build a fully autonomous solution or pair it up with live agents.
This API finds answers in a set of FAQ articles. Each article is a question – answer pair. (It may also contain additional information.)
Powered by Deep Learning algorithms, the system requires a training corpus of historic user queries with the correct answers assigned to them. The bigger the corpus, the higher the search quality. You upload your training corpus into the system via this API, too.
The system keeps a log of queries it receives. Past queries may be assigned correct answers, and added to the training corpus.
The API has four main parts:
- performing search,
- uploading and editing the FAQ articles,
- working with the training corpus and query log,
- managing FAQ settings
The first part is used during the serving time. It performs actual search. The user asks a question or enters a search query; you pass the query to this API, and it returns the search results, ordered by relevance.
The other three parts are used ahead of time, to upload and edit data, and train machine learning.
All APIs defined here follow the REST paradigm.
All methods here require an API key. It is passed as “Authorization” header in the request. You automatically receive your API key when you self-register for the service on Alterra’s website.
All GET
methods take arguments as CGI parameters in the URL.
All POST
and PUT
requests take arguments in the request body, which should be in JSON format.
All methods return JSON. It may be empty if the only result is an operation status which is reported as HTTP status code.
The end-point for this API is at http://next.alterra.ai/api/faq/v1/
Inference
Search API
This is the inference part. It is used during the serving time. It performs actual search in your FAQ. The user queries your application, you pass the query to this API, which returns the search results, ordered by relevance.
Given a user query, find relevant answer(s) in the FAQ: GET /api/faq/v1/search
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
query |
query | string | Y | user query |
format |
query | string | N | Format of answer field for corpus (plaintext or html) |
Example:
curl -H 'Authorization: YOUR_API_KEY' 'https://next.alterra.ai/api/faq/v1/search?query=How+can+I+contact+you&format=plaintext'
Server reply
Type | Description |
---|---|
Search response object | A search response object (set of search results, ordered by relevance) |
Example:
{
"search_id": "73b61636-29b1-4bee-8845-3bc0ffe9a86a",
"results":
[
{
"article_id": "42",
"question": "Where can I find more bots?"
},
{
"article_id": "43",
"question": "Who can see me ‘online’?",
"snippet": "People can only see you online if you’re sharing your last seen status with them."
}
]
}
Given a search request object, find relevant answer(s) in the FAQ: POST /api/faq/v1/search
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
body |
body | Search request object | Y | Search request object |
Example:
curl -H 'Content-Type:application/json' -H 'Authorization: YOUR_API_KEY' 'https://next.alterra.ai/api/faq/v1/search' -d {'query': 'How can I contact you' 'format': 'plaintext'}
Server reply
Type | Description |
---|---|
Search response object | A search response object (set of search results, ordered by relevance) |
Example:
{
"search_id": "73b61636-29b1-4bee-8845-3bc0ffe9a86a",
"results":
[
{
"article_id": "42",
"question": "Where can I find more bots?"
},
{
"article_id": "43",
"question": "Who can see me ‘online’?",
"snippet": "People can only see you online if you’re sharing your last seen status with them."
}
]
}
Feedback API
You may optionally collect user feedback on the quality of the delivered search results.
Record a user feedback to search results: POST /api/faq/v1/feedback
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
body |
body | Feedback request object | Y | Feedback request object |
Server reply
Feedback recorded
This concludes the inference part of the API.
ML Training and Training Corpus Management
Train API
Train Machine Learning: POST /api/faq/v1/train
This API invokes re-training of ML algorithms and re-indexing data, after completing editing the training corpus.
Arguments
No arguments
Server reply
Train successful
Articles API
This part is used for uploading and editing FAQ articles.
Each POST
, PUT
or DELETE
endpoint may be used with an optional CGI parameter train=true
to
re-train ML models after API call succeeds. If you plan a run of consequent API calls updating
the corpus, it is advised not to use train=true
, but rather invoke
train API call for
re-training of the ML models after finishing editing the training corpus with this API.
Each GET
endopoint may be used with optional CGI parameters queries=true
(articles in the
result list will contain the array of query texts) or query_objects=true
(articles in the
result list will contain the array of query objects).
Get a list of articles: GET /api/faq/v1/articles
Export articles from the system. It could be used to retrieve all articles, or a portion of (with pagination).
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
offset |
query | integer | N | Offset in the sorted list of articles. May be negative (Then is applied from the end of the list) Default value is 0 |
limit |
query | integer | N | Maximum number of articles to return. Default value is 10 |
queries |
query | boolean | N | return queries with articles |
query_objects |
query | boolean | N | return query objects with articles |
common |
query | string | N | Common corpus name |
Example:
curl -H 'Authorization: YOUR_API_KEY' 'https://next.alterra.ai/api/faq/v1/articles?offset=42&limit=2&queries=true'
Server reply
Type | Description |
---|---|
List of Article objects | List of articles |
Example:
[
{
"article_id": 42,
"question": "Where can I find more bots?",
"answer": "There is no official store at the moment, so you‘ll have to ask your friends or search the web for now. We’re pretty sure you’ll find some bots to play with.",
"queries": [
"where are bots?",
"more bots",
"bot store"
]
},
{
"article_id": 43,
"question": "Who can see me ‘online’?",
"snippet": "People can only see you online if you’re sharing your last seen status with them.",
"answer": "People can only see you online if you’re sharing your last seen status with them. There is one exception to this: people will be able to see you online for a brief period when you send them a message in a one-on-one chat or in a group where you both are members.",
"queries": []
}
]
Add new articles: POST /api/faq/v1/articles
Upload new article(s) to the system. Either all or none article IDs must be provided. By default if all IDs are provided this method will succeed only if all these IDs are available (not used by any other article).
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
body |
body | List of Article objects | Y | new articles to upload |
replace |
query | boolean | N | If true , all previously existing articles will be erased before adding |
partial |
query | boolean | N | If true , a subset of given articles with available IDs will be added |
Example:
curl -X POST -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' 'https://next.alterra.ai/api/faq/v1/articles?replace=true&train=true' -d '
[
{
"id": "42",
"question": "Where can I find more bots?",
"snippet": "There is no official store yet",
"answer": "There is no official store at the moment, so you‘ll have to ask your friends or search the web for now. We’re pretty sure you’ll find some bots to play with.",
"queries": [
"where are bots?",
"more bots",
"bot store"
]
},
{
"id": "54",
"question": "Who can see me ‘online’?",
"answer": "People can only see you online if you’re sharing your last seen status with them. There is one exception to this: people will be able to see you online for a brief period when you send them a message in a one-on-one chat or in a group where you both are members."
}
]
'
Server reply
Type | Description |
---|---|
List of integers | List of identifiers of just uploaded articles. |
If the articles were uploaded with specific idsthen these ids are honored. If the articles were uploaded without ids then the system automatically assigns new ids to them. ids of all just uploaded articles are returned here. |
Example:
[42,54]
Update existing articles: PUT /api/faq/v1/articles
Edit (replace) existing article(s). All article IDs must be provided. By default this method will succeed only if corpus already has an article for every provided ID
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
body |
body | List of Article objects | Y | data for articles you are updating |
partial |
query | boolean | N | Skip input articles with unknown ids |
Example:
curl -X PUT -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' 'https://next.alterra.ai/api/faq/v1/articles?train=true' -d '
[
{
"id": 42,
"question": "Where can I find more bots?",
"snippet": "There is no official store yet",
"answer": "There is no official store at the moment, so you‘ll have to ask your friends or search the web for now. We’re pretty sure you’ll find some bots to play with.",
"queries": [
"where are bots?",
"more bots",
"bot store"
]
},
{
"id": 54,
"question": "Who can see me ‘online’?",
"answer": "People can only see you online if you’re sharing your last seen status with them. There is one exception to this: people will be able to see you online for a brief period when you send them a message in a one-on-one chat or in a group where you both are members."
}
]
'
Server reply
Type | Description |
---|---|
List of integers | List of ids for replaced articles (as a confirmation). |
Example:
[42,54]
Delete all articles: DELETE /api/faq/v1/articles
Delete all article
Arguments
No arguments
Server reply
Articles successfully deleted
Change answer format for articles in FAQ: PUT /api/faq/v1/articles/change_format
Change answer format for existing articles
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
partial |
query | boolean | N | Skip input articles with unknown ids |
format |
query | string | Y | Answer format (plaintext or html) |
train |
query | boolean | N | Re-train corpus afterwards |
Server reply
Answer format was successfully changed
Get one article: GET /api/faq/v1/articles/{articleId}
Export one specific article, identified by article_id, from the system.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | ID of the article that needs to be fetched |
queries |
query | boolean | N | Return queries with articles |
query_objects |
query | boolean | N | return query objects with articles |
Server reply
Type | Description |
---|---|
Article object | successful operation |
Delete one article: DELETE /api/faq/v1/articles/{articleId}
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | Article id to delete |
Server reply
Article successfully deleted
Queries API
This part is used for working with the query log and training corpus for Machine Learning.
There are two types of queries:
- All queries entered by users in the past – see Log entries
- Queries admitted to the training corpus – see Queries
This API deals with the latter.
These two sets have a big overlap by may be not equal. Indeed, only legitimate user queries shall be added to the training corpus. Garbage and spam shall be discarded. On the other hand, some queries in the training corpus may come from sources other than logged user queries (e.g. other public training corpora).
Each POST
, PUT
or DELETE
endpoint may be used with an optional CGI parameter train=true
to re-train ML models after API call succeeds. If you plan a run of consequent API calls
updating the corpus, it is advised not to use train=true
, but rather invoke
train API call
for re-training of the ML models after finishing editing the training corpus with this API.
Get a list of queries: GET /api/faq/v1/queries
Export query objects from the training corpus (with pagination). It could be used to retrieve all queries, or a portion of.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
offset |
query | integer | N | Offset in the sorted list of queries. May be negative (Then is applied from the end of the list) |
limit |
query | integer | N | Number of queries to return. Default value is 100 |
common |
query | string | N | Common corpus name |
Example:
curl -H 'Authorization: YOUR_API_KEY' 'https://next.alterra.ai/api/faq/v1/queries?offset=1138&limit=1'
Server reply
Type | Description |
---|---|
List of Query objects | List of queries |
Example:
[
{
"hash": "23db4",
"text": "Who should I contact about my booking?",
"article_id": 2
}
]
Update queries: POST /api/faq/v1/queries
Add new queries to the training corpus or update existing queries.
Only unique queries will be actually added. Existing queries will be replaced. The result
will contain the list of query hashes corresponding to the given list of queries. Duplicate
queries will have the same hashes. article_id
shall be determined by human labelers and
must be set in all queries.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
body |
body | List of Query objects | Y | New queries to upload |
partial |
query | boolean | N | If true , a subset of given queries with known article_ids will be added |
train |
query | boolean | N | Re-train corpus afterwards |
article_id
field must be set in all queries
Example:
curl -X POST -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' 'https://next.alterra.ai/api/faq/v1/queries?train=true' -d '
[
{
"text": "Who should I contact about my booking?",
"article_id": 2
},
{
"text": "Where is my confirmation?",
"article_id": 5
},
{
"text": "WHERE IS MY CONFIRMATION???",
"article_id": 5
},
]
'
Server reply
Type | Description |
---|---|
List of strings | List of respective query hashes. |
Example:
["67F227A57F1A496F", "47E25DF1D9BAF663", "47E25DF1D9BAF663"]
Delete all queries: DELETE /api/faq/v1/queries
Delete all queries associated with FAQ articles
Arguments
No arguments
Server reply
Queries successfully deleted
Create new queries: POST /api/faq/v1/queries/new
Add new queries and skip existing queries.
Only new queries will be added from given set, existing queries will not be affected.
If article_id
field is not set in a query or is zero, the query is assumed to be unlabeled,
and is stored for future labeling.
The result will contain numbers of successfully added, skipped or invalid queries. Number
of invalid queries can only be non-zero if endpoint is called with partial=true
. In that
case the number of invalid queries is the number of queries skipped because of
unknown article_id
.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
body |
body | List of Query objects | Y | New queries to upload |
partial |
query | boolean | N | If true a subset of given queries with known article_ids will be added |
train |
query | boolean | N | Re-train corpus afterwards |
Example:
curl -X POST -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' 'https://next.alterra.ai/api/faq/v1/queries/new?partial=true' -d '
[
{
"text": "Who should I contact about my booking?",
"article_id": 2
},
{
"text": "Where is my booking confirmation?",
"article_id": 1000
},
{
"text": "WHERE IS MY LUGGAGE???",
"article_id": 0
},
]
'
Server reply
Type | Description |
---|---|
New queries stats object | Result stats |
Example:
{"Added": 1, "Skipped": 1, "Invalid": 1}
Get one query: GET /api/faq/v1/queries/{queryHash}
Export one specific query, identified by hash, from the training corpus.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
queryHash |
path | string | Y | Hash of the query that needs to be fetched |
Server reply
Type | Description |
---|---|
Query object | A Query object |
Example:
{
"hash": "34512",
"text": "Where is my confirmation?",
"article_id": 13
}
Delete one query: DELETE /api/faq/v1/queries/{queryHash}
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
queryHash |
path | string | Y | Hash of the query to delete |
train |
query | boolean | N | Re-train corpus afterwards |
Server reply
Query successfully deleted
Get list of queries attached to the article: GET /api/faq/v1/articles/{articleId}/queries
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | ID of the article whose queries needs to be fetched |
offset |
query | integer | N | zero-based |
limit |
query | integer | N | default value 100. Max value 1000 |
Example:
curl -H 'Authorization: YOUR_API_KEY' 'https://next.alterra.ai/api/faq/v1/articles/1/queries?offset=1138&limit=2'
Server reply
Type | Description |
---|---|
List of Query objects | List of article queries |
Example:
[
{
"hash": "123e4",
"article_id": 1,
"text": "Where’s the money Lebowski?"
},
{
"id": "9ffc94",
"article_id": 1,
"text": "Who should I contact about my booking?"
}
]
Update article’s queries: POST /api/faq/v1/articles/{articleId}/queries
Attach queries to a specific article. If given queries are attached to other articles, they are detached and attached to the selected article.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | ID of the article to add queries to |
train |
query | boolean | N | Re-train corpus afterwards |
body |
body | List of Query objects | Y | Queries to attach |
hash
and article_id
are ignored.
Example:
curl -X POST -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' 'https://next.alterra.ai/api/faq/v1/articles/1/queries' -d '
[
{
"text": "Where is my booking confirmation?"
}
]
'
Server reply
Type | Description |
---|---|
List of strings | List of respective query hashes |
Example:
["706CB0285892CF2E"]
Delete all article queries: DELETE /api/faq/v1/articles/{articleId}/queries
Delete all queries associated with the article
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | ID of the article to add queries to |
train |
query | boolean | N | Re-train corpus afterwards |
Server reply
Queries successfully deleted
Add new queries to article: POST /api/faq/v1/articles/{articleId}/queries/new
Add queries to specified article. Only new queries are added, existent queries are skipped and not relabeled
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | ID of the article to add queries to |
body |
body | List of Query objects | Y | List of queries. You souldn’t fill hash fields, they will be generated by the server |
train |
query | boolean | N | Re-train corpus afterwards |
Server reply
Type | Description |
---|---|
New queries stats object | Result stats |
Get one query attached to the article: GET /api/faq/v1/articles/{articleId}/queries/{queryHash}
Retrieve one specific query, identified by the query_hash
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | ID of the article whose queries needs to be fetched |
queryHash |
path | string | Y | ID of the query that needs to be fetched |
Server reply
Type | Description |
---|---|
Query object | successful operation |
Delete one query attached to the article: DELETE /api/faq/v1/articles/{articleId}/queries/{queryHash}
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
articleId |
path | integer | Y | ID of the article whose queries needs to be deleted |
queryHash |
path | string | Y | Query id to delete |
train |
query | boolean | N | Re-train corpus afterwards |
Server reply
Query successfully detached from the article
Logs API
This part is used for working with the raw log of all queries entered by end-users in the past – see Log entries. The set of queries in this log may not fully coincide with the Queries in the training corpus. Indeed, only legitimate user queries shall be added to the training corpus. Garbage and spam may be discarded.
The intended use of this API is as follows. The system logs all end-user queries. You retrieve them, one-by-one or in bulk, make humans assign the right canonical answer (article id) to each query, add them to the training set (via Queries API), and invoke re-training of the ML models. You may use dedicated (hired) labelers or rely on the end-user or community feedback.
For you, the raw query log is read-only. The system logs all end-user queries, as is. You may retrieve them, but not modify.
Get list of log entries: GET /api/faq/v1/log
Export log entry objects from the the raw query log (with pagination). It could be used to retrieve the entire query log, or a portion of.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
offset |
query | integer | N | Offset in the list of log entries (sorted from oldest to newest). May be negative (Then it is applied from the end of the list, thus taking N newest entries) |
limit |
query | integer | N | default value 10. Max value 1000 |
excludedChannels |
query | List of integers | N | list of channels, which logs should be excluded from logs (csv format) |
Example:
curl -H 'Authorization: YOUR_API_KEY' 'https://next.alterra.ai/api/faq/v1/log?offset=-100&limit=1'
Server reply
Type | Description |
---|---|
List of Log entry objects | List of log entries |
Example:
[
{
"query": "How can I pay?",
"search_id": "73b61636-29b1-4bee-8845-3bc0ffe9a86a",
"query_hash": "01C5A0BBD64963CC",
"timestamp": "2017-03-21T13:23:53+00:00",
"result_ids": [ 3, 5, 8 ]
}
]
Get one log entry: GET /api/faq/v1/log/{searchId}
Retrieve one specific log entry, identified by the search_id
.
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
searchId |
path | string | Y | Search ID string |
Server reply
Type | Description |
---|---|
Log entry object | successful operation |
Example:
{
"query": "How can I pay?",
"search_id": "73b61636-29b1-4bee-8845-3bc0ffe9a86a",
"query_hash": "01C5A0BBD64963CC",
"timestamp": "2017-03-21T13:23:53+00:00",
"result_ids": [ 3, 5, 8 ]
}
Settings API
This API allows you to combine your main FAQ corpus with pre-defined common corpora and do some other fine-tuning.
When a common corpus is merged, it adds a set of articles to your FAQ. Merged articles are modifiable. The articles will become indexed and searchable after a Train API call.
If a common corpus is un-merged, all its articles will be removed from the main FAQ, with all its attached queries. If you had added a corpus, edited it and then un-merge it you will lose all your edits.
If your corpus is a plain-text one, we suggest you to set disable_html_sanitizer
to true
in
settings to prevent transformation of symbols in text to HTML entities.
Get FAQ settings: GET /api/faq/v1/settings
Retrieve FAQ settings
Arguments
No arguments
Server reply
Type | Description |
---|---|
FAQ settings object | FAQ settings object |
Example:
{
"merge_in": [
{ "name": "chitchat" }
]
}
Upload new FAQ settings: POST /api/faq/v1/settings
Arguments
Field name | In | Type | Always present | Description |
---|---|---|---|---|
train |
query | boolean | N | Re-train corpus afterwards |
body |
body | FAQ settings object | Y | New settings |
Example:
curl -X POST -H 'Authorization: YOUR_API_KEY' -H 'Content-Type: application/json' 'https://next.alterra.ai/api/faq/v1/settings' -d '
{
"merge_in": [
{ "name": "chitchat" }
]
}
'
Server reply
Settings updated
Get a list of all user FAQs: GET /api/faq/v1/userFaqs
Get a list of FAQs available to user
Arguments
No arguments
Server reply
Type | Description |
---|---|
List of strings | FAQ names list |
Get list of common FAQ corpora: GET /api/faq/v1/commonFaqs
Get a list of all available common FAQs you can merge into your own corpus.
Arguments
No arguments
Server reply
Type | Description |
---|---|
Common FAQ object | FAQ settings object |
Example:
[{
"name": "chitchat",
"description": "Small talk / chitchat corpus"
}]
Corpus API
This API allows you to manage corpus data.
Delete all data: DELETE /api/faq/v1/corpus
Delete all data
Arguments
No arguments
Server reply
Data successfully deleted
Get dirty state: GET /api/faq/v1/is_dirty
true if corpus requires training, false otherwise
Arguments
No arguments
Server reply
Type | Description |
---|---|
boolean | Does corpus require training |
Entities
Below is the description of entities used in this API. Each entity is represented by a JSON object.
Search request
Query string and parameters
Field name | Type | Always present | Description |
---|---|---|---|
query |
string | Y | user query |
format |
string | N | Format of answer field for corpus (plaintext or html) |
Search response
Set of all results matching given search query, ordered by relevance (in websearch it would be called SERP).
Field name | Type | Always present | Description |
---|---|---|---|
search_id |
string | Y | The ID of the search |
timestamp |
string | N | Search date and time in ISO 8601 (RFC 3339) format |
query |
string | N | Actual searched query before spelling correction |
query_hash |
string | Y | Normalized query text hash |
marked_query |
List of Part objects | N | Named entities which were extracted |
results |
List of Search result objects | Y | List of search results, ordered by relevance |
spelled_query |
string | N | Actual searched query, with spelling corrected |
format |
string | N | Format of answer field (plaintext or html) |
feedback_signature |
string | N | Cryptographic signature for feedback provided for this particular search |
Search result
One result of FAQ search, represented by one FAQ article.
Field name | Type | Always present | Description |
---|---|---|---|
article_id |
integer | Y | Article ID |
question |
string | Y | Article title (aka canonical question) |
snippet |
string | N | A short snippet of the article text |
answer |
string | N | Full article text |
alt_answers |
List of strings | N | Other formulations of the answer |
action |
string | N | Action to be taken in response to user inquiry |
score |
number | N | Relevancy score |
url |
string | N | URL of the original article |
Snippet and answer may contain HTML formatting.
Search response object is returned by the Search API.
Example:
{
"article_id": 42,
"question": "Where can I find more bots?"
}
Part
A part of a text with an entity label.
Field name | Type | Always present | Description |
---|---|---|---|
label |
string | N | Label of an entity. |
text |
string | Y | Text |
canonical_value |
string | N |
Example:
{
"text": "New York",
"label": "city"
}
Feedback request
A request to record user feedback on a particular search response. There are two types of user feedback: a feedback on the SERP as a whole (I looked at these suggested articles and they — or one of them — answered my question), or on a particular article (This article is the one I was looking for). The feedback can also be positive (it helped me) or negative (the suggestions didn’t answer my question).
Field name | Type | Always present | Description |
---|---|---|---|
signature |
string | Y | Signature received with the search results |
article_id |
integer | N | The relevant article id, if known |
positive |
boolean | Y | Whether the feedback is positive or not |
Article
One article (question-answer pair) from the FAQ document
Field name | Type | Always present | Description |
---|---|---|---|
id |
integer | N | ID of the article. Positive integer |
question |
string | Y | Title of the article, aka canonical question |
answer |
string | Y | Full answer |
snippet |
string | N | Short summary of the answer |
action |
string | N | User-defined action string |
comment |
string | N | Private comment, not visible to end-users |
alt_answers |
List of strings | N | Other formulations of the answer |
queries |
List of strings | N | List of queries attached to the article |
query_objects |
List of Query objects | N | List of query objects attached to the article |
pos_regex |
string | N | Regexp (matched against the query) that forcedly selects this answer |
neg_regex |
string | N | Regexp (matched against the query) that cancels the pos_regex |
flt_regex |
string | N | Regexp (matched against the query) that keeps the article in the SERP only if matched |
merged_from |
string | N | Name of common corpus from which the article was merged |
merged_dups |
List of integers | N | List of duplicate articles ids merged into this one, for history |
ignore_dups |
List of integers | N | List of articles ids which are not to be shown and merged as dups |
do_not_index |
boolean | N | Do not index this article, only match regexps |
url |
string | N | Url of original article |
Strings may contain HTML formatting.
Normally, only answer
is displayed to end-users. alt_answers
(optional) would be logically equivalent to answer
, but expressed in different words. They may be sometimes shown instead of the main answer, to make the bot appear “less robotic”.
Action is a semicolon-separated string, like: “key1:value1;key2:value2”. Action interpretation depends on search results consumers. For example, name of the key can be used to identify a method to be called in response to the user inquiry, in addition to or instead of displaying the answer. Examples of actions include: send email or a message, display a new webpage, create a support ticket, create a task in task management software or CRM, etc. Search consumers should ignore actions that they don’t recognize.
Rapid-resolution widget considers action “rapid-resolution:false” as a signal to inhibit Rapid-resolution popup window and the article will not raise the widget.
Web chat widget considers action “operator-fallback:true” as a signal to close the web chat widget and open fallback chat with a human operator like Intercom or Drift.
Note that by default question
is not a query. It is not indexed. If you want it to be indexed explicitly add it to queries.
Article objects are used in Articles API.
Example:
{
"id": 42,
"question": "Where can I find more bots?",
"snippet": "There is no official bot store yet",
"answer": "There is no official bot store at the moment, so you‘ll have to ask your friends or search the web for now. We’re pretty sure you’ll find some bots to play with."
}
Query
Users ask questions in their own words. Many of these questions (queries) are logically equivalent and shall be
answered by the same answer. They are all paraphrases of one canonical question (question
). These paraphrases
(referred to as “queries”) are stored in the system and used for training AI.
These queries may be imported from the log of actual queries entered by actual users (see Log Entry), or from other sources (e.g. public training corpora). They may be even thought up by you – think how you could rephrase the canonical question.
Field name | Type | Always present | Description |
---|---|---|---|
text |
string | N | Query’s text |
hash |
string | N | A hash of this query’s text, used as its ID |
article_id |
integer | N | id of the FAQ article that answers this query |
text_marked |
List of Part objects | N | Query text with entity labels. Can’t be used when text is filled. |
source |
string | N | Query source |
article_id
shall be trusted; it is assigned by a human labeler and used for training the algorithm.
Zero article_id
can be used just to store queries in corpus for further labeling.
Query objects are used in Queries API.
Together, Articles and Queries form the training corpus for Machine Learning.
Example:
{
"text": "Where’s the money Lebowski?",
"hash": 1138,
"article_id": 0
}
Entity
Named entity for slot-filling module
Field name | Type | Always present | Description |
---|---|---|---|
label |
string | Y | Unique label of an entity. Must be a one word or a concatenation of words, space symbol is forbidden. |
type |
string | Y | Type of a matching algorithm. Only exact_match is supported. |
allowed_values |
List of Synonym set objects | N | List of allowed values. |
Use exact_match
for exact substring matching.
New queries stats
Results of the Create new queries API call
Field name | Type | Always present | Description |
---|---|---|---|
added |
integer | N | Number of queries which were successfully added to the corpus |
skipped |
integer | N | Number of queries which are already existing in the corpus and were not affected |
invalid |
integer | N | Number of queries which have unknown article id (can only be non-empty if partial=true is specified) |
Example:
{
"added": 11,
"skipped": 23,
"invalid": 0
}
Log entry
The actual query that a user entered into the system in the past.
All or some of these user queries may be exported to the system and become a part of the training corpus. Other user queries may be pre-filtered as irrelevant, garbage, spam, etc. and ignored. Thus, not all queries from the raw query log belong to the training corpus.
Field name | Type | Always present | Description |
---|---|---|---|
query |
string | Y | User query text |
search_id |
string | Y | The ID of the search assigned when the search was performed |
query_hash |
string | N | Normalized query text hash |
timestamp |
string | Y | Search date and time in ISO 8601 (RFC 3339) format |
article_ids |
List of integers | Y | List of article_ids returned by the search algorithm as the response to this query, in the order of relevance (see Search Response) |
selected_id |
integer | N |
Unlike article IDs in Queries
, these article IDs cannot be trusted. They are assigned by the search algorithm
and may contain errors.
Log entry objects are used in Logs API.
Example:
{
"query_text": "How do one discover new bots?",
"query_hash": "F95C6BB30EC32F55",
"search_id": "05F4F53B-4F5D8162-7852A351-4B90F22E",
"timestamp": "2017-03-29T12:00:35Z",
"article_ids": [42, 17, 5]
}
Extraction response
Field name | Type | Always present | Description |
---|---|---|---|
search_id |
string | Y | The ID of the search performed (for logging/debugging) |
marked_query |
List of Part objects | Y | Named entities which were extracted |
Merged FAQ
These settings allow you to combine your main FAQ corpus with pre-defined common corpora. Currently, there are three common corpora available:
chitchat
Contains dialogs that would enable your bot to answer small talk questions like “how are you?”, “are you a bot or a human?”, “thank you, good bye”, etc.
User queries related to these topics are independent of your knowledge base. They are common across all verticals. This engine comes with a collection of such common queries. The answers, however, are under your control — you would edit the default values as you think fit.
grab_info
This corpus covers the “contact me” user intent. Currently, it contains only one article “contact me – here is my email address”. Specifically, if the user message contains the user’s email address this occurrence is detected by this API and the ID of this class is returned, along with the respective user message.
Additionally, an email notification is automatically sent to you (to the email address you provided when registering at Alterra’s website.)
company
Common questions about your company.
Field name | Type | Always present | Description |
---|---|---|---|
name |
string | Y | Name of the merged common FAQ corpus |
sync_period |
string | N | Automatically synchronize corpus with specified period. Only 'daily' is allowed currently. |
last_sync_time |
integer | N | Timestamp of last sync |
blacklist |
List of integers | N | Article IDs to ignore during import |
FAQ settings
Object describing all settings for this API. It contains the list of common FAQs merged with your main corpus.
Field name | Type | Always present | Description |
---|---|---|---|
merge_in |
List of Merged FAQ objects | N | Common corpora merged with your corpus |
supported_languages |
List of strings | N | Filter out queries with languages not from given list |
use_speller |
string | N | Turn spell correction on if 'yes' |
disable_html_sanitizer |
boolean | N | Set to true to disable processing of uploaded articles with HTML sanitizer |
format |
string | N | Format of answer field for corpus (plaintext or html), read only. |
max_answer_sentences |
integer | N | Set the number of first answer sentences to index. Set to 0 if answer should not be indexed at all, or to -1 if all sentences should be indexed. By default this is set to 8. |
do_not_augment_entities |
boolean | N | |
do_not_index_question |
boolean | N | Set to true to disable indexing of article title aka question |
corpus_is_public |
boolean | N | Corpus is available for search by everyone |
unlabeled_english_only |
boolean | N | Do not save non-english queries as unlabeled |
cleanup_email_rubbish |
boolean | N | Cleanup email quotations and signatures |
bot_settings |
Bot settings object | N | Settings for bots connected to corpus |
synonyms |
List of Synonym set objects | N | There are cases when your field uses synonyns that are not common in English. In these cases creating a custom synonym table may improve quality of bot’s answers. |
cut_regexps |
List of strings | N | Consecutively apply regexps to query and remove matched substrings. RE2 Regexp syntax. |
Bot settings
Settings of bots connected to corpus.
Field name | Type | Always present | Description |
---|---|---|---|
pause_duration |
integer | N | Bot will be paused for this time interval after human answer. In seconds. By default it is 2 hours. |
reply_delay |
integer | N | Delay before bot’s answer, in seconds |
common_human_working_hours |
List of integers | N | Bot won’t work within working hours interval. |
human_working_hours |
object | N | Working hours for particular days of week. Overrides common_human_working_hours . |
timezone |
string | N | Time zone for working hours |
silent_mode |
boolean | N | Bot won’t answer at all if this is set to true |
Synonym set
Represents a canonical variant and a set of different variants to write it.
Field name | Type | Always present | Description |
---|---|---|---|
canonical |
string | N | Canonical variant of this synonym (all following synonyms will be rewritten to this variant). |
synonyms |
List of strings | N | Array of different variants, these will all be equivalent to the canonical variant. |
Example:
{
"canonical": "Y combinator",
"synonyms": ["Ycombinator", "Y-combinator", "YC"]
}
Common FAQ
A common FAQ available to merge into your corpus.
For further info see FAQ Settings API.
Note on pre-defined articles
There is a number of pre-defined articles (classes) to treat user questions that don’t have answers in your FAQ files.
Pre-defined articles are editable and can be manually deleted from your corpus.
Title | ID | Indexed | Description |
---|---|---|---|
Wrong Language | -4 | No | Special article which shows up when the user query is detected to be non-English |
Garbage | -5 | No | Completely useless queries. Garbage. Trash. Spam. Not worth answering, ever. |
Ignore | -3 | No | Meaningful queries worth answering that however shall not be added to your FAQ file: off-topic, one-off, too ambiguous, too short, too long and complex for bot, requiring a non-public answer, etc. You may forward them to humans. |
To do | -2 | No | Meaningful on-topic questions that doesn’t have an answer in the current FAQ file, but should. You may create new articles and then re-assign these queries to them. Thus, the “to-do” name. |
Greeting | -6 | No | Enables your bot to initiate a conversation with the user. The bot will send the text of the Answer of this Article to the user, unprompted. |
Wrong Language: this API only supports English. The engine includes language identification algorithm. When it detects a non-English query it returns id=-4 and the respective answer. (You can edit it.)
Garbage, Ignore, To do: use these three classes for questions that don’t have answers in your FAQ file. (The table above describes the differences between the three.) If the user query is classified as one of these, the system will return a “No results found” message to the user.
Since the queries that fall under these categories are quite different from legitimate frequently asked questions, the search engine may be not as accurate on these queries, compared to good ones. Garbage in – garbage out …
Therefore, you have an option to deactivate some or all of these classes. You do it by setting
do_not_index = true
. (In fact, it is the default value.) If you do so, the ML system will not use the respective
classes for training and will not reply with the “No results found” message. Instead, it will attempt to find an
answer in your FAQ. Most likely, it will be incorrect. Garbage in – garbage out …
However, even if you decide to deactivate these classes, you should still use them when labeling the query log. Otherwise, if you try to label these “bad” queries as legitimate it will wreak havoc on the algorithms. Besides, you may later decide to activate these classes — your training corpus will be ready. You may always activate it by changing ‘do_not_index’ from ‘true’ to ‘false’.
Greeting: you may want your bot to be active and begin talking first, even if not prompted by the user. This pre-defined class is reserved for this purpose. You would program your bot to initiate the conversation with the message of this article.
Alternatively, you may make your system passive: it will wait until the user asks the first question. In that case, don’t call this class.