Queries
The queries below are the main entry-point for our public API. GraphQL queries return only the data you specify.
Queries are structured like this:
query {
JSON objects to return
}
Chat State
Returns information about the partner to which the authentication token you are using corresponds to.
Example
Query
The query below asks for the id and for the state of the current partner
to check if the chat feature is currently available.
query {
partner {
id
state {
chat {
isAvailable
}
}
}
}
Response
The server responds to the query with an object under data which keys match
the structure of the request. In the example below, the server replies that
the id of the current partner is guuru-qa and chat is currently enabled.
"data": {
"partner": {
"id": "guuru-qa",
"state": {
"chat": {
"isAvailable": true
}
}
}
}
Chats
Returns a paginated and ordered list of chats that match the given arguments.
If you are not familiar with pagination in GraphQL, please read Pagination before continuing.
Example 1
Query
The query below asks for the 3 most recent chats of the current partner,
sorted by creation date. It also requests for pagination
information (pageInfo) namely hasNextPage which returns true when there
are more chats available and endCursor that can be used to request the next
n chats.
A full example on how to fetch all chats is available.
query {
partner {
chats(
first: 3
orderBy: { field: id, direction: desc }
) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
status
createdAt
closedAt
question
expert {
name
}
user {
name,
email
}
category {
name
}
}
}
}
}
}
Response
The response to the example query above would return the requested pagination information and a list of edges, each containing a cursor and a node (as per the Relay Cursor Connections Specification):
"data": {
"partner": {
"chats": {
"pageInfo": {
"hasNextPage": true,
"endCursor": "MTE1MA=="
},
"edges": [
{
"node": {
"status": "rated",
"createdAt": 1520338294661,
"closedAt": 1520338704673,
"question": "test",
"rating": "good",
"expert": {
"name": "J. Lincoln"
},
"user": {
"name": "John Doe",
"email": "john.doe@guuru.com",
},
"category": {
"name": "General"
}
}
},
{
"node": {
"status": "rated",
"createdAt": 1520338294971,
"closedAt": 1520338704684,
"question": "Another test question",
"rating": "good",
"expert": {
"name": "Peter K."
},
"user": {
"name": "Hannah Doe",
"email": "hannah.doe@guuru.com",
},
"category": {
"name": "TV Sets"
}
}
},
{
"node": {
"status": "rated",
"createdAt": 1520338295672,
"closedAt": 1520338824690,
"question": "One more test question",
"rating": "good",
"expert": {
"name": "Andrew"
},
"user": {
"name": "Peter Doe",
"email": "hannah.doe@guuru.com",
},
"category": {
"name": "TV Sets"
}
}
}
]
}
}
}
}
Example 2
Query
The query below asks for the first 3 chats created between September 2020 and
October 2020. It also requests for pagination information (pageInfo)
namely hasNextPage which returns true when there are more chats
available and endCursor that can be used to request the next n chats.
A full example on how to fetch all chats is available.
query {
partner {
chats(
startDate: "2020-09-01"
endDate: "2020-10-01"
first: 3
orderBy: { field: id, direction: asc }
) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
status
createdAt
question
expert {
name
}
user {
name,
email
}
category {
name
}
}
}
}
}
}
Response
The response to the example query above would return the requested pagination information and a list of edges, each containing a cursor and a node (as per the Relay Cursor Connections Specification):
"data": {
"partner": {
"chats": {
"pageInfo": {
"hasNextPage": true,
"endCursor": "MTE1MA=="
},
"edges": [
{
"node": {
"status": "rated",
"createdAt": 1598958180000,
"question": "What is the meaning of life?",
"rating": "good",
"expert": {
"name": "J. Lincoln"
},
"user": {
"name": "John Doe",
"email": "john.doe@guuru.com",
},
"category": {
"name": "General"
}
}
},
{
"node": {
"status": "rated",
"createdAt": 1598958720000,
"question": "Do you ship to Austria?",
"rating": "good",
"expert": {
"name": "Peter K."
},
"user": {
"name": "Hannah Doe",
"email": "hannah.doe@guuru.com",
},
"category": {
"name": "TV Sets"
}
}
},
{
"node": {
"status": "rated",
"createdAt": 1598959200000,
"question": "Can I pay with an American Express card?",
"rating": "good",
"expert": {
"name": "Andrew"
},
"user": {
"name": "Peter Doe",
"email": "hannah.doe@guuru.com",
},
"category": {
"name": "TV Sets"
}
}
}
]
}
}
}
}
Chat Messages
Returns a paginated and ordered list of messages from a given chat.
If you are not familiar with pagination in GraphQL, please read Pagination before continuing.
A message can have different fields depending on its type. The example below requests the fields
hideForuser,hideForExpertandcreatedAtwhich are common to all message types using... on Message. Additionally if the message is aTextMessagewe request the fieldtext; if it is anAttachmentMessagewe request theurlandmimetypeof the attachment.
The author of a message can have different fields depending on its type. In the example below you can see that if the author is an user we request
name,phone. If it is an expert we do not request thephonebut do request thephotoUrl. You can read more about unions and interfaces in the GraphQL specification.
Example 1
Query
The query below asks for the 20 most recent messages of a given chat and
information about their authors (e.g. name, email, etc).
It also requests the pagination information (pageInfo),
namely hasNextPage which returns true when there are more messages
to show and endCursor that can be used to request the next n messages.
Note that in addition to the chat messages we also request the time at which the chat was created, accepted and closed. We could have requested any other fields from the Chat type.
query {
chat(id: "-MCIJ5mvshQZOkFx72z-") {
createdAt
acceptedAt
closedAt
messages(first: 20) {
pageInfo {
endCursor
hasNextPage
}
edges {
node {
... on Message {
hideForUser
hideForExpert
createdAt
}
... on TextMessage {
text
}
... on AttachmentMessage {
attachment {
mimetype
url
}
}
author {
... on UserAuthor {
name
email
phone
}
... on ExpertAuthor {
name
email
photoUrl
}
... on BotAuthor {
name
photoUrl
}
}
}
}
}
}
}
Response
The response to the example query above would return the requested pagination information and a list of edges, each containing a cursor and a node (as per the Relay Cursor Connections Specification):
{
"data": {
"chat": {
"createdAt": 1594830646924,
"acceptedAt": 1594830874024,
"closedAt": 1594830955685,
"messages": {
"pageInfo": {
"endCursor": "MTE1MA==",
"hasNextPage": false
},
"edges": [
{
"node": {
"hideForUser": false,
"hideForExpert": false,
"createdAt": 1594830948568,
"text": "I would recommend Linux Kernel in a Nutshell",
"author": {
"name": "Greg KH",
"email": "gkh@linux.org",
"photoUrl": "https://firebasestorage.googleapis.com/v0/b/guuru-b685d.appspot.com/o/profilePicture%2FAyO5RVaOmbXm1xwSdnAKantvzNd2%2F02ab4b87-ffea-4e2a-b8a4-ecd57ff9068c?alt=media&token=0f7ab485-5483-4481-aad6-c9646499bcf3"
}
}
},
{
"node": {
"hideForUser": false,
"hideForExpert": true,
"createdAt": 1594830874756,
"text": "You are now chatting with Greg KH",
"author": {
"name": "Guuru-Bot",
"photoUrl": "https://cdn.guuru.com/assets/logo/robotAvatar.png"
}
}
},
{
"node": {
"hideForUser": false,
"hideForExpert": true,
"createdAt": 1594830644814,
"text": "You will be connected with an independent product expert",
"author": {
"name": "Guuru-Bot",
"photoUrl": "https://cdn.guuru.com/assets/logo/robotAvatar.png"
}
}
},
{
"node": {
"hideForUser": false,
"hideForExpert": true,
"createdAt": 1594830643227,
"text": "Andrew Tanenbaum",
"author": {
"name": "Andrew Tanenbaum",
"email": null,
"phone": null
}
}
},
{
"node": {
"hideForUser": false,
"hideForExpert": true,
"createdAt": 1594830641423,
"text": "What's your name?",
"author": {
"name": "Guuru-Bot",
"photoUrl": "https://cdn.guuru.com/assets/logo/robotAvatar.png"
}
}
},
{
"node": {
"hideForUser": false,
"hideForExpert": false,
"createdAt": 1594830638819,
"text": "Which is the best book to learn Linux as a beginner?",
"author": {
"name": null,
"email": null,
"phone": null
}
}
},
{
"node": {
"hideForUser": false,
"hideForExpert": true,
"createdAt": 1594830625844,
"text": "Welcome to Barnes & Noble!",
"author": {
"name": "Guuru-Bot",
"photoUrl": "https://cdn.guuru.com/assets/logo/robotAvatar.png"
}
}
}
]
}
}
}
}
Experts
Returns a paginated and ordered list of experts that match the given arguments.
If you are not familiar with pagination in GraphQL, please read Pagination before continuing.
Example
Query
The query below asks for the 3 most recent experts of the current partner.
It also requests for pagination information (pageInfo) namely
hasNextPage which returns true when there are more experts available and
endCursor that can be used to request the next n experts.
query {
partner {
experts(
first: 3
orderBy: { field: id, direction: desc }
) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
name
email
}
}
}
}
}
Response
The response to the example query above would return the requested pagination information and a list of edges, each containing a cursor and a node (as per the Relay Cursor Connections Specification):
"data": {
"partner": {
"experts": {
"pageInfo": {
"hasNextPage": true,
"endCursor": "MjE="
},
"edges": [
{
"node": {
"name": "Miguel5",
"email": "miguel+5@guuru.com"
}
},
{
"node": {
"name": "Miguel0",
"email": "miguel+0@guuru.com"
}
},
{
"node": {
"name": "Miguel",
"email": "miguel@guuru.com"
}
}
]
}
}
}
Community Experts
Returns a paginated and ordered list of Guurus that are in the specified Community.
If you are not familiar with pagination in GraphQL, please read Pagination before continuing.
Example
Query
The query below asks for the 5 "best" Guurus of the current partner. In this context, the "best" Guurus are the ones that have a bio filled and a profile picture set.
It also requests for pagination information (pageInfo) namely
hasNextPage which returns true when there are more Guurus available and
endCursor that can be used to request the next n Guurus.
For significant performance improvements, consider calling the query with a specific name starting with "GetPersisted<Name of Query>".
You can check the example below for guidance.
query GetPersistedCommunityExpertProfiles {
community(id: "guuru-qa") {
id
experts(first: 5) {
edges {
node {
id
bio
photoUrl
name
joinedAt
rating
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
Response
The response to the example query above would return the requested pagination information and a list of edges, each containing a cursor and a node (as per the Relay Cursor Connections Specification):
{
"data": {
"community": {
"id": "guuru-qa",
"experts": {
"edges": [
{
"node": {
"id": "d8KJURdErYaQJo78xjnt7TPeecE3",
"bio": "✈️ world traveller | 🌎 34 countries explored and counting | Travel trips & Wisdom ✨️",
"photoUrl": "https://scontent.guuru.com/expert/profile-picture/d8KJURdErYaQJo78xjnt7TPeecE3.jpg?v=1687797508131",
"name": "Joana",
"joinedAt": 1633367340046,
"rating": 0.8375,
},
},
{
"node": {
"id": "1PDF1vmgr8OGwWz7qgj8SF3wI1o1",
"bio": "I’m not actually a dog, or am I ?",
"photoUrl": "https://scontent.guuru.com/expert/profile-picture/1PDF1vmgr8OGwWz7qgj8SF3wI1o1.jpg?v=1717437462378",
"name": "Diogo Araújos",
"joinedAt": 1590166798437,
"rating": 0.9583333,
},
},
{
"node": {
"id": "sox0PNj4T1hRHYiypcl6DrAGmVA3",
"bio": "I'm part of this community because as a developer we need to make sure that everything is working after a new release! And i love it!!",
"photoUrl": "https://scontent.guuru.com/expert/profile-picture/sox0PNj4T1hRHYiypcl6DrAGmVA3.jpg?v=1706271759310",
"name": "Samuel Alpoim",
"joinedAt": 1626371893649,
"rating": 0.9125,
},
},
{
"node": {
"id": "cji2kZMY3zPJEDL3eElGyru2uLP2",
"bio": "Hello, I'm Nuno!",
"photoUrl": "https://scontent.guuru.com/expert/profile-picture/8q0SE1mJW4hkhFNPkcxEyxobWl33.jpg?v=1690881255556",
"name": "Nuno Silvaa",
"joinedAt": 1588600481052,
"rating": 0.8982609,
},
},
{
"node": {
"id": "uBIWWUGNkZMUOkcgpETXl01Pfsu1",
"bio": "As a product manager I of course also am testing the solution and therefore part of QA",
"photoUrl": "https://scontent.guuru.com/expert/profile-picture/uBIWWUGNkZMUOkcgpETXl01Pfsu1.jpg?v=1712822548510",
"name": "Rafaela",
"joinedAt": 1683556611728,
"rating": 0.8130435,
},
},
],
"pageInfo": {
"hasNextPage": true,
"endCursor": "MgA0ODg=",
"__typename": "PageInfo"
},
},
}
}
}
Payouts
Returns a paginated list of experts and their balances for a given monthly
accounting period. Any timestamp within the desired month (e.g.
1548979200000 which corresponds to 2019-02-01 or 1550102400000 which
corresponds to 2019-02-14) is accepted as a valid value for period and
will return the balances for February 2019.
Timestamps are defined as milliseconds since the Unix epoch, i.e., the number of milliseconds that have elapsed since 00:00:00, 1 January 1970 UTC.
Balances are defined as an array of tuples where each tuple contains an
amount in cents and a three letter currency code (ISO 4217). As specified by ISO 4217, the XXX
currency code is used to denote transactions involving no currency, e.g.,
loyalty points.
The amount is an integer that denotes a value in cents, e.g., the tuple
{ amount: 1500, currency: 'EUR' }represents €15.00 and the tuple{ amount: 75000, currency: 'XXX' }can represent 750 points.
If you are not familiar with pagination in GraphQL, please read Pagination before continuing.
Example
Query
The query below requests the first 10 experts having balances greater than 0
for the monthly period starting on 2019-02-01 (February 2019).
It also requests for pagination information (pageInfo) namely hasNextPage
which returns true when there are more experts with payouts available and
endCursor that can be used to request the next n experts with payouts.
A full example on how to fetch all payouts for a given period is also available.
query {
partner {
payouts(period: 1550102400000) {
experts(first: 10) {
edges {
node {
name
email
balances {
amount
currency
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
Response
The response to the example query above would return the requested pagination information and a list of edges, each containing a cursor and a node (as per the Relay Cursor Connections Specification):
{
"data": {
"partner": {
"payouts": {
"experts": {
"edges": [
{
"node": {
"name": "Tyler Durden",
"email": "tyler.durden@example.com",
"balances": [
{
"amount": 1500,
"currency": "EUR"
},
{
"amount": 12400,
"currency": "XXX"
}
]
},
"node": {
"name": "Robinson Crusoe",
"email": "robison.crusoe@example.com",
"balances": [
{
"amount": 90400,
"currency": "XXX"
}
]
}
}
],
"pageInfo": {
"hasNextPage": false,
"endCursor": "MTQ="
}
}
}
}
}
}
Content
Retrieve approved opinions to display on product or topic pages, including pages rendered on the server.
Results use cursor-based pagination. See Pagination for details.
Example 1
Query
Retrieve opinions for a community using one or more page keys.
A page key uniquely identifies a page. It can be a URL, product SKU, or custom page ID. Include the language code in the key to keep content separate by language.
Use first to limit the number of opinions returned.
query {
community(id: $id) {
id
mentions(pageKeys: $pageKeys, first: $first) {
edges {
node {
id
createdAt
createdAtRelative
summary
headline
author {
id
bio
name
photoUrl
}
}
}
count
}
}
}
Response
Each entry in edges contains an opinion in node, including its text and
author details. The count field is the total number of matching opinions,
which may exceed the number returned in this response.
{
"data": {
"community": {
"id": "guuru",
"mentions": {
"edges": [
{
"node": {
"id": "98642",
"createdAt": "2025-12-06T07:12:16.957Z",
"createdAtRelative": "4 months ago",
"summary": "You can tap into your community by letting experienced users help answer questions and guide others in your online store. This not only supports your customers but also creates memorable moments that keep them coming back.",
"headline": "Community support drives loyalty",
"author": {
"id": "f7m32ykcgOXSZjXXKNu9TR8k61W2",
"bio": "Nach über 8 Jahren Erfahrung in diversen Community‘s,kann ich gute Tips geben im Umgang mit User/innen von diversen Community‘s und allgemeine nützlichen Informationen geben ",
"name": "Patrick ",
"photoUrl": "https://extcdn.guuru.com/cdn-cgi/image/format=auto,width=80/https://scontent.guuru.com/expert/profile-picture/f7m32ykcgOXSAjbXKNu9TR8k61W2.jpg?v=1668584150731"
}
}
}
],
"count": 1
}
}
}
}
Example 2
Query
Pass generation to fetch approved opinions and also request asynchronous
content generation. See Mentions for the generation fields,
defaults and behaviour.
query {
community(id: "guuru") {
id
mentions(
pageKeys: ["topic-123:en"]
generation: {
page: {
url: "https://example.com/en/topic-123"
title: "Community support drives loyalty"
locale: "en"
source: topic
}
}
first: 3
) {
edges {
node {
id
createdAt
createdAtRelative
summary
headline
author {
id
bio
name
photoUrl
}
}
}
count
}
}
}
Response
The response has the same structure as Example 1 and contains existing approved opinions. It may be empty if none are available. Newly generated content can be retrieved in later requests once approved.
Total opinion count
To retrieve the total number of opinions matching your query, include the
count field in mentions. The count represents all matching opinions,
not just the opinions returned in the current page.
When using pagination, you can use the GraphQL @include directive to
request count only on the first page, avoiding repeated count requests on
subsequent pages.
query {
community(id: "guuru") {
id
mentions(
pageKeys: $pageKeys
first: $first
after: $after
) {
edges {
node {
id
createdAt
summary
headline
}
}
pageInfo {
hasNextPage
endCursor
}
count @include(if: $isFirstPage)
}
}
}
In this example, $isFirstPage is a Boolean variable set to true for the
first page and false for subsequent pages. When the directive excludes
count, the field is omitted from the response.
Pagination
To fetch more opinions than the initial request returns, use the pageInfo
fields and the after argument to retrieve subsequent pages.
Request cursor inside edges and use pageInfo.hasNextPage and
pageInfo.endCursor to determine whether more pages are available and
where to continue.
See the Pagination documentation for details on how cursor-based pagination works.
To retrieve the total number of matching opinions, include the count field
in your query. If you are using pagination, you can request it only on the
first page using count @include(if: $isFirstPage).
Use the same pageKeys, first, and other query filters for every request to ensure consistent pagination. Request count only on the first page if you need the total number of matching opinions.
Tracking content impressions
Fetching content through the Admin API does not automatically track
impressions. To track them, call
logEvent in the
browser when the opinions are displayed. Set contentIds to the IDs of the
displayed opinions.
if (Math.random() <= samplingRate) {
window.guuru.logEvent('contentImpression', { contentIds }, samplingRate);
}
Use sampling to reduce tracking requests, especially on high-traffic websites. For example, set
samplingRateto0.1to track approximately 10% of impressions. Pass the same rate tologEventso Guuru can estimate the total number of impressions. The numbers shown in the dashboard are approximate.
Tracking content feedback
You can track whether visitors like or dislike a piece of content by adding your own thumbs-up and thumbs-down buttons to each displayed opinion.
Render the buttons in your website's UI and call logEvent when a visitor
clicks one of them. Set type to 'positive' for a thumbs-up or 'negative'
for a thumbs-down, and pass the ID of the opinion in contentId.
// When a visitor clicks the thumbs-up button
window.guuru.logEvent('contentFeedback', {
type: 'positive',
contentId,
});
// When a visitor clicks the thumbs-down button
window.guuru.logEvent('contentFeedback', {
type: 'negative',
contentId,
});
Guuru tracks these feedback events so you can measure how visitors respond to the displayed content.
You are responsible for implementing the feedback buttons, handling their interactions, and maintaining the visitor's feedback state (e.g. whether they have already liked or disliked an opinion). The Guuru API does not provide this state, so you must manage it yourself if you want to show previously submitted feedback or prevent visitors from voting multiple times.
If you need help setting this up, please contact our support team.