MindLink API

Version 17.2

On this page:


API Developers reference

1 API Concepts and Technical Overview

1. 1 URLs and versioning

All requests to the API are made over HTTP. Your system administrator will be able to provide you with the base URL to use for the API, for example https://api.mycompany.net/.Resources are versioned to ensure a stable interface is available for developers while allowing breaking changes to be made in future versions. All requests to the API must include the target version in the URL; at present the only version permitted is v1. Thus, with the above base URL, a request to the /Channels resource on the Collaboration service would be made to https://api.mycompany.net/Collaboration/v1/Channels. 

1.1. 1 Format of request and response to the API

A developer may choose the format of the request or response to the API by setting the HTTP request headers “Accept” and “Content-Type” to “application/json” or “application/xml” for JSON and XML respectively. 

2. 2 Channels

The API introduces a concept of channels – a source and/or destination for messages. A channel may represent a chat room, an individual user, or (in future versions of the API) more esoteric data sources such as RSS feeds or e-mail accounts.Channels have a unique ID which is used to refer to them throughout the API. Each ID has a prefix indicating the underlying transport that the channel represents. At present these prefixes are:

  •         chat-room: - for channels representing chat rooms
  •         contact: - for channels representing an IM with an individual contact

It is recommended that, where possible, API users avoid depending on these prefixes and instead rely on proper provisioning of channels (see 1.3.2) and administrator-supplied configuration via meta-data (see 1.3.3). 

3. 3 Agents

An agent is the API’s representation of a single consumer of its services. The API maintains connections to underlying chat or collaboration systems on behalf of each configured agent. Agents have an ID defined by the administrator, which users of the API must be given in order to successfully authenticate (see 1.4). 

3.1. 1 Standard vs. Advanced agents

There are two distinct use cases intended for the API: standard agents and advanced agents.Standard agents have the ability to send and receive messages to channels which have been configured (‘provisioned’ – see 1.3.2) by the system administrator. Advanced agents have the same abilities as standard agents, but can also modify their own and other agents’ configuration.Standard agents are limited to the authentication and collaboration APIs (see sections 2 and 3), while advanced agents also have access to the provisioning API (see section 4). 

3.2. 2 Provisioned channels

The API gives control of which channels an agent is allowed to communicate with to the system administrator, rather than the agent developers. Administrators must provision an agent before it is used, and in doing so must specify the channel(s) the agent is allowed to access.Agents can retrieve the list of their provisioned channels by accessing the /Channels resource. Administrators or advanced agents can update this list using the /Agents/{agentId}/Channels/{channelId} resource.If an agent attempts to interact with a channel which they are not provisioned on, an error will be returned from the API. 

3.3. 3 Meta-data

Each agent has a ‘meta-data’ dictionary defined by the administrator. This is intended to allow agents to be configured through the API instead of through other means.Administrators or advanced agents can modify the meta-data via the /Agents/{agentId}/MetaData resource. Agents can retrieve their own meta-data via the Collaboration API’s /MetaData resource.The meta-data dictionary consists of a set of key/value pairs. Both keys and values are stored and transmitted as strings. There is no constraint on the content of keys or values, except that keys must be unique within each meta-data dictionary (as per a Java Map or C# Dictionary). 

4. 4 Authentication

In order to use the collaboration or provisioning APIs, callers must first authenticate as a registered user of the API, and supply the ID of an agent that they are provisioned to use.Upon successful authentication a token is returned, and this should be passed whenever a request is made to the Collaboration or Provisioning APIs. Tokens will expire after a period of time, and agents will need to re-authenticate in order to obtain a new one. 

4.1. 1 Creating a token

Tokens are created by making a POST request to the /Tokens/ resource. On successful authentication, a token will be returned. Information about the token (including the expiry date) can be retrieved from the /Tokens/{token} resource.While the expiry date is published, it is recommended that users do not schedule reauthentication, but instead rely on return codes issued by API methods. A typical workflow for making a request would therefore be:
1.       Check if a token has been previously retrieveda.       If not, authenticate
2.       Request the resource with the previously obtained token
3.       Check the response code retrieved from the APIa.       If 401 (not authorised) – re-authenticate and go back to step 2. 

4.2. 2 Passing tokens

When calling Collaboration or Provisioning API methods, a valid token must be given in an Authorization header. The type of authorization should be ‘FCF’. A token of ‘abc123’ would therefore result in the following header being sent on all requests: Authorization: FCF abc123 

5. 5 Notation used in documentation

This section describes some of the notation used in the API documentation which follows. 

5.1. 1 Arguments lists

  •        Arguments presented with a name in braces (for example {id}) are given as part of the URL when making the request.
  •        Arguments presented with a name in angle brackets (for example ) are supplied as the entire body of the request – that is, they are not referred to by name.

2   Authentication REST API

1. 1   /Tokens/ resource

Image The /tokens/ resource allows the creation of new authentication tokens for use with the Collaboration and Provisioning APIs. For an overview of how authentication works in the MindLink API, see section 1.4.The /tokens/ resource supports only the POST method – there is no way to enumerate all tokens. The POST payload must contain three arguments:

  •    Username – the account name of the user wishing to use the API
  •    Password – the password for the given account
  •    AgentId – the ID of the agent the user wishes to use when accessing the API

On success, the newly generated token will be returned. This will need to be passed to any call made to the Collaboration or Provisioning APIs. Information on the token is available via the /Tokens/{token} resource.The ‘super user’ (configurable using the management tool) may authenticate and access the provisioning service. This can be done using an empty ‘AgentId’. 

2. 2   /Tokens/{token} resource

Image The /Tokens/{token} resource retrieves information about the specified token. No authentication is required in order to access this resource.The resource returns a TokenDetails object, which contains the following members:

  •          Username (string) – the (Windows) username associated with the token
  •          AgentID (string) – the unique Agent ID associated with the token
  •          ExpiresTimestamp (long) – the timestamp at which the token will expire

3   Collaboration REST API

1. 1   /Channels resource

Image The /Channels resource allows an agent to view information about all of the channels it is provisioned for, and can currently interact with.Specifically, the resource will return a list containing all channels that the agent is provisioned for that are currently in a state such that the agent can send and receive messages. If the agent is not in a position to send/receive messages to a channel (for example, if the agent has been kicked or removed from a chat group) the channel will not be displayed in the list.Each channel has the following members:

  •          CanAcceptFiles (boolean) – whether or not the channel can accept file uploads
  •          Description (string) – a textual description of the channel
  •          DisplayName (string) – a user-friendly display name for the channel
  •          EmailAddress (string) – the e-mail address if any associated with the channel
  •          Id (string) – the unique ID of the channel
  •          IsReadOnly (boolean) – whether or not the channel is read only. DEPRECATED

 o   The IsReadOnly property cannot be reliably determined from the underlying chat system, it has therefore been deprecated.

  •          Metadata (Map {string,string}) – channel-specific metadata/state (not implemented but included for future versions)
  •          Subject (string) – a textual subject of the channel
  •          MaxMessageLength (string) – the maxium message length allowed to be sent
  •          MaxStoryLength (string) – the maximum story length allowed to be sent

 All members may be null except for Id and DisplayName.The ID of the channel can be used to access more information about the channel and retrieve and post messages – see the /Channels/{id} resource and /Channels/{id}/Messages resource. 

2. 2   /Channels/{id} resource

Image The /Channels/{id} resource returns information about a channel with the specified ID. Agents are only allowed to view channel info for channels they have been provisioned for (see section 1.3.2).For information on the members of the Channel object returned, see the documentation for the /Channels resource. 

3. 3   /Channels/{id}/File/{fileName} resource

Image The /Channels/{id}/File/{fileName} resource allows agents to upload files to channels. The channel ID and file name must be specified in the requested URL; the file itself should be streamed in the request body.If the request is successful, no body is returned. Agents should check for a 204 (No Response) status code to determine success. 

4. 4   /Channels/{id}/Messages resource

Image The /Channels/{id}/Messages resource allows agents to both query existing messages in a channel and post new messages into it. To retrieve a list of existing messages, the ‘take’ parameter must be provided indicating how many messages should be retrieved. The response may contain less than the request number depending on the configuration of the channel, and the back-end chat system. A Message has the following properties:

  •          Id (string) – a unique ID for the message
  •          IsAlert (boolean) – whether the message is an ‘alert’ or not
  •          SenderId (string) – the ID of the user/agent sending the message
  •          ChannelId (string) – the ID of the channel the message was sent to
  •          Subject (string) – the subject of the message
  •          Text (string) – the main content of the message
  •          MessageParts (Array) – the main content of the message, as parts.
  •          Timestamp (long) – the timestamp at which the message was sent

When sending a message, only the IsAlert and either the Text or MessageParts fields need to be provided, and optionally the Subject field can be provided. All other properties are ignored. If a message has a non-empty Subject, it will be treated as a ‘Story’ where supported by the back-end chat system. This will typically render the message as a hyperlink, whereby users can click on the subject text in order to see the full content of the message. The IsAlert property correlates to the back-end chat system’s “alert” functionality. Typically, alert messages will result in more aggressive notifications to end users (e.g. sounds or popup windows).

4.1. 1 Message Parts (v18.6+)

Message parts can be used to create or process messages that are more complex, such as those that contain links to other groups or users. Each MessagePart has a ‘__type’ property that determines which type of message part it is, plus other properties depending on the part:

PlainTextMessagePart – represents plain text

  • __type: ‘PlainTextMessagePart:http://schemas.fcg.im/foundation/v1/collaboration’
  • Text (string) – The text content

HyperlinkMessagePart – a link that can be clicked to navigate to a URL

  • __type: ‘HyperlinkMessagePart:http://schemas.fcg.im/foundation/v1/collaboration’
  • Text (string) – The text that is displayed
  • Url (string) – The URL to navigate to when the hyperlink is clicked

ChannelLinkMessagePart – a link that can be clicked to join and open a channel, if the user has permission to do so

  • __type: ‘ChannelLinkMessagePart:http://schemas.fcg.im/foundation/v1/collaboration’
  • ChannelName (string) – The channel's name (this is what will be displayed as text)
  • ChannelId (string) – The ID of the channel

HashtagMessagePart – a hashtag that can be used to filter similar messages

  • __type: ‘HashtagMessagePart:http://schemas.fcg.im/foundation/v1/collaboration’
  • Hashtag (string) – The hashtag as it will appear to the user

Important note: When generating message parts, the "__type" property must be specified before all others; if another property is placed higher, the request will fail.

See the code samples for examples of how to utilize message parts.

5. 5   /Channels/{id}/State resource

Image The /Channels/{id}/State resource allows agents to query the current state of one of the channels they are provisioned in.The ChannelState type has the following properties:

  •          Subject (string) – the subject of the channel
  •          Presence (Presence) – the current presence of the channel
  •          PresenceText (string) – the current presence text of the channel

All properties may be null or empty if not applicable to the underlying channel type.Presence is an enumeration and will be represented as an integer in responses:

  •          0: Unknown
  •          100: Available
  •          150: AvailableIdle
  •          200: Busy
  •          250: BusyIdle
  •          300: DoNotDisturb
  •          400: BeRightBack
  •          500: Away
  •          600: Offline

6. 6   /Channels/{id}/Me resource (v19.1+)

Channels ChannelId Me
The /Channels/{id}/Me resource allows agents to update their own state in the channel, such as whether they are composing a message. The update is passed in as a ChannelMe object. ChannelMe has the following properties:

  •          IsComposing (boolean) – whether or not the bot is composing a message.

The IsComposing property will only function in private 1-to-1 conversations. When setting IsComposing to true, the bot will appear to be typing a message. This will show up in the other user's client with a message such as "bot is typing a message...". This message will automatically disappear after a period of time (generally around 30 seconds). When IsComposing is set to false, the notification will disappear; however, there may be a delay of a few seconds following the request before the other user sees the change.

7. 7   /Channels/Search resource

Image The /Channels/Search resource allows agents to search for messages in the history of one or more channels. The search criteria are passed in as a MessageSearchCriteria object.MessageSearchCriteria has the following properties:

  •          SearchTerm (string) – the word(s) to search for (separated by spaces)
  •          MatchCase (boolean) – whether or not to search case-sensitively
  •          MatchExact (boolean) – whether the search terms should be matched as an exact phrase rather than searching for individual words
  •          MatchAll (boolean) – whether all the words must be matched or just some
  •          FromDate (string) – the date to start searching at (inclusive)
  •          ToDate (string) – the date to end searching at (inclusive)
  •          DaysBack (integer) – the number of days to search back from the current day (including the current day)
  •          OnDate (string) – the single date to search for results on
  •          Limit (integer) – the maximum number of results to return
  •          ChannelIds (string[]) – the channels to be searched

 FromDate, ToDate and OnDate are culture-sensitive, and have to be formatted based on the United States culture (en-US). If no UTC offset is provided, the date is assumed to be in UTC. Examples:

  •          mm/dd/yyyy hh:mm:ss -hh:mm

o   “05/15/2012 22:30:00 +06:00”

  •          mm/dd/yyyy -hh:mm

o   “05/15/2012 +06:00”

  •          mm/dd/yyyy

o   “05/15/2012”     NOTE: This is assumed to be in UTC since no time offset is specified. The date-related properties are listed in ascending order of priority – that is, if OnDate is specified it will override DaysBack and FromDate/ToDate, and similarly if DaysBack is specified then FromDate/ToDate will be ignored.The PostSearchResultSet type has the following properties:

  •          ChannelId (string) – the ID of the channel the results in the set have been returned for
  •          Count (integer) – the number of results in the set
  •          MaxMessageId (string) – the largest message ID of the set
  •          Messages (Message[]) – the messages in the set
  •          MinMessageId (string) – the smallest message ID of the set

 For the definition of Message see the documentation for the /Channels/{id}/Messages resource.

8. 8   /Events resource

Image The /Events resource allows agents to retrieve a ‘stream’ of events which are occurring. The resource implements the long polling (or ‘comet’) pattern – requests made will not return until either an event is available or a timeout occurs. 

8.1. 1   Event types

There are three event types available as of V1:

  •          Message events – when a message has been received on a channel
  •          MetaData events – when an administrator has modified the agent’s metadata
  •          Channel state events – when the state of a channel has changed

Agents must provide a comma-separated list of event types they are interested in in the types parameter. The valid values are: message, meta-data, and channel-state. 

8.2. 2 Filtering

The message and channel-state types may be filtered by channel ID. The channels argument should be a comma-separated list of channel IDs that the agent is interested in retrieving events for. If the list is empty, then events for all channels will be returned. Note: the API does not validate channel IDs passed to this resource; if invalid IDs are passed they will be accepted but will fail to match any events.

The message type may also be further filtered by providing a regular expression to match the message content. The MindLink API supports regular expressions compatible with the .NET CLR – for a full listing of supported language elements, see the MSDN documentation at http://msdn.microsoft.com/en-us/library/az24scfc(v=VS.100).aspx.

The origin argument should be a comma separated list of the origin of messages that the agent is interested in retrieving events for. The options are ‘local’ and ‘remote’:

  •          Local: will allow the agent’s own messages to be returned.
  •          Remote: will allow any other user’s messages to be returned

Note that if the list is empty then both ‘local’ and ‘remote’ messages will be returned. 

8.3. 3   Response types

All events have a set of common properties, defined as a BaseSubscriptionEvent. These are:

  •          EventId (long) – the unique ID for the event
  •          Time (long) – the timestamp at which the event occurred
  •          InstanceId (string) – the instance ID of the service.

Each of the three possible event types then defines further properties:MessageEvent:

  •          ChannelId (string) – the ID of the channel the message was received on
  •          Sender (string) – the ID of the user or agent who sent the message
  •          Subject (string) – the subject of the message (only set when this is a story message)
  •          Content (string) – the textual content of the message (note that if the Subject property is set this will be the story content)


  •          Key (string) – the metadata key that was changed
  •          Value (string) – the new value of the key (or null if it was removed)


  •          ChannelId (string) – the ID of the channel whose state has changed
  •          Active (boolean) – whether or not the agent is now active in the channel

8.4. 4   Event IDs

Each event is assigned a numeric ID, retrievable from the EventId property. When making a request to the /Events resource, agents should pass in the last ID they received, so that the API can filter out previous events. If an agent passes a last-event argument of 0, then all cached events will be returned. Agents should only do this when they initially begin listening to events, and in subsequent calls should pass the most recent event ID back. 

8.5. 5 Instance IDs

Each event includes an instance ID that corresponds to the specific API service instance; each time the API service is started or re-started it generates a new unique ID. The ID is used to ensure proper re-synchronization of the event channel over service re-starts.

When an agent first requests events from the Events resouce they will not include the instance ID as an argument – this is the discovery phase. When the agent gets their first events back they store a local copy of the instance ID which is included in each event, and then use it as a parameter when making subsequent requests to the resource. The API service will compare the instance ID in the requests with that of its own generated instance ID, and if they do not match (because the service has been re-started between event poll requests) then the service will return 410 Gone. On receipt this error response, the agent knows that the service instance has changed and that it should reset its last-event counter back to 0 to match that of the service and should fetch the events resource again without including the instance ID. This will allow all the new cached events on the service to come down so that the agent can re-sync their local copy of the instance ID and continue using it to make future requests to the resource.

Without including the instance ID using the pattern described above, the agent loses a degree of failure resilience. If the agent is unaware that the service has been re-started and its event counter reset to 0 then it will only receive events again once the number of cached events on the service exceeds the last-event count.

8.6. 6   Long polling and timeouts

The /Events resource will only return when either a relevant event is received, or when a set period of time has elapsed. The default timeout is 30 seconds, but this can be modified by the API administrator.Each agent maintains a buffer or cache of events which are eligible to be returned when this resource is accessed. These events time out themselves after, by default, 15 seconds. This means that an agent that was to receive all relevant events should start a new request to the /Events resource within 15 seconds of receiving the results of a previous request. In practice, it is recommended that the request is initiated immediately when the previous request is returned. 

9. 9   /MetaData resource

Image The /MetaData resource allows agents to retrieve the ‘MetaData’ configured for the agent by the system administrator (see section 1.3.3).

4   Provisioning REST API

1. 1   /Agents resource

Agents The /Agents resource allows administrators and advanced agents to view all existing agents.A ProvisionedAgent has the following members:

  •          Id (string) – the unique ID of the agent
  •          UserName (string) – the username the agent will use to log into the chat system with
  •          Channels (List{ProvisionedChannel}) – the channels the agents is allowed to use
  •          MetaData (Dictionary{string,string}) – the agent’s custom meta-data
  •          ProvisioningMode (ProvisioningMode) – the agent’s level of access to the provisioning API (v18.6+, takes priority over CanProvision)
  •          CanProvision (boolean) – true if the agent can access the provisioning API
  •          State (ProvisionedAgentState) – the current state of the agent
  •          Users (List{String}) – the IDs of the users who may use the agent

ProvisionedChannels have the following members:

  •          Id (string) – the ID of the channel. Can be retrieved from the/Channels resource.
  •          State (ProvisionedChannelState) – the current state of the channel

ProvisionedAgentState and ProvisionedChannelState are enumerations with the following values:

  •          0: Idle
  •          1: Activating
  •          2: Active

ProvisioningMode (v18.6+) is an enumeration with the following values:

  •          0: Unspecified – will not be returned by a GET; when used in a PUT, uses CanProvision instead. This is the default value.
  •          1: None – the agent cannot access the provisioning API.
  •          2: System – the agent can access all operations of the provisioning API.
  •          3: Self – the agent can access the provisioning API only to access/modify its own data.

See the “Provisioning modes” row on each table in this section for more information on which provisioning modes have access to which operations.

2. 2   /Agents/{agentId} resource

Agents AgentId The /Agents/{agentId} resource allows administrators and advanced agents to view, create, modify and delete agents by their ID.See the /Agents resource for details of the ProvisionedAgent type. Note that the State member of both ProvisionedAgent and ProvisionedChannel is read-only, and cannot be modified with a PUT request.When creating or updating an agent with a PUT request, the ID passed as a property of the ProvisionedAgent must match the ID in the resource URL. If they do not match, the API will return a 400 Bad Request response.

3. 3   /Agents/{agentId}/Channels resource

Agents AgentId Channels The /Agents/{agentId}/Channels resource returns all channels that the agent with the specified ID is provisioned to access. See the /Agents resource for details of the ProvisionedChannel type
Note that this resource is read-only. To add or remove channels, use the /Agents/{agentId}/Channels/{channelId} resource.
Also note that self-provisioning agents can use this resource, but only if the given agentId is their own.

4. 4   /Agents/{agentId}/Channels/{channelId} resource

Agents AgentId Channels ChannelId The /Agents/{agentId}/Channels/{channelId} resource allows provisioned channels to be added or removed from an agent.Channel IDs can be retrieved from the/Channels resource. 

5. 5   /Agents/{agentId}/MetaData resource

Agents AgentId MetaData The /Agents/{agentId}/MetaData resource allows retrieval or replacement of all of an agent’s meta-data in one operation.Individual meta-data keys can be modified via the /Agents/{agentId}/MetaData/{key} resource.

6. 6   /Agents/{agentId}/MetaData/{key} resource

Agents AgentId MetaData Key The /Agents/{agentId}/MetaData/{key} resource allows individual meta-data key/value pairs to be viewed, created, modified and deleted.

7. 7   /Channels resource

Channels The /Channels resource allows administrators and advanced agents to search for channels by their display name.A dictionary containing all channels matching the given query string will be returned. The dictionary maps channel IDs onto display names. The search parameter cannot be empty, otherwise a 400 Bad Request will be returned.This method requires the currently authorised user to have specified a valid agent when they acquired their token, otherwise a 400 Bad Request will be returned.

8. 8   /Users resource

Users The /Users resource allows administrators and advanced agents to view all existing users. Users are associated with agents by inserting their IDs into the agent’s configuration via the /Agents/{agentId} resource.A ProvisionedUser has the following members:

  •          UserId (string) – the unique ID of the user
  •          UserName (string) – the username the user will use to authenticate

As of version 1, the UserName must be a user found in Active Directory in the format of DOMAIN\user. 

9. 9   /Users/{userId} resource

Users UserId The /Users/{userId} resource allows administrators and advanced agents to view, create, modify and delete users by their ID.See the /Channels resource for details of the ProvisionedUser type. Users are associated with agents by inserting their IDs into the agent’s configuration via the /Agents/{agentId} resource.When creating or updating a user with a PUT request, the ID passed as a property of the ProvisionedUser must match the ID in the resource URL. If they do not match, the API will return a 400 Bad Request response. 

10. 10   /Throttles resource

Throttles The /Throttles resource allows administrators and advanced agents to view all existing throttles.A ProvisionedThrottle has the following members:

  •          Id (string) – the unique ID of the throttle.
  •          Type (ProvisionedThrottleType) – the type of the throttle.
  •          Threshold (int) – The maximum number of operations the throttle will allow (the behavior of this depends on the                        ProvisionedThrottleType).
  •          Agents (List) – The IDs of agents to which the throttle will apply.

ProvisionedThrottleType is an enumeration with the following values:

  •          0: MessagesPerMinute
  •          1: TargetedMessagesPerMinute
  •          2: ConcurrentTransfers

11. 11   /Throttles/{throttleId} resource

Throttles ThrottleId The /Throttles/{throttleId} resource allows administrators and advanced agents to view, create, modify and delete throttles by their ID.See the /Throttles resource for details of the ProvisionedThrottle type.When creating or updating a throttle with a PUT request, the ID passed as a property of the ProvisionedThrottle must match the ID in the resource URL. If they do not match, the API will return a 400 Bad Request response.When updating a throttle with a PUT request, the Type property must be preserved; otherwise the API will return a 400 Bad Request response. This is to simplify how changes need to be propagated around the service. 
Getting Started Documentation

Getting Started Overview

This document is an introduction to the main concepts of the MindLink API, as well as a walkthrough of initial steps to get up and running with performing basic collaboration and provisioning concepts. It is meant as a complimentary initial guide to the “MindLink API Developers Guide” document.

We assume you are familiar with Microsoft Office Communications Server/Lync and its

Group/Persistent Chat Server role, and the types of applications that are typically built to extend it – “Communications Enabled Business Processes” (CEBP).

We also assume you are familiar with the concepts of using web services (in any programming language of your choice), including the RESTful web services design pattern, HTTP headers, and the parsing and constructing of JSON and XML requests and responses. As such, the examples here will be programming-agnostic, dealing in terms of HTTP requests and responses only.

The MindLink API is a server component that exposes a REST-like API web service with which applications for an underlying Lync Persistent Chat instance can be written.

It allows the following kinds of applications to be written with minimal code, and in any programming language capable of making HTTP requests:

• Applications that post message data into a chat room or send as an instant-message to a user.

• Applications that listen for message data posted to chat rooms or sent as instant-messages and then take a related action – including posting message data back into the chat system. In contrast, the level of abstraction and the programming paradigm offered by the web service API is not meant to be a platform on top of which full-client applications are written. The general rule here is:

• Autonomous agent applications that pump message or presence data in and out of the chat system can and should be written against the MindLink API.

• Applications that represent a human user on the system, or which offer any form of UI into which a human user can log on, cannot and should not be written against the MindLink API. Instead, these applications should leverage lower-level SDKs which MindLink Software’s consulting team can assist with. This is the case because:

• We want to present a very simple API that makes accomplishing CEBP integration as simple as possible.

• In our experience, most applications in an enterprise require only very simple functionality, and it is these applications are written by developers that do not have Lync SDK experience or the time to learn the Lync SDKs.

• Our provisioning and application control model does not map to application behaviour required of an application that represents a human user.

• Support for deployment against a topology without PChat (17.3). This can also include IM only or GC only modalities and if desired, both.

1. 1 Provisioning and Control

The MindLink API does not only offer web services to send and receive collaborative message data - we also offer a provisioning and control system, such that system administrators can control, throttle and reconfigure applications running against the web services in real-time in production.

This is an extremely important and powerful concept, since it eradicates many of the issues of ongoing application maintenance, security, and chat-system protection from rogue applications that have plagued large and small enterprises running CEBP applications against Lync in the past.

We introduce two roles in the development and production lifetime of an application:

• The developer:

o Writes the application code.

o Architects the code to take all application configuration from calls to the API web service itself.

o Does not write application code to join or leave chat rooms or subscribe/unsubscribe to specific users, only to respond to and pump message data in and out of those chat rooms.

• The administrator:

o Owns the MindLink API web service.

o Provisions and configures all agents on the MindLink API instance, including their credentials, what channels they are joined to, and any application-specific configuration.

o Does this by making calls to the MindLink Provisioning web service using custom tooling written in-house.

Figure 1 - Administrator and Developer Roles
This essentially inverts the traditional “bot” paradigm – whereby the application is driven and configured from the central web service, not via configuration local to its installation. Furthermore, if the application is written to respond to configuration changes correctly, the application can be dynamically reconfigured on demand by an administrator on the central web service.

6 Key Entity Concepts

Here we introduce the main concepts involved with working with the MindLink API.

1. 1 Agents

You can think of an Agent as representing an application on the chat system. Agents live constantly in-memory inside the MindLink web service node, and maintain the online endpoint on the chat system.

Typically there will be one agent per application, and hence the MindLink web service node will have many agents running simultaneously, all logged on and listening for messages from the underlying chat system. When an application makes calls to use the agent, under-the hood the MindLink web service simply looks up the appropriate agent instance and uses that to process the requests.

Figure 2 - Collaboration service mapping requests to agents
To configure a new application, an administrator will create a new agent and configure it with the credentials that the application will be seen to use by other users. He will do this by making a request to the Provisioning service. Note that the administrator must simply provide a single sipaddress – since the connection made by the agent on the MindLink web service node to the chat system is via trusted connection, no user name/password credentials are required.Image
As soon as an agent is created it will log on and show its presence as available, until it is deleted. If an incorrect sip-address is provided and as such log-on cannot occur, it will continue re-trying to connect until such time that the administrator modifies the agent’s sip-address. Similarly, if the agent becomes unexpectedly disconnected due to network connectivity loss etc. the agent will continue re-trying to connect.Image
Figure 4 - Agent state
The agent reports its state via the web service to the administrator via a State property. If an application makes calls to the collaboration service e.g. to send a message when an agent is not active then the request will be returned with a 503 service unavailable error.
Note: When using a Microsoft Lync or Office Communications Server backend, agents connect as a trusted autonomous application. Microsoft Persistent/Group Chat only supports trusted endpoints that are backed by an object in Active Directory. This implies that an Active Directory User object must be used to provide the SIP address for an agent, otherwise the agent will be refused connection by Microsoft Persistent/Group Chat. This means that the agent can have a SIP URI of a regular user, but not that a trusted application endpoint configured by the NewCsTrustedApplicationendpoint cmdlet.

2. 2 Channels

A “Channel” represents a source and destination of message data. This is a generalisation over both instant-messaging and chat room communication – i.e. a channel can either be a chat room or a remote user.

Agents are configured with channels by the administrator. Adding a channel to an agent will immediately join the agent to the chat room or subscribe the agent to a user’s presence. This will make the channel “active” and allow messages to be sent and received on the channel.

State: Active
Figure 5 - Channels and agent relationship
Unlike with agent state, there is no reconnection logic for failed channel joins or subscribes. An administrator must remove and re-add a channel to an agent if the initial join or subscribe fails.

Figure 6 - Channel state
Channels report their state to both the administrator and the application via a State property. If an application tries to send a message to a channel that is not active or not provisioned, a 403 forbidden error is returned.

3. 3 Users

The final entity in the MindLink API model is the “User”. You will notice that while an agent is provisioned with the user name with which it will appear on the chat system (the sip address), this is not the same as the credentials with which applications will authenticate with the web services to obtain access to make collaboration and provisioning web service calls.

This is the role that the “User” covers – i.e. it represents a set of credentials with which an application can authenticate itself against the web service. We have chosen this pattern so that application credentials and authorization at the web-service layer are decoupled from the underlying chat-system credentials (sip-address), used to post messages from an application.

There is therefore an explicit mapping between “Users” created to specify web-service credentials, and the “Agent” that authenticated applications can use to post messages. This mapping is such that an Agent is configured with the users that can make web service calls to it.

State: Active
Figure 7 - User and agent relationship
Note that the difference between the mapping of an agent to its channels and an agent to its users is that the channels can be considered an agent-specific sub-collection whereas users are a globally defined collection that the agent maintains a mapping to.

For clarity, consider the provisioning of a new application that will appear on the chat system as sip:app-1@domain.com. The application itself will make calls to the collaboration service to send messages which will appear as coming from that SIP address. However, the application itself will not authenticate against the MindLink API services using that SIP address or any related account, it will instead authenticate itself with the domain\bot1 Active Directory account.

The administrator would provision the following (note that IDs are arbitrary strings specified on creation by the administrator):

• A User with user name domain\bot1 and ID user1

• An agent with user name sip:app-1@domain.com, ID agent1, and a users collection that contains “user1”.

The application would then be configured to authenticate with the domain\bot1 credentials, and specify that it wishes to use agent1 to service its calls.

Agent: agent1
Figure 8 - Example configuration

4. 4 Super User

The “super user” is a single special kind of user that is configured not via the provisioning web services but on installation in the MindLink Management Tool configuration. This user has default provisioning rights, and should be used to create the initial agent and user accounts.

7 Authentication

All calls to the MindLink API must be performed with an authentication identity, provided in the form of a token in the request’s HTTP header collection. This token is obtained by making a one-time call to the MindLink Authentication Service with the provided credentials.

1. 1 Token Management

The typical workflow of an application’s token management will be as follows:

1) On start-up, obtain the applications credentials – the tuple of user credentials and agent ID.

These will typically be configured in the applications configuration file by the administrator.

2) Make a call to the Authentication Service to obtain a token by providing the applications credentials.

3) Save this token in memory.

4) In every other request used by the application, supply this token in the “Authorization” HTTP header.

5) The token will expire every hour. The application should be written to handle the expiry of the token by requesting another token from the Authentication Service, or periodically renew the token from the Authentication Service.

The Authentication service also exposes a method to return the details of a given token. This can be helpful in diagnosing and verifying token validity.

2. 2 Credentials

The credentials provided to the Authentication service will take two forms:

1) Agent and User pair.

a. This is the typical scenario used by applications.

b. The application’s agent “agent1” will be configured with “user1” in its users collection, which in turn will be configured with the domain\bot1 account – which is an Active Directory account with password “Password1”.

c. The application will be configured to authenticate with “domain\bot1” and “Password1”, and “agent1”. It will provide these three values to the Authentication service.

d. The Authentication service will issue a token that maps to the “agent1” agent. All calls made to the Collaboration service will be mapped to and carried out by the agent1 agent.

2) Super User

a. This will be used initially to configure the system.

b. Only the super user account credentials need be provided – no agent is required.

c. No calls to the Collaboration service will work with a token obtained in this way – as the token provides no mapping to an agent with which to service the request. Note that when obtaining a token via the typical Agent/User mechanism, the provided user account must map to a user configured for the given agent – otherwise an unauthorized error will be returned.

3. 3 Mechanisms

Super User and User credentials must be valid Active Directory accounts. The credentials can either be provided manually – by explicitly configuring the user name and password of the account in the configuration file of an application – or by using integrated NTLM or Kerberos authentication to use the service account credentials with which the application is running.

This mechanism is configurable in the MindLink Management Center.

8 Provisioning

Provisioning is the termed used to describe the process of configuring the MindLink API entities such that applications can communicate with the chat system. This is done by making calls to the Provisioning service, which uses typical REST resource collections to describe the various configurable entities.

1. 1 Authorization

Calls to the Provisioning service must be made with a token obtained from the Authentication service. A token will be considered valid if:

1) The token was obtained for the super user.

2) The token maps to an agent that is authorized to perform the requested operation.

This means that typically all initial set up will be performed by the super user, and then subsequent configuration will be performed using a token obtained for a special “provisioning slave” agent. In addition, it also means that special applications may be granted permission to perform provisioning operations themselves – either on behalf of other agents or on behalf of themselves. This essentially allows applications to be written using the traditional “bot” paradigm where the application itself decides which channels it is joined to.

2. 2 Resources

The Provisioning service exposes REST resource collections for the User, Agent and Throttle resources. These resource collections are examined and manipulated using standard REST verbs requests.

• Users - define the credentials used by applications and administrators to access the MindLink API.

• Agents – represent the application on the chat system. Creating an agent resource will immediately spin up an agent instance and log the agent in. Querying the “State” property of an agent will determine whether the agent is Active (logged in) or Inactive – log on failed or waiting to reconnect.

• Throttles – these can be applied to agents to limit the rate of actions that an application can perform.

The channels that an agent is joined to are configured via the Agent resource’s “Channels” subresource collection. Adding a channel – which is represented via an ID – to this collection will immediately make the agent join the channel. Querying a Channel’s “State” property will indicate whether the channel is Active (joined) or Inactive – the join failed.

As mentioned previously, each application running against the MindLink API should map to a single Agent. If that Agent resource is configured that has been given permissions to provision, then an application holding a token that maps to that agent may make calls to the Provisioning service. This means that it is possible for the application to provision its own channels – i.e. decide which channels to join and leave – or to provision channels of other agents.

In this way an application can be written in a traditional autonomous “bot” style, in which the application itself controls its own actions. We would recommend however that typically this permission is not granted to agents used by applications, and applications are written such that the channels to which they are joined is driven entirely by the actions of a central administrator.

2.1. 1 Provisioning Modes (v18.6+)

If the MindLink server is version 18.6 or later, agents can be given a ProvisioningMode instead of setting the CanProvision property. This gives admins more granular control over what agents are able to do. The possible values are as follows:

  •          1: None – The agent cannot access any functionality of the provisioning API. This is functionally equivalent to CanProvision=false.
  •          2: System – The agent has full access and can make all requests to the provisioning API. This is functionally equivalent to CanProvision=true.
  •          3: Self – The agent can access the provisioning API only for their own data. Self-provisioning agents can make requests to access and modify their own channels list and metadata, and can also search for channels. However they cannot access or modify data of other agents, users or throttles.

Note that CanProvision will still function as before and is used if the ProvisioningMode is not specified.

3. 3 Obtaining Channel IDs

Channels – chat rooms and users – are referenced by ID. The ID of a channel is typically not a well known value, since the ID of a chat room does not map or depend on its name. Therefore, for convenience, the Provisioning service provides a mechanism to search for and obtain the IDs of available channels – the Channels resource collection.

These available channels are fetched by directly searching the underlying chat system and as such fulfilling such requests to the Channels resource collection requires a connection to the underlying chat system to be available. For this reason, requests to this collection can only be serviced using a token that maps to an agent – that agent is used to perform the query of the underlying chat system.

It is suggested therefore that to configure the MindLink API for the first time, a master “provisioning slave” agent is created that can then be used to perform channel search queries. This agent would typically:

• Be given a chat-system account that has access to all available channels – i.e. it must be able to “see” the channels on the chat system for them to be returned in the search queries. In Lync terms, this means it must be have rights to view chat rooms in every category.

• Have its “CanProvision” property set to “true” (or "ProvisioningMode" set to "2"). This is because all requests made to the Provisioning service must be made with a token that maps to an agent that can provision (unless the token is for the super user).

• Have all administrator users in its Users collection. This means that all administrators will be able to have access to and obtain a token to use this agent.

4. 4 Metadata

All Agent resources have a “MetaData” sub-resource collection. This metadata can be used to store arbitrary key/value configuration that an application using that agent can understand. The purpose of this is to facilitate the “inversion of control” design principals whereby all application configuration is driven from the administration of the central MindLink API server.

Via the Collaboration service, applications can subscribe to notifications of their metadata being changed by the administrator and be coded to take action accordingly.

5. 5 Initial Set Up

The typical workflow for initial set up of the MindLink API via the provisioning service would be as follows:

1) In the MindLink Management Center, set the super user as “domain\mindlinksuperadmin”.

2) From the Authentication service, obtain a token for user “domain\mindlinksuperadmin”.

3) Using this token, make a request to create the normal admin users e.g. “admin1” with user name “domain\mindlinkadmin1”.

4) Make a request to create a provisioning slave agent e.g. “adminagent1” with user name “sip:mindlinkslave@domain.com”, and “CanProvision” to true.

5) Assign the “admin1” agent to the users collection of “adminagent1”.

6) Re-authenticate by obtaining a token using the standard admin account – “admin1” with agent “adminagent1”. This will be the standard way of authenticating to provision in future.

7) Create and configure the agents and users for your applications using the new token.

8) Obtain the Channel IDs for each agent by searching the Channels resource collection – an operation which will be mapped to and serviced by the “adminagent1” agent.

9 Collaborating

Applications themselves will be written against the Collaboration service. This service uses Channels and Messages resource collections to model the channels on the underling system. More information about writing applications against this service can be found in the developer guide.

1. 1 Authorization

Requests to the collaboration service are mapped directly to and serviced by the agent contained in the provided token. Hence, tokens used to access the collaboration service must be issued for an agent – i.e. tokens issued for the super user account will not be accepted.

Furthermore, the agent mapping to the account must be “active” – i.e. logged in to the system. Calls made with a token whose agent is not active will be failed with a Service Unavailable code. Applications must be written to deal with this error code as this will occur when the connection to the underlying chat system is dropped. Note that reconnection of the agent is automatically performed inside the MindLink API, so external application code should gracefully fail as appropriate and then retry until the agent becomes active again.

2. 2 Event Streaming

Applications perform invocation and query operations on the chat system e.g. message sending, message fetching using standard HTTP verb requests - e.g. GET/POST etc. - since this paradigm is a natural mapping. To be able to subscribe to and wait for remote events e.g. receiving messages, we must use a different mechanism.

We have chosen to solve this by using a long-polling (sometimes known as “Comet”) pattern, whereby the application should continually make HTTP GET requests to the Events resource collection. If new events are available then the request will return immediately with those events, otherwise the request will be held open until events become available. If no events become available within 30 seconds an empty collection of events is returned.

Typically this logic will be implemented in an application in the form of a loop that continually makes a request, processes each event in the returned response (which may be an empty set of events), and then makes the request again.

The types of events that are returned can be configured via the querystring – this provides a pseudosubscription mechanism.

Note that when addressing the resource using instanceIDs, requests will fail if the ID does not match the API service instance. If this should occur, steps should be taken to re-synchronize the ID to continue long-polling (see section 3.8.5).

10 Walkthrough

We will conclude by examining the example requests required from both the administration and application roles to set up the API with an agent and make a request to send a message to a channel.

10.1 Pre-requisites

We assume the following:

• The MindLink API is configured to run at https://mindlink.domain.com

• Lync is the underlying chat system.

• The MindLink API is configured with domain\mindlinksuperuser as the super user account

• Active Directory user accounts domain\mindlinkadmin1 and domain\mindlinkuser1 are configured.

• The MindLink API is configured for manual authentication. All Active Directory user accounts have “Password1” as the password.

• Lync SIP accounts have been created with SIP addresses sip:mindlinkslave@domain.com and sip:agent1@domain.com

• There is a Lync Persistent Chat Room called “TestChatRoom” with ID chat-room:f9a694eb3cae-4235-bcb6-b8aeefb83284 which is visible to sip:mindlinkslave@domain.com and accessible by sip:agent1@domain.com

10.2 High-Level Strategy

Our high level strategy will be as follows

1) Provision the agents and users

a. Use the super user to create a normal admin user and slave agent

b. Use the admin user to create an application user and an agent

c. Search for a channel using the slave agent

d. Provision the application agent with the channel

2) Send a message

a. Use the application agent to send a message to the channel

b. Verify that the message was sent to the channel

By the end of the provisioning steps the system will look as follows:


10.3 Provisioning Requests


10.3.1 Obtain a Super User Token

• Make a POST request to https://mindlink.domain.com/Authentication/V1/Tokens with the payload:
• This will return 200 OK with the token e.g.
"xPq5OitUf9NIOUI8VMN314EjEEsvmatZTqZ7LHuo0AQ0Xq1VRhZ8tL6mmGSRe_xO+YGEDBDE52SOCeJphu +cGg=="
If it does not then check the configured super user credentials in the MindLink Management Center and in Active Directory.
• This token must be provided in all subsequent requests in the “Authorization” HTTP header, prefixed with “FCF ”. For example the Authorization header in this case will be:
FCF xPq5OitUf9NIOUI8VMN314EjEEsvmatZTqZ7LHuo0AQ0Xq1VRhZ8tL6mmGSRe_xO+YGEDBDE52SOCeJphu+ cGg==
• Setting this header and then making a GET request to https://mindlink.domain.com/Authentication/V1/Tokens/xPq5OitUf9NIOUI8VMN314EjEEsv matZTqZ7LHuo0AQ0Xq1VRhZ8tL6mmGSRe_xO+YGEDBDE52SOCeJphu+cGg== will return 200 OK with the token details:
{"AgentId":"","ExpiresTimestamp":1370990873148,"Username":"domain\\mindlinksuperuse r"}


10.3.2 Create the admin user

• Making a GET request to https://mindlink.domain.com/Provisioning/V1/Users will return an empty collection as there are no configured users: []
• Make a PUT request to https://mindlink.domain.com/Provisioning/V1/Users/admin1 with the payload:
• This will return with 200 OK.
• Making a GET request to https://mindlink.domain.com/Provisioning/V1/Users will now return 200 OK with a collection containing the admin1 user:
• Similarly, whereas a GET request to https://mindlink.domain.com/Provisioning/V1/Users/admin1 would have previously returned 404 Not Found, it will now return:


10.3.3 Create the admin slave agent

• Making a GET request to https://mindlink.domain.com/Provisioning/V1/Agents will return an empty collection as there are no configured agent: []
• Make a PUT request to https://mindlink.domain.com/Provisioning/V1/Agents/slaveagent with the payload:
{"Id":"slaveagent","UserName":"sip:mindlinkslave@domain.com","Channels":[],"MetaDat a":[],"Users":[|"admin1"],"CanProvision":"true"}
• This will return with 200 OK.
• Making a GET request to https://mindlink.domain.com/Provisioning/V1/Agents will now return 200 OK with a collection containing the slaveagent agent:
[{"CanProvision":true,"Channels":[],"Id":"slaveagent","MetaData":[],"State":2,"User Name":"sip:mindlinkslave@domain.com","Users":[|"admin1"]}]
• Similarly, whereas a GET request to https://mindlink.domain.com/Provisioning/V1/Agents/slaveagent would have previously returned 404 Not Found, it will now return:
{"CanProvision":true,"Channels":[],"Id":"slaveagent","MetaData":[],"State":2,"UserN ame":"sip:mindlinkslave@domain.com","Users":[|"admin1"]}
• Note that the “State” property being “2” indicates that the agent has logged on successfully. If this value is 0 or 1 then check the agent user name.


10.3.4 Reauthenticate as the new admin account

• Make a POST request to https://mindlink.domain.com/Authentication/V1/Tokens with the payload:
• This will return 200 OK with the token e.g.
"fQaQrO2QgeDoOeQpnaALQMsYdQlSm75hAZDWs0CR6eL5OVzFx8ONEjia5gp1QMEc99aLsDVTaEa_FY+3dK ZuFQ=="
• This token must be provided in all subsequent requests in the “Authorization” HTTP header, prefixed with “FCF ”
• Setting this header and then making a GET request to https://mindlink.domain.com/Authentication/V1/Tokens/fQaQrO2QgeDoOeQpnaALQMsYd QlSm75hAZDWs0CR6eL5OVzFx8ONEjia5gp1QMEc99aLsDVTaEa_FY+3dKZuFQ== will return 200 OK with the token details:
{"AgentId":"slaveagent","ExpiresTimestamp":1370990873148,"Username":"domain\\mindli nkadmin1"}


10.3.5 Create the application user

• Make a PUT request to https://mindlink.domain.com/Provisioning/V1/Users/user1 with the payload:
• This will return with 200 OK.
• Making a GET request to https://mindlink.domain.com/Provisioning/V1/Users/user1 will now return:


10.3.6 Create the application agent

• Make a PUT request to https://mindlink.domain.com/Provisioning/V1/Agents/agent1 with the payload:
{"Id":"agent1","UserName":"sip:agent1@domain.com","Channels":[[]],"MetaData":[[]],"User s":[["user1"]],"CanProvision":"false"}
• This will return with 200 OK.
• Making a GET request to https://mindlink.domain.com/Provisioning/V1/Agents/agent1 would have previously returned 404 Not Found, it will now return:
{"CanProvision":false,"Channels":[[]],"Id":"agent1","MetaData":[[]],"State":2,"UserName ":"sip:agent1@domain.com","Users":[|"user1"]}
• Note that the “State” property being “2” indicates that the agent has logged on successfully. If this value is 0 or 1 then check the agent user name.


10.3.7 Look up the channel ID for the target chat room

• Make a GET request to https://mindlink.domain.com/Provisioning/V1/Channels?query=TestChatRoom.
• This will return with 200 OK and the list of matching channels: {"Key":"chat-room:f9a694eb-3cae-4235-bcb6-b8aeefb83284","Value":" TestChatRoom "}
• From this response we know that the ID of chat room TestChatRoom as recognized by the MindLink API is “chat-room:f9a694eb-3cae-4235-bcb6-b8aeefb83284”.


10.3.8 Provision the application agent with the target chat room channel

• Make a PUT request to https://mindlink.domain.com/Provisioning/V1/Agents/agent1/Channels/chatroom:f9a694eb-3cae-4235-bcb6-b8aeefb83284.
• This will return with 200 OK.
• Making a GET request to https://mindlink.domain.com/Provisioning/V1/Agents/agent1 will return 200 OK with:
{"CanProvision":false,"Channels"[:{"Id":"chat-room:f9a694eb-3cae-4235-bcb6b8aeefb83284","State":2},"Id":"agent1","MetaData":[],"State":2,"UserName":"sip:age nt1 at domain.com","Users":[|"user1"]}
• The channel’s “State” property being “2” indicates that the agent has successfully joined the channel. If this value is 0 or 1 then check the chat room permissions for the agent’s user name.


10.4 Collaboration Requests


10.4.1 Obtain an agent Token

• Make a POST request to https://mindlink.domain.com/Authentication/V1/Tokens with the payload: {"Username":"domain\\mindlinkuser1","Password":"Password1","AgentId":"agent1"}
• This will return 200 OK with the token e.g.
"PzE4IsnjVkmLn+XnYM8LRQvWr+1xyaGkIi58qkx5mV4yBiz4kw1QAAqtGIKY4Feqdh8FtE9WKFeDZ4lADY R2xA=="
• This token must be provided in all subsequent requests in the “Authorization” HTTP header, prefixed with “FCF ”.
• Setting this header and then making a GET request to https://mindlink.domain.com/Authentication/V1/Tokens/PzE4IsnjVkmLn+XnYM8LRQvWr+1 xyaGkIi58qkx5mV4yBiz4kw1QAAqtGIKY4Feqdh8FtE9WKFeDZ4lADYR2xA== will return 200 OK with the token details:
{"AgentId":"agent1","ExpiresTimestamp":1370990873148,"Username":"domain\\mindlinkus er1"}


10.4.2 Verify the agent channels

• For the sake of example, to verify the agent is configured correctly make a GET request to https://mindlink.domain.com/Collaboration/V1/Channels
• This will return 200 OK with the channel collection:
{"CanAcceptFiles":true,"Description":"Test Room","DisplayName":"TestChatRoom","EmailAddress":null,"Id":"chat-room:f9a694eb-3cae-4235-bcb6b8aeefb83284","IsReadOnly":false,"MaxMessageLength":500,"MaxStoryLength":4000,"Meta data":null,"Subject":"Test Room"}


10.4.3 Post a message to the channel

• Make a POST request to https://mindlink.domain.com/Collaboration/V1/Channels/chat-room:f9a694eb-3cae-4235-bcb6-b8aeefb83284/Messages with payload:
{"IsAlert":false,"Text":"Test Message"}
• This will return 200 OK with the sent message:
{"ChannelId":"chat-room:f9a694eb-3cae-4235-bcb6b8aeefb83284","Id":null,"IsAlert":false,"Origin":0,"SenderId":"agent1","Subject":nu ll,"Text":"Test Message","Timestamp":1370994481922}


10.4.4 Verify the message was sent

• Make a GET request to https:// mindlink.domain.com/Collaboration/V1/Channels/chatroom:f9a694eb-3cae-4235-bcb6-b8aeefb83284/Messages?take=10
• This will return 200 OK with the 10 most recent messages in the channel:
{|{"ChannelId":"chat-room:f9a694eb-3cae-4235-bcb6b8aeefb83284","Id":"136180","IsAlert":false,"Origin":1,"SenderId":"contact:agent1@d omain.com","Subject":null,"Text":"Test Message","Timestamp":1370994482073}

11 Sample Code Repository

Sample code can be downloaded from https://github.com/mindlink/api-samples