Skip to main content
Enterprise customers can use User API Keys to programmatically query their Remark data via the GraphQL API. This covers dashboard statistics, conversation history, smart tags, order data, and more.

Authentication

Create and use API keys to authenticate requests.

Dashboard Statistics

Query chat volume, revenue, conversion rates, and leaderboards.

Conversations

List and filter conversations with pagination.

Smart Tags

Aggregate smart tag counts across conversations.

Authentication

Creating an API Key

1

Navigate to API Keys

Go to Settings > API Keys in the Remark dashboard.
2

Create a key

Click Create API Key, give it a name and optional expiry date.
3

Copy the token

Copy the token immediately — it is only shown once. Token format: rmrk_u_ followed by a secure hash.

Using the API Key

All requests go to the GraphQL endpoint:
POST https://api.withremark.com/graphql
Include your token in the Authorization header:
Authorization: Bearer rmrk_u_your_token_here
The key inherits the full permissions of the user who created it. Keys can be revoked at any time from the dashboard.

Example Request

curl -X POST https://api.withremark.com/graphql \
  -H "Authorization: Bearer rmrk_u_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "{ vendorById(vendorId: \"your-vendor-id\") { name } }"
  }'

Dashboard Statistics

The main analytics entry point. All stats are nested under vendorById > conversationAggregateStatistics and support filtering by date range and optionally by channel.
Permission required: VIEW_CONVERSIONS (for revenue/conversion fields)

All-in-One Dashboard Query

Fetches the most commonly used KPIs in a single request:
query DashboardStats(
  $vendorId: ID!
  $start: DateTime!
  $end: DateTime!
  $timezone: String!
  $channel: ConversationChannel
) {
  vendorById(vendorId: $vendorId) {
    conversationAggregateStatistics(start: $start, end: $end, channel: $channel) {
      # Chat volume
      numberOfChats
      numberOfAIChats
      numberOfHumanChats
      automationRate

      # Revenue & conversions
      totalValueOfConversationsAttributedToChat
      totalValueOfConversationsAttributedToHumanChat
      totalValueOfConversationsAttributedToAIChat
      numberOfConversionsAttributed
      conversionRateForChatters
      conversionRateForNonChatters
      aovForChatters
      aovForNonChatters
      aovForAttributedConversions
      aovForNonAttributedConversions

      # Performance
      averageExpertResponseTime
      medianJoinTime
      totalManHoursSpentInChat

      # Time series
      attributedRevenueTimeSeries(timezone: $timezone) {
        precision
        time
        totalAttributedValue
      }
      chatsByHourHistogram(timezone: $timezone) {
        hour
        count
        average
      }
      chatsByDayOfWeekHistogram(timezone: $timezone) {
        day
        dayIndex
        chatCount
        dayCount
      }

      # Leaderboards
      topProductsByAttributedSales {
        numberOfRecommendations
        numberSold
        totalSales
        product { id name }
      }
      topExpertByAttributedSales {
        asAiPersona
        attributedAmountUSD
        expert { id firstName lastName }
      }
      topExperts(first: 10) {
        asAiPersona
        numberOfChats
        isCSAgent
        expert { id firstName lastName }
      }
      topCitedKnowledge {
        count
        knowledgeDocument { id title }
      }

      # Impact
      minutesSavedByRemark

      # CSAT (requires VIEW_NPS)
      csatScore
    }
  }
}

Variables

VariableTypeRequiredDescription
vendorIdID!YesYour vendor ID
startDateTime!YesPeriod start (ISO 8601)
endDateTime!YesPeriod end (ISO 8601)
timezoneString!YesIANA timezone for time series (e.g. "America/New_York")
channelConversationChannelNoFilter by channel: RemarkChat, GorgiasTicket, ZendeskTicket, KustomerConversation

Example Response

{
  "data": {
    "vendorById": {
      "conversationAggregateStatistics": {
        "numberOfChats": 1842,
        "numberOfAIChats": 1455,
        "numberOfHumanChats": 387,
        "automationRate": 0.79,
        "totalValueOfConversationsAttributedToChat": 284500.00,
        "numberOfConversionsAttributed": 156,
        "conversionRateForChatters": 0.085,
        "conversionRateForNonChatters": 0.032,
        "aovForChatters": 185.50,
        "aovForNonChatters": 142.00,
        "averageExpertResponseTime": 45,
        "medianJoinTime": 12,
        "attributedRevenueTimeSeries": [
          { "precision": "DAY", "time": "2026-03-01T00:00:00Z", "totalAttributedValue": 9500.00 },
          { "precision": "DAY", "time": "2026-03-02T00:00:00Z", "totalAttributedValue": 11200.00 }
        ],
        "topProductsByAttributedSales": [
          {
            "numberOfRecommendations": 89,
            "numberSold": 34,
            "totalSales": 6120.00,
            "product": { "id": "prod_1", "name": "Trail Runner Pro" }
          }
        ],
        "minutesSavedByRemark": 48500,
        "csatScore": 4.6
      }
    }
  }
}
FieldDescription
numberOfChatsTotal conversations in period
numberOfAIChatsConversations handled entirely by AI
numberOfHumanChatsConversations involving a human expert
automationRateFraction of chats handled by AI (0–1)
totalValueOfConversationsAttributedToChatTotal revenue attributed to chat interactions (USD)
totalValueOfConversationsAttributedToHumanChatRevenue attributed to human-handled chats
totalValueOfConversationsAttributedToAIChatRevenue attributed to AI-handled chats
numberOfConversionsAttributedNumber of orders attributed to chat
conversionRateForChattersConversion rate for visitors who chatted
conversionRateForNonChattersConversion rate for visitors who did not chat
aovForChattersAverage order value for chatters (USD)
aovForNonChattersAverage order value for non-chatters (USD)
aovForAttributedConversionsAOV for orders directly attributed to chat
aovForNonAttributedConversionsAOV for non-attributed orders
averageExpertResponseTimeAverage expert response time (seconds)
medianJoinTimeMedian time for an expert to join a chat (seconds)
totalManHoursSpentInChatTotal expert hours spent in chat
attributedRevenueTimeSeriesRevenue over time, bucketed by day/week/month
chatsByHourHistogramChat volume by hour of day
chatsByDayOfWeekHistogramChat volume by day of week
topProductsByAttributedSalesProducts ranked by attributed revenue
topExpertByAttributedSalesSingle top expert by revenue
topExpertsExperts ranked by chat count
topCitedKnowledgeMost-referenced knowledge documents
minutesSavedByRemarkEstimated minutes saved by AI automation
csatScoreAverage CSAT score (requires VIEW_NPS)

Period-over-Period Comparison

Use GraphQL aliases to fetch current and previous periods in one request:
query DashboardComparison(
  $vendorId: ID!
  $start: DateTime!
  $end: DateTime!
  $prevStart: DateTime!
  $prevEnd: DateTime!
) {
  vendorById(vendorId: $vendorId) {
    current: conversationAggregateStatistics(start: $start, end: $end) {
      numberOfChats
      totalValueOfConversationsAttributedToChat
      conversionRateForChatters
      aovForChatters
      automationRate
    }
    previous: conversationAggregateStatistics(start: $prevStart, end: $prevEnd) {
      numberOfChats
      totalValueOfConversationsAttributedToChat
      conversionRateForChatters
      aovForChatters
      automationRate
    }
  }
}

Smart Tag Aggregation

Count how often each smart tag was applied to conversations in a time range. Useful for tracking trending topics, common customer issues, or product interest over time.
Permission required: VIEW_CONVERSATIONS

Count Tags in a Period

query SmartTagSummary($vendorId: ID!, $start: DateTime!, $end: DateTime!) {
  smartTagCounts(vendorId: $vendorId, start: $start, end: $end) {
    tag {
      id
      title
      description
    }
    count
  }
}

Example Response

{
  "data": {
    "smartTagCounts": [
      {
        "tag": { "id": "tag_1", "title": "Sizing Question", "description": "Customer asked about product sizing" },
        "count": 234
      },
      {
        "tag": { "id": "tag_2", "title": "Return Request", "description": "Customer wants to return a product" },
        "count": 89
      }
    ]
  }
}

List Available Smart Tags

query VendorTags($vendorId: ID!) {
  vendorSmartTags(vendorId: $vendorId) {
    id
    title
    description
  }
}

Conversation Listing

Paginated list of conversations with filtering and sorting. Uses cursor-based pagination.
Permission required: VIEW_CONVERSATIONS
query Conversations(
  $vendorId: ID!
  $first: Int
  $cursor: ID
  $sort: [ConversationSortInput!]
  $filter: [ConversationFilterInput!]
) {
  conversations(
    vendorId: $vendorId
    first: $first
    cursor: $cursor
    sort: $sort
    filter: $filter
  ) {
    edges {
      cursor
      node {
        id
        status
        channel
        platform
        subject
        lastMessageDate
        updated
        customerIdentity {
          id
          suppliedFirstName
          email           # requires VIEW_PII
        }
        currentExpert {
          id
          firstName
          lastName
        }
        hasAttributedConversion(anyExpert: true)
        hasPositiveNPS(anyExpert: true)
        vendorConversationSummaries {
          summary
        }
        mostRecentSegmentStats {
          smartTags { id title }
          aiAppliedTags { tag weight explanation }
          aiInferredSentiment
          pairingTime
          totalTimeSpentChatting
        }
      }
    }
    totalCount
    hasNextPage
    hasPrevPage
    startCursor
    endCursor
  }
}

Variables

VariableTypeRequiredDescription
vendorIdID!YesYour vendor ID
firstIntNoPage size (default varies)
cursorIDNoCursor from previous page’s endCursor
sort[ConversationSortInput!]NoSort criteria
filter[ConversationFilterInput!]NoFilter criteria

Filter Options

Filter KeyTypeDescription
expertIdIDFilter by assigned expert
emailStringSearch by customer email
conversionStatusEnumAttributed, Converted, None
smartTagIds[ID]Filter by smart tag IDs
npsRatingEnumPositive, Negative
sentimentEnumAI-inferred sentiment
expertChatTypeEnumAI, Human, Both, HasAI, HasHuman
channels[ConversationChannel]Filter by channel type

Sort Options

FieldDirection
LastMessageDateDesc (most recent) or Asc

Pagination

Use cursor-based pagination to iterate through results:
# First page
conversations(vendorId: "...", first: 50) { ... }

# Next page
conversations(vendorId: "...", first: 50, cursor: "endCursor_from_previous") { ... }

Conversation Detail

Fetch a single conversation with its full message history.
Permission required: VIEW_CONVERSATIONS
query ConversationDetail($id: ID!, $last: Int!) {
  conversation(id: $id) {
    id
    channel
    platform
    subject
    status
    created
    updated
    externalUrl
    customerIdentity {
      id
      suppliedFirstName
      email               # requires VIEW_PII
      location
    }
    hasAttributedConversion(anyExpert: true)
    hasPositiveNPS(anyExpert: true)
    vendorConversationSummaries { summary }
    npsSurveys {                          # requires VIEW_NPS
      id
      rating
      expert { id firstName lastName }
    }
    mostRecentSegmentStats {
      smartTags { id title description }
      aiAppliedTags { tag weight explanation }
      aiInferredSentiment
      pairingTime
      totalTimeSpentChatting
    }
    events(last: $last) {
      totalCount
      hasNextPage
      hasPrevPage
      endCursor
      startCursor
      edges {
        cursor
        node {
          id
          body
          type
          created
          expert { id firstName lastName }
          detectedIntents { id name explanation }
          actionsTaken { name success }
          recommendations {
            product { id name }
            variant { id name }
          }
          knowledgeCitations {
            knowledgeDocument { id title }
          }
        }
      }
    }
  }
}

Session & Order Data

Look up browsing sessions and conversion/order details for a customer.
Permission required: VIEW_CONVERSIONS
query SessionDetails($vendorId: ID!, $lead: String!) {
  sessionByVendorId(vendorId: $vendorId, lead: $lead) {
    id
    lastUserAgent {
      browser
      deviceType
      deviceModel
    }
    conversions(last: 10) {
      edges {
        node {
          id
          created
          totalPrice
          currency
          orderNumber
          externalId
          externalUrl
          platform
          attributionMethod
          lineItems {
            quantity
            finalTotalPrice
            product { id name }
            variant { id name }
          }
          attribution {
            method
            chattingExpert { id firstName lastName }
          }
        }
      }
    }
  }
}

Key Fields

FieldDescription
totalPriceOrder total
attributionMethodHow the conversion was attributed to chat
attribution.chattingExpertThe expert credited with the sale
lineItemsIndividual products/variants in the order

Permissions Reference

Your API key inherits the permissions of the user who created it. Different data requires different permissions:
PermissionGrants access to
VIEW_CONVERSATIONSConversation data, smart tags, message history, chat analysis
VIEW_CONVERSIONSRevenue metrics, conversion rates, order details, attributed sales
VIEW_PIICustomer emails, names, IP addresses, contact info
VIEW_NPSNPS/CSAT scores and survey details
VIEW_BILLINGBilling and payment data
EDIT_ANALYTICSSmart tag management (create/edit/delete)
An admin or vendor owner will have all permissions for their vendor.

Rate Limits & Best Practices

  • Rate limiting: Rate limits may be enforced to prevent abuse and maintain quality of service
  • Request only what you need: GraphQL lets you select specific fields — smaller queries are faster
  • Use pagination: Always paginate conversation and session lists rather than fetching everything at once
  • Cache where appropriate: Dashboard statistics don’t change in real time; polling every few minutes is sufficient
  • Time ranges: Always provide start/end for dashboard stats queries — omitting them returns lifetime data which is slower
  • Timezone: Pass your local IANA timezone (e.g. America/New_York) for time series and histogram queries to get correctly bucketed data