REST API source configuration examples

The REST API source allows you to index virtually any content system exposing its data through an API. When creating your source, you must provide a JSON configuration detailing how the Coveo Platform should request content from the API and index the returned items. This configuration indicates which API calls to execute to obtain the desired items, how to parse the responses to extract relevant metadata, and which type of content these items represent.

This article offers realistic JSON configuration examples. You can either start from these examples and tailor them to your needs, or use them as a reference to create your own configuration from scratch.

Tip

In addition to the examples provided here, you can find more examples in Coveo’s connectivity library on GitHub.

When working on your REST API source configuration, you may also want to refer to the following articles:

Basic example

The configuration below results in the execution of these two queries (each along with the two specified headers):

  • GET http://example.com/api/v1/posts?type=post&expand=true&id=120

  • POST http://example.com/api/v1/users?expand=true

Source configuration
{
  "Services": [
    {
      "Url": "http://example.com/api/v1",
      "Headers": {
        "key": "value",
        "authentication": "basic"
      },
      "Authentication": {
        "Username": "@Username",
        "Password": "@Password",
        "ForceBasicAuthentication": true
      },
      "Endpoints": [
        {
          "Path": "/posts",
          "Method": "GET",
          "Paging": {
            "PageSize": 10,
            "OffsetStart": 0,
            "OffsetType": "page",
            "Parameters": {
              "Limit": "limit",
              "Offset": "page"
            }
          },
          "QueryParameters": {
            "id": "120",
            "type": "user",
            "expand": true
          },
          "ItemType": "Post",
          "Uri": "%[coveo_url]/repository/posts/%[id]",
          "ClickableUri": "%[coveo_url]/posts/%[id]",
          "Title": "%[title]",
          "ModifiedDate": "%[updated]",
          "Body": "%[html.content]",
          "Metadata": {
            "author": "%[author]",
            "id": "%[id]"
          }
        },
        {
          "Path": "/users",
          "Method": "POST",
          "ItemPath": "results",
          "PayloadParameters": {
            "id": "120",
            "type": "user",
            "expand": true
          },
          "ItemType": "User",
          "Uri": "%[coveo_url]/repository/users/%[id]",
          "ClickableUri": "%[coveo_url]/users/%[id]",
          "Title": "%[name]",
          "ModifiedDate": "%[updated]",
          "Metadata": {
            "id": "%[id]",
            "name": "%[name]"
          }
        }
      ]
    }
  ]
}

Blog posts and comments

The following configuration indexes blog posts and their comments. The comments are subitems of the blog posts.

Source configuration
{
   "Services": [
      {
         "Url": "https://example.com/blog",
         "Endpoints": [
            {
               "Path": "/posts",
               "Method": "GET",
               "ItemType": "Post",
               "Uri": "%[coveo_url]/posts/%[id]",
               "ClickableUri": "%[coveo_url]/posts/%[id]",
               "Title": "%[title]",
               "Body": "%[body]",
               "Metadata": {
                  "id": "%[id]",
                  "userid": "%[userId]"
               },
               "SubItems":[
                  {
                     "Path": "/posts/%[coveo_parent.id]/comments",
                     "Method": "GET",
                     "ItemType": "Comment",
                     "Uri": "%[coveo_url]/posts/%[coveo_parent.id]/comments/%[id]",
                     "ClickableUri": "%[coveo_url]/comments/%[id]",
                     "Title": "%[name]",
                     "Body": "%[body]",
                     "Metadata": {
                        "id": "%[id]",
                        "postid": "%[postId]",
                        "name": "%[name]",
                        "email": "%[email]"
                     }
                  }
               ]
            }
         ]
      }
   ]
}

Azure DevOps project

The following configuration indexes work items from an Azure DevOps (previously Visual Studio Team Services) project.

This configuration instructs Coveo to authenticate to Azure DevOps using OAuth, and then to retrieve work items using the Work Item Query Language (WIQL) API.

Source configuration
{
  "Services": [
    {
      "Authentication": {
        "OAuth": {
          "Query": {
            "Headers": {
            "User-Agent": "Coveobot/2.0"
            },
            "RefreshUrl": "https://app.vssps.visualstudio.com/oauth2/token",
            "Method": "POST",
            "Parameters": {
              "client_assertion_type": {
                "Type": "Payload",
                "Value": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
              },
              "client_assertion": {
                "Type": "Payload",
                "Value": "@ClientSecret"
              },
              "grant_type": {
                "Type": "Payload",
                "Value": "refresh_token"
              },
              "assertion": {
                "Type": "Payload",
                "Value": "@RefreshToken",
                "IsRefreshToken": true
              },
              "redirect_uri": {
                "Type": "Payload",
                "Value": "<YOUR_REDIRECT_URI>"
              }
            }
          },
          "Response": {
            "AccessToken": "access_token",
            "SupportsRefreshToken" : "true",
            "RefreshToken": "refresh_token",
            "ExpiresIn": "expires_in",
            "TokenType": "token_type"
          }
        }
      },
      "Url": "https://<ACCOUNT_NAME>.visualstudio.com/<PROJECT>/<TEAM>}/_apis",
      "Endpoints": [
        {
          "Path": "/wit/wiql/<QUERY_ID>",
          "Method": "GET",
          "QueryParameters": {
            "api-version": "5.0-preview.2"
          },
          "ItemType": "WorkItem",
          "ItemPath": "workItems",
          "Uri": "%[url]",
          "ClickableUri": "%[url]",
          "Metadata": {
            "id": "%[id]",
            "url": "%[url]"
          }
        }
      ]
    }
  ]
}

ServiceNow incidents and knowledge articles

The following configuration requests ServiceNow incidents and knowledge articles. The configuration includes subqueries retrieving the name and email of the user who opened the incident or authored the article.

Important

This JSON configuration is meant to be used as an example only. To index ServiceNow content, see Create a ServiceNow source. The Coveo Support team doesn’t provide help with REST API sources indexing ServiceNow content.

Source configuration
{
   "Services": [
      {
         "Url": "https://YOUR_INSTANCE.service-now.com/api/now/",
         "Authentication": {
            "ForceBasicAuthentication": "true",
            "Username": "@Username",
            "Password": "@Password"
         },
         "Endpoints": [
            {
               "Path": "/table/incident",
               "Method": "GET",
               "ItemPath": "result",
               "ItemType": "Incident",
               "Uri": "%[coveo_url]/incident/%[sysid]",
               "ClickableUri": "https://YOUR_INSTANCE.service-now.com/nav_to.do?uri=incident.do?sys_id=%[sysid]%26sysparm_view=ess",
               "Title": "%[short_description]",
               "Body": "%[description]",
               "Paging": {
                  "PageSize": 100,
                  "OffsetStart": 0,
                  "OffsetType": "item",
                  "Parameters": {
                     "Limit": "sysparm_limit",
                     "Offset": "sysparm_offset"
                  }
               },
               "Metadata": {
                  "sysid": "%[sys_id]",
                  "number": "%[number]",
                  "closecode": "%[close_code]",
                  "closenotes": "%[close_notes]",
                  "resolvedat": "%[resolved_at]",
                  "description": "%[description]",
                  "category": "%[category]"
               },
               "SubQueries": [
                  {
                     "Path": "%[coveo_parent.raw.opened_by.link]",
                     "Method": "GET",
                     "Metadata": {
                        "openedbyname": "%[result.name]",
                        "openedbyemail": "%[result.email]"
                     }
                  }
               ]
            },
            {
               "Path": "/table/kb_knowledge",
               "Method": "GET",
               "ItemPath": "result",
               "ItemType": "KB",
               "Uri": "%[coveo_url]/kb/%[sysid]",
               "ClickableUri": "https://YOUR_INSTANCE.service-now.com/nav_to.do?uri=incident.do?sys_id=%[sysid]%26sysparm_view=ess",
               "Title": "%[short_description]",
               "Body": "%[text]",
               "Paging": {
                  "PageSize": 50,
                  "OffsetStart": 0,
                  "OffsetType": "item",
                  "Parameters": {
                     "Limit": "sysparm_limit",
                     "Offset": "sysparm_offset"
                  }
               },
               "Metadata": {
                  "sysid": "%[sys_id]",
                  "number": "%[number]",
                  "description": "%[description]",
                  "published": "%[published]",
                  "meta": "%[meta]",
                  "topic": "%[topic]",
                  "category": "%[category]"
               },
               "SubQueries": [
                  {
                     "Path": "%[coveo_parent.raw.author.link]",
                     "Method": "GET",
                     "Metadata": {
                        "authorname": "%[result.name]",
                        "authoremail": "%[result.email]"
                     }
                  }
               ]
            }
         ]
      }
   ]
}

ServiceNow with RefreshEndpoints

The following configuration indexes the following ServiceNow content:

  • Knowledge articles

  • Questions, answers, and comments

  • Catalog items

  • Customer service cases

It also includes RefreshEndpoints to update the index when content is modified or deleted.

Important

This JSON configuration is meant to be used as an example only. To index ServiceNow content, see Create a ServiceNow source. The Coveo Support team doesn’t provide help with REST API sources indexing ServiceNow content.

Source configuration
{
  "Services": [
    {
      "Url": "https://YOUR_INSTANCE.service-now.com/api/now/",
      "Authentication": {
        "Username": "@Username",
        "Password": "@Password"
      },
      "Endpoints": [
        {
          "Path": "/api/now/table/kb_knowledge",
          "Method": "GET",
          "ItemPath": "result",
          "ItemType": "kbknowledge",
          "Uri": "%[coveo_url]/kb_knowledge/%[sys_id]",
          "PermanentId": "%[sys_id]",
          "ModifiedDate": "%[sys_updated_on]",
          "ClickableUri": "%[coveo_url]/nav_to.do?uri=kb_knowledge.do?sys_id=%[sys_id]%26sysparam_view-ess",
          "Title": "%[short_description]",
          "Body": "%[text]",
          "QueryParameters": {
            "sysparm_query": "workflow_state=published"
          },
          "Paging": {
            "PageSize": 100,
            "OffsetStart": 0,
            "OffsetType": "item",
            "TotalCountHeaderKey": "x-total-count",
            "Parameters": {
              "Limit": "sysparam_limit",
              "Offset": "sysparam_offset"
            }
          },
          "Metadata": {
            "short_description": "%[short_description]",
            "wiki": "%[wiki]",
            "roles": "%[roles]",
            "rating": "%[rating]",
            "description": "%[description]",
            "source": "%[source]",
            "sys_updated_on": "%[sys_updated_on]",
            "related_products": "%[related_products]",
            "number": "%[number]",
            "sys_id": "%[sys_id]",
            "flagged": "%[flagged]",
            "workflow_state": "%[workflow_state]",
            "text": "%[text]",
            "image": "%[image]",
            "article_type": "%[article_type]",
            "author": "%[author]",
            "published": "%[published]",
            "sys_tags": "%[sys_tags]",
            "kb_knowledge_base": "%[kb_knowledge_base]",
            "meta": "%[meta]",
            "topic": "%[topic]",
            "category": "%[category]",
            "kb_category": "%[kb_category]"
          },
          "RefreshEndpoints": [
            {
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "QueryParameters": {
                "sysparm_query": "workflow_state=published^sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            },
            {
              "IsDeletionQuery": true,
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "QueryParameters": {
                "sysparm_query": "workflow_state!=published^sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            },
            {
              "IsDeletionQuery": true,
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "Path": "/api/now/table/sys_audit_delete",
              "QueryParameters": {
                "tablename": "kb_knowledge",
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            }
          ],
          "SubQueries": [
            {
              "Path": "%[coveo_parent.raw.source.link]",
              "Method": "GET",
              "Metadata": {
                "source.sys_id": "%[result.sys_id]"
              }
            },
            {
              "Path": "%[coveo_parent.raw.related_products.link]",
              "Method": "GET",
              "Metadata": {
                "related_product.sys_id": "%[result.sys_id]"
              }
            },
            {
              "Path": "%[coveo_parent.raw.author.link]",
              "Method": "GET",
              "Metadata": {
                "author.name": "%[result.name]",
                "author.user_name": "%[result.user_name]",
                "author.title": "%[result.title]",
                "author.sys_id": "%[result.sys_id]",
                "author.email": "%[result.email]"
              }
            },
            {
              "Path": "%[coveo_parent.raw.kb_knowledge_base.link]",
              "Method": "GET",
              "Metadata": {
                "kb_knowledge_base.sys_id": "%[result.sys_id]"
              }
            },
            {
              "Path": "%[coveo_parent.raw.kb_category.link]",
              "Method": "GET",
              "Metadata": {
                "kb_category.sys_id": "%[result.sys_id]"
              }
            }
          ]
        },
        {
          "Path": "/api/now/table/kb_social_qa_question",
          "Method": "GET",
          "ItemPath": "result",
          "ItemType": "kbsocialqaquestion",
          "Uri": "%[coveo_url]/kb_social_qa_question/%[sys_id]",
          "PermanentId": "%[sys_id]",
          "ModifiedDate": "%[sys_updated_on]",
          "ClickableUri": "%[coveo_url]/nav_to.do?uri=kb_social_qa_question.do?sys_id=%[sys_id]%26sysparam_view-ess",
          "Title": "%[sys_id]",
          "Body": "<p>%[question]</p>%[question_details]",
          "Paging": {
            "PageSize": 100,
            "OffsetStart": 0,
            "OffsetType": "item",
            "TotalCountHeaderKey": "x-total-count",
            "Parameters": {
              "Limit": "sysparam_limit",
              "Offset": "sysparam_offset"
            }
          },
          "Metadata": {
            "question": "%[question]",
            "question_details": "%[question_details]",
            "last_activity": "%[last_activity]",
            "profile": "%[profile]",
            "active": "%[active]",
            "sys_tags": "%[sys_tags]",
            "accepted_answer_id": "%[accepted_answer.value]",
            "top_answer_id": "%[top_answer.value]",
            "has_comment": "%[has_comment]",
            "votes": "%[votes]",
            "views": "%[views]",
            "kb_category_id": "%[kb_category.value]",
            "kb_knowledge_base_id": "%[kb_knowledge_base.value]"
          },
          "RefreshEndpoints":
          [
            {
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "QueryParameters": {
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            },
            {
              "IsDeletionQuery": true,
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "Path": "/api/now/table/sys_audit_delete",
              "QueryParameters": {
                "tablename": "kb_social_qa_question",
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            }
          ]
        },
        {
          "Path": "/api/now/table/kb_social_qa_answer",
          "Method": "GET",
          "ItemPath": "result",
          "ItemType": "kbsocialqaanswer",
          "Uri": "%[coveo_url]/kb_social_qa_answer/%[sys_id]",
          "PermanentId": "%[sys_id]",
          "ModifiedDate": "%[sys_updated_on]",
          "ClickableUri": "%[coveo_url]/nav_to.do?uri=kb_social_qa_answer.do?sys_id=%[sys_id]%26sysparam_view-ess",
          "Title": "%[sys_id]",
          "Body": "%[answer]",
          "Paging": {
            "PageSize": 100,
            "OffsetStart": 0,
            "OffsetType": "item",
            "TotalCountHeaderKey": "x-total-count",
            "Parameters": {
              "Limit": "sysparam_limit",
              "Offset": "sysparam_offset"
            }
          },
          "Metadata": {
            "question_id": "%[question.value]",
            "profile": "%[profile]",
            "active": "%[active]",
            "accepted": "%[accepted]",
            "sys_tags": "%[sys_tags]",
            "answer": "%[answer]",
            "has_comment": "%[has_comment]",
            "votes": "%[votes]"
          },
          "RefreshEndpoints": [
            {
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "QueryParameters": {
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            },
            {
              "IsDeletionQuery": true,
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "Path": "/api/now/table/sys_audit_delete",
              "QueryParameters": {
                "tablename": "kb_social_qa_answer",
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            }
          ]
        },
        {
          "Path": "/api/now/table/kb_social_qa_comment",
          "Method": "GET",
          "ItemPath": "result",
          "ItemType": "kbsocialqacomment",
          "Uri": "%[coveo_url]/kb_social_qa_comment/%[sys_id]",
          "PermanentId": "%[sys_id]",
          "ModifiedDate": "%[sys_updated_on]",
          "ClickableUri": "%[coveo_url]/nav_to.do?uri=kb_social_qa_comment.do?sys_id=%[sys_id]%26sysparam_view-ess",
          "Title": "%[sys_id]",
          "Body": "%[comment]",
          "Paging": {
            "PageSize": 100,
            "OffsetStart": 0,
            "OffsetType": "item",
            "TotalCountHeaderKey": "x-total-count",
            "Parameters": {
              "Limit": "sysparam_limit",
              "Offset": "sysparam_offset"
            }
          },
          "Metadata": {
            "reference_name": "%[reference_name]",
            "reference_id": "%[reference_id.value]",
            "sys_mod_count": "%[sys_mod_count]",
            "sys_tags": "%[sys_tags]",
            "sys_id": "%[sys_id]",
            "comment": "%[comment]"
          },
          "RefreshEndpoints": [
            {
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "QueryParameters": {
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            },
            {
              "IsDeletionQuery": true,
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "Path": "/api/now/table/sys_audit_delete",
              "QueryParameters": {
                "tablename": "kb_social_qa_comment",
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            }
          ]
        },
        {
          "Path": "/api/now/table/sc_cat_item",
          "Method": "GET",
          "ItemPath": "result",
          "ItemType": "sccatitem",
          "Uri": "%[coveo_url]/sc_cat_item/%[sys_id]",
          "PermanentId": "%[sys_id]",
          "ModifiedDate": "%[sys_updated_on]",
          "ClickableUri": "%[coveo_url]/nav_to.do?uri=sc_cat_item.do?sys_id=%[sys_id]%26sysparam_view-ess",
          "Title": "%[short_description]",
          "Body": "%[description]",
          "Paging": {
            "PageSize": 100,
            "OffsetStart": 0,
            "OffsetType": "item",
            "TotalCountHeaderKey": "x-total-count",
            "Parameters": {
              "Limit": "sysparam_limit",
              "Offset": "sysparam_offset"
            }
          },
          "Metadata": {
            "delivery_time": "%[delivery_time]",
            "type": "%[type]",
            "no_search": "%[no_search]",
            "sys_updated_by": "%[sys_updated_by]",
            "price": "%[price]",
            "sys_created_on": "%[sys_created_on]",
            "recurring_frequency": "%[recurring_frequency]",
            "sys_name": "%[sys_name]",
            "image": "%[image]",
            "sys_update_name": "%[sys_update_name]",
            "meta": "%[meta]",
            "name": "%[name]",
            "short_description": "%[short_description]",
            "roles": "%[roles]",
            "icon": "%[icon]",
            "description": "%[description]",
            "mobile_picture": "%[mobile_picture]",
            "sys_id": "%[sys_id]",
            "sc_catalogs": "%[sc_catalogs]",
            "cost": "%[cost]",
            "sys_mod_count": "%[sys_mod_count]",
            "recurring_price": "%[recurring_price]",
            "billable": "%[billable]",
            "picture": "%[picture]",
            "category": "%[category]"
          },
          "RefreshEndpoints": [
            {
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "QueryParameters": {
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            },
            {
              "IsDeletionQuery": true,
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "Path": "/api/now/table/sys_audit_delete",
              "QueryParameters": {
                "tablename": "sc_cat_item",
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            }
          ],
          "SubQueries": [
            {
              "Path": "%[coveo_parent.raw.category.link]",
              "Method": "GET",
              "Metadata": {
                "category.title": "%[result.title]",
                "category.sys_id": "%[result.sys_id]",
                "category.sys_name": "%[result.sys_name]"
              }
            }
          ]
        },
        {
          "Path": "/api/now/table/sn_customerservice_case",
          "Method": "GET",
          "ItemPath": "result",
          "ItemType": "sncustomerservicecase",
          "Uri": "%[coveo_url]/sn_customerservice_case/%[sys_id]",
          "PermanentId": "%[sys_id]",
          "ModifiedDate": "%[sys_updated_on]",
          "ClickableUri": "%[coveo_url]/nav_to.do?uri=sn_customerservice_case.do?sys_id=%[sys_id]%26sysparam_view-ess",
          "Title": "%[short_description]",
          "Body": "%[close_notes]",
          "Paging": {
            "PageSize": 100,
            "OffsetStart": 0,
            "OffsetType": "item",
            "TotalCountHeaderKey": "x-total-count",
            "Parameters": {
              "Limit": "sysparam_limit",
              "Offset": "sysparam_offset"
            }
          },
          "Metadata": {
            "parent": "%[parent]",
            "caused_by": "%[caused_by]",
            "sys_updated_on": "%[sys_updated_on]",
            "support_manager": "%[support_manager]",
            "skills": "%[skills]",
            "number": "%[number]",
            "resolved_by": "%[resolved_by]",
            "problem": "%[problem]",
            "opened_by": "%[opened_by]",
            "contact": "%[contact]",
            "case": "%[case]",
            "knowledge": "%[knowledge]",
            "expected_start": "%[expected_start]",
            "opened_at": "%[opened_at]",
            "first_response_time": "%[first_response_time]",
            "resolved_at": "%[resolved_at]",
            "work_notes": "%[work_notes]",
            "short_description": "%[short_description]",
            "correlation_display": "%[correlation_display]",
            "work_start": "%[work_start]",
            "description": "%[description]",
            "close_notes": "%[close_notes]",
            "sys_id": "%[sys_id]",
            "company": "%[company]",
            "consumer": "%[consumer]",
            "assigned_to": "%[assigned_to]",
            "product": "%[product]",
            "comments": "%[comments]",
            "sla_due": "%[sla_due]",
            "comments_and_work_notes": "%[comments_and_work_notes]",
            "due_date": "%[due_date]",
            "sys_tags": "%[sys_tags]",
            "partner_contact": "%[partner_contact]",
            "account": "%[account]"
          },
          "RefreshEndpoints": [
            {
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "QueryParameters": {
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            },
            {
              "IsDeletionQuery": true,
              "DateFormat": "\\'yyyy-MM-dd\\',\\'hh:mm:ss\\'",
              "Path": "/api/now/table/sys_audit_delete",
              "QueryParameters": {
                "tablename": "sn_customerservice_case",
                "sysparm_query": "sys_updated_on>javascript:gs.dateGenerate(@RefreshDate)"
              }
            }
          ],
          "SubQueries": [
            {
              "Path": "%[coveo_parent.raw.parent.link]",
              "Method": "GET",
              "Metadata": {
                "parent.number": "%[result.number]",
                "parent.sys_id": "%[result.sys_id]"
              }
            },
            {
              "Path": "%[coveo_parent.raw.caused_by.link]",
              "Method": "GET",
              "Metadata": {
                "caused_by.reason": "%[result.reason]",
                "caused_by.type": "%[result.type]",
                "caused_by.number": "%[result.number]",
                "caused_by.short_description": "%[result.short_description]",
                "caused_by.sys_id": "%[result.sys_id]"
              }
            },
            {
              "Path": "%[coveo_parent.raw.support_manager.link]",
              "Method": "GET",
              "Metadata": {
                "support_manager.name": "%[result.name]",
                "support_manager.user_name": "%[result.user_name]",
                "support_manager.sys_id": "%[result.sys_id]"
              }
            }
          ]
        }
      ]
    }
  ]
}

Yammer messages, attachments, and permissions

The following configuration indexes a specific Yammer group’s messages and their attachments, as well as the responses to these messages and the responses' attachments.

The message attachments and responses are subitems of the messages, and the response attachments are subitems of the responses. This results in the following content structure:

  • Message

    • Attachment

    • Response

      • Attachment

This configuration also applies the same Permissions object to all items. This object hardcodes the rule that only members of the Yammer group Tech_Team can access the content.

Source configuration
{
  "services": [
    {
      "url": "https://www.yammer.com/api/v1",
      "Headers": {
        "Authorization": "Bearer @ApiKey"
      },
      "endpoints": [
        {
          "path": "/messages/in_group/01234567890.json",
          "QueryParameters": {
            "threaded": "true"
          },
          "Paging": {
            "PageSize": 20,
            "OffsetType": "cursor",
            "NextPageKey": "$.messages[-1:].id",
            "Parameters": {
              "Limit": "limit",
              "Offset": "older_than"
            }
          },
          "method": "GET",
          "itemPath": "messages",
          "itemType": "message",
          "uri": "example.com/%[id]",
          "title": "thread-strart-%[id]",
          "ClickableUri": "%[url]",
          "modifiedDate": "%[created_at]",
          "body": "%[body.parsed]",
          "metadata": {
            "messageid": "%[id]",
            "groupid": "%[group_id]",
            "threadid": "%[thread_id]"
          },
          "Permissions": [
            {
              "Name": "AllowedMemberLevel",
              "PermissionsSets": [
                {
                  "Name": "AllowedMembersSet",
                  "PermissionsFromMetadata": [
                    {
                      "Name": "Tech_Team",
                      "Type": "Group",
                      "PermissionType": "YammerGroup",
                      "IsAllowedMember": true,
                      "AdditionalInfo": {
                        "group_id": "%[groupid]"
                      }
                    }
                  ],
                  "isAnonymousAllowed": "false"
                }
              ]
            }
          ],
          "SubItems": [
            {
              "ItemPath": "attachments",
              "ItemType": "Attachments",
              "uri": "example.com/attachement/%[id]",
              "title": "attachment-%[id]-%[name]",
              "ClickableUri": "%[url]",
              "modifiedDate": "%[created_at]",
              "body": "%[description]",
              "metadata": {
                "messageid": "%[id]",
                "groupid": "%[group_id]",
                "threadid": "%[thread_id]"
              },
              "Permissions": [
                {
                  "Name": "AllowedMemberLevel",
                  "PermissionsSets": [
                    {
                      "Name": "AllowedMembersSet",
                      "PermissionsFromMetadata": [
                        {
                          "Name": "Tech_Team",
                          "Type": "Group",
                          "PermissionType": "YammerGroup",
                          "IsAllowedMember": true,
                          "AdditionalInfo": {
                            "group_id": "%[groupid]"
                          }
                        }
                      ],
                      "isAnonymousAllowed": "false"
                    }
                  ]
                }
              ]
            },
            {
              "Path": "/messages/in_thread/%[coveo_parent.threadid].json",
              "method": "GET",
              "itemPath": "messages",
              "itemType": "message",
              "uri": "example.com/%[id]",
              "title": "reply-%[id]",
              "ClickableUri": "%[url]",
              "modifiedDate": "%[created_at]",
              "body": "%[body.parsed]",
              "metadata": {
                "messageid": "%[id]",
                "groupid": "%[group_id]",
                "threadid": "%[thread_id]"
              },
              "Permissions": [
                {
                  "Name": "AllowedMemberLevel",
                  "PermissionsSets": [
                    {
                      "Name": "AllowedMembersSet",
                      "PermissionsFromMetadata": [
                        {
                          "Name": "Tech_Team",
                          "Type": "Group",
                          "PermissionType": "YammerGroup",
                          "IsAllowedMember": true,
                          "AdditionalInfo": {
                            "group_id": "%[groupid]"
                          }
                        }
                      ],
                      "isAnonymousAllowed": "false"
                    }
                  ]
                }
              ],
              "SubItems": [
                {
                  "ItemPath": "attachments",
                  "ItemType": "Attachments",
                  "uri": "example.com/attachement/%[id]",
                  "title": "attachment-%[id]-%[name]",
                  "ClickableUri": "%[url]",
                  "modifiedDate": "%[created_at]",
                  "body": "%[description]",
                  "metadata": {
                    "messageid": "%[id]",
                    "groupid": "%[group_id]",
                    "threadid": "%[thread_id]"
                  },
                  "Permissions": [
                    {
                      "Name": "AllowedMemberLevel",
                      "PermissionsSets": [
                        {
                          "Name": "AllowedMembersSet",
                          "PermissionsFromMetadata": [
                            {
                              "Name": "Tech_Team",
                              "Type": "Group",
                              "PermissionType": "YammerGroup",
                              "IsAllowedMember": true,
                              "AdditionalInfo": {
                                "group_id": "%[groupid]"
                              }
                            }
                          ],
                          "isAnonymousAllowed": "false"
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Then, in the Content security tab of the source, the following permission configuration would instruct Coveo to retrieve the members of the Tech_Team group, and then each member’s email address.

Permission configuration
{
  "url": "https://www.yammer.com/api/v1",
  "Headers": {
     "Authorization": "Bearer @ApiKey"
  },
  "Identities": {
    "YammerGroup": {
      "PermissionSubQueries": [{
        "Path": "/users/in_group/%[coveo_parent.group_id].json",
        "Method": "GET",
        "itemPath": "users",
        "Name": "%[email]",
        "additionalInfo": {
          "email": "%[email]"
        },
        "Type": "User",
        "PermissionType": "Employees"
      }
      ]
    },
    "Employees": {
      "PermissionsFromMetadata": [{
        "Name": "%[coveo_parent.email]",
        "Type": "User"
      }]
    }
  }
}