The ingestion API can be used to upload data to Birdie directly. Clients upload data by making an HTTP PUT for each record they want to upload.
The request must include a Birdie API key in an HTTP header in the form Authorization: ApiKey {api-key}
. To generate an API key, you can reach out to the Birdie team and we will provide you one.
The response status code will be one of the following:
201 Created
on success;400 Bad Request
if the request body is invalid;401 Unauthorized
if the API key is missing or invalid.503 Service Unavailable
if too many requests are being made in a short amount of time.
For status code 400, the response body will be a JSON object with an error message.
We suggest making up to 100 requests per second (6000 per minute) to the Birdie API to avoid 5XX errors.
JSON formats
The uploaded data has to be in JSON format. Schema definitions for each type are available at https://api.birdie.ai/ingestion/schemas
Types of Uploads
Conversations and Messages
A conversation is an identifier of a discussion that happens between one or more users. An example could be a support ticket on Zendesk, or an issue on Github.
A message is part of conversation, where an entire conversation is composed of a group of messages. An example could be a message from a support agent for a Zendesk Ticket, or a comment by another contributor on a Github Issue.
A conversation may contain more than one message. The message may be posted by the same user or by a different user, at some different point of time.
These two types of records walk hand and hand together, and they cannot exist within the Birdie application without each other.
They must be uploaded together. We suggest always uploading the conversation first, then conversation message.
Conversations don't appear inside the Birdie application if they don't have an associated conversation message and vice-versa.
Birdie calculates a summary for each conversation based on it's messages and displays it in your feed.
The summary can be expanded to see the individual messages exchanged within the conversation.
Feedbacks
A single feedback record posted by a user.
An example could be NPS survey response by a user or a user review posted under an App on Google Play Store.
Feedbacks are displayed together with conversation summaries in you feed.
Audience: Accounts and Users
Accounts and users are an optional, additional type of record that can be uploaded to further segment feedbacks and conversations.
Within the kind fields for the feedback or conversation message, you can provide the {account-id}
and {author-id}
fields respectively.
Then after you have uploaded the feedbacks or conversations and their messages, you can upload information about the individual accounts and users.
Kinds
For conversations, conversation messages, and feedbacks, the schema includes a kind
field that's used to distinguish different kinds of conversations/feedbacks.
Kinds are used to add more fields that are more specific to the origin of the data.
For example, for conversations and messages, the Zendesk Tickets example falls under the support_ticket
kind. The app store user review example falls under the review
kind.
We have multiple kinds, which can be listed here: https://api.birdie.ai/ingestion/schemas
You will need to analyze your source of data and see which record type (so Conversation vs Feedbacks) and which Kind best fits your data.
The value of the kind field within a feedback, conversation or conversation message is always an object with two fields:
name
: specifies the kindfields
: contains data specific to this kind.
The valid kinds and their schemas are documentated at the URL given above.
Other common concepts
Later on you will notice that the endpoints for uploading data all have a set of path parameters. These parameters are identifiers for each records. They should be a string (we suggest alpha-numerical). These identifiers are very important since they are used to differentiate records. If any two records should exist within your account at Birdie at the same time, they must have two different IDs.
There are also two fields common to all record types: additional_fields
and batch_id
.
additional_fields
lets clients upload any fields that don't fit the pre-defined schema. These can be mapped to custom fields in Birdie. Reach out to the Birdie team for help setting up custom fields.
batch_id
is an optional field that lets clients specify that a set of uploaded records should be grouped together -- in other words, that they're a "batch" of records uploaded together.
For example, if a script is used to upload data, the script could generate a batch ID each time it runs and include that batch ID in each record it uploads. The default batch ID includes the current date so all records uploaded on the same day are considered a batch.
Clients that set a batch ID should follow two guidelines: (1) they should upload all records with the same batch ID within 24 hours (2) they should not use a different batch ID for each record (and thus create a huge number of batches).
Endpoints
There are five endpoints to upload different types of data.
PUT /ingestion/conversations/{conversation-id}
This endpoint is used to upload (create or update) a conversation. When updating a record, the entire content of the record will be overwritten with the new content (no partial updates).
Example request 1 - Conversation of kind Support Ticket:
curl https://api.birdie.ai/ingestion/conversations/123 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"kind": {
"name": "support_ticket",
"fields": {
"subject": "Account reset",
"status": "open",
"priority": "normal",
"channel": "email"
}
},
"additional_fields": {
"ticket_opened_at": "2024-01-01T00:00:00Z"
}
}'
Example request 2 - Conversation of kind Issue:
curl https://api.birdie.ai/ingestion/conversations/issue-1 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"kind": {
"name": "issue",
"fields": {
"project_id": "birdie/repository",
"project_name": "repository",
"status": "open",
"title": "Doesnt work after update 1.01"
}
},
"additional_fields": {
"issue_opened_at": "2024-01-01T00:00:00Z",
"repository_tags": ["repo"]
}
}'
The messages belonging to the conversation are uploaded separately.
PUT /ingestion/conversations/{conversation-id}/messages/{message-id}
This endpoint is used to upload (create or update) a message that belongs to a conversation. When updating a record, the entire content of the record will be overwritten with the new content (no partial updates).
Example request 1 - Message of kind support ticket:
curl https://api.birdie.ai/ingestion/conversations/123/messages/456 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"kind": {
"name": "support_ticket",
"fields": {
"author_id": "author-1",
"author_name": "John Doe",
"author_type": "Agent"
}
},
"text":"Hello, My name is John! Im here to assist you today.",
"language":"en",
"posted_at":"2024-01-01T00:00:00Z",
"additional_fields": {
"high_priority": true
}
}'
Example request 2 - First message of kind issue by User:
curl https://api.birdie.ai/ingestion/conversations/issue-1/messages/issue-msg-1 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"kind": {
"name": "issue",
"fields": {
"author_id": "engineer123",
"author_name": "John"
}
},
"text":"Since the last update, I cant get the service to work!",
"language":"en",
"posted_at":"2024-01-01T10:00:00Z",
"additional_fields": {
"thumbs_up": 5,
"thumbs_down": 3
}
}'
Example request 3 - Second message of kind issue by another user:
curl https://api.birdie.ai/ingestion/conversations/issue-1/messages/issue-msg-2 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"kind": {
"name": "issue",
"fields": {
"author_id": "contributor456",
"author_name": "Josh"
}
},
"text":"Try rolling back to the last version, that worked for me",
"language":"en",
"posted_at":"2024-01-01T10:15:00Z",
"additional_fields": {
"thumbs_down": 10
}
}'
The conversation ID must match the ID of a conversation uploaded separately. The order of the uploads is not important -- clients can upload first a conversation, then its messages, or the other way around.
PUT /ingestion/feedbacks/{feedback-id}
This endpoint is used to upload (create or update) feedbacks that don't belong to a conversation. When updating a record, the entire content of the record will be overwritten with the new content (no partial updates).
Example request 1 - Feedback of kind Review:
curl https://api.birdie.ai/ingestion/feedbacks/abcd-123 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"posted_at": "2024-01-01T00:00:00Z",
"text": "Excellent app",
"language": "en",
"kind": {
"name": "review",
"fields": {
"owner": "Owner",
"rating": 5.0
}
},
"additional_fields": {
"author": "John Doe",
"device": "Android"
}
}'
Example request 2 - Feedback of kind NPS:
curl https://api.birdie.ai/ingestion/feedbacks/xyzw-451 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"posted_at": "2024-01-01T00:00:00Z",
"text": "Im always recommending this service to my friends!",
"language": "en",
"kind": {
"name": "nps",
"fields": {
"author_id": "john123",
"author_name": "John Doe",
"account_id": "companyABC",
"title": "[NPS 2024] How Likely are you to recommend Birdie?",
"rating": 10
}
},
"additional_fields": {
"classification": "promoter"
}
}'
PUT /ingestion/audience/accounts/{account-id}
This endpoint is used to upload (create or update) an account. When updating a record, the entire content of the record will be overwritten with the new content (no partial updates).
Example request - Match uploaded NPS Feedback:
curl https://api.birdie.ai/ingestion/audience/accounts/companyABC \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"name": "Doe Inc.",
"website": "https://example.com",
"additional_fields": {
"key_account": true
}
}'
PUT /ingestion/audience/users/{user-id}
This endpoint is used to upload (create or update) a user. When updating a record, the entire content of the record will be overwritten with the new content (no partial updates).
Example request - Match uploaded NPS Feedback:
curl https://api.birdie.ai/ingestion/audience/users/john123 \
-H 'Authorization: ApiKey {api-key}' \
-H 'content-type: application/json' \
-X PUT -d '{
"name": "John Doe",
"email": "[email protected]",
"additional_fields": {
"key_user": true
}
}'
Results
If you succesfully managed to execute the previous requests, you should see the following results in your Birdie Feed: