GUURU for Developers

GUURU for Developers

  • Docs
  • Contacts

›API Reference

Web SDK

  • Getting Started
  • Public Interface
  • Handling Events
  • Conversion
  • Cookies
  • Examples

SmartChat

  • Getting started
  • Chat Window

    • Getting started
    • Parameters

SmartForm

  • Getting Started

Admin API

  • Getting started
  • API Reference

    • Queries
    • Mutations
    • Types
    • Pagination
  • Examples

Webhooks

  • Getting started
  • Examples

Integrations

  • Facebook
  • Salesforce
  • Zendesk
  • Third Party Messaging

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, hideForExpert and createdAt which are common to all message types using ... on Message. Additionally if the message is a TextMessage we request the field text; if it is an AttachmentMessage we request the url and mimetype of 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, email and phone. If it is an expert we do not request the phone but do request the photoUrl. 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 samplingRate to 0.1 to track approximately 10% of impressions. Pass the same rate to logEvent so 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.

← Getting startedMutations →
  • Chat State
    • Example
  • Chats
    • Example 1
    • Example 2
  • Chat Messages
    • Example 1
  • Experts
    • Example
  • Community Experts
    • Example
  • Payouts
    • Example
  • Content
    • Example 1
    • Example 2
    • Total opinion count
    • Pagination
    • Tracking content impressions
    • Tracking content feedback
GUURU for Developers
Docs
SmartChatSmartFormAPI Reference
Community
GitLabFacebookLinkedIn
Copyright © 2026 GUURU Solutions Ltd.