{"id":15779641,"url":"https://github.com/aldaviva/csxapi","last_synced_at":"2025-07-07T02:04:00.624Z","repository":{"id":184433251,"uuid":"671333858","full_name":"Aldaviva/CSxAPI","owner":"Aldaviva","description":"🎦 C# xAPI for Cisco Webex/TelePresence video conferencing room system endpoints","archived":false,"fork":false,"pushed_at":"2025-05-11T21:23:02.000Z","size":69705,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-28T21:09:43.991Z","etag":null,"topics":["api-client","cisco","codec","roomos","teleconference","telepresence","video-conferencing","webex","xapi"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/csxapi","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aldaviva.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":["https://paypal.me/aldaviva"]}},"created_at":"2023-07-27T04:54:41.000Z","updated_at":"2025-05-11T21:19:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"e481e641-0f4c-45a1-af2b-14760e1f4c62","html_url":"https://github.com/Aldaviva/CSxAPI","commit_stats":null,"previous_names":["aldaviva/csxapi"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Aldaviva/CSxAPI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aldaviva%2FCSxAPI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aldaviva%2FCSxAPI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aldaviva%2FCSxAPI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aldaviva%2FCSxAPI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aldaviva","download_url":"https://codeload.github.com/Aldaviva/CSxAPI/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aldaviva%2FCSxAPI/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262497430,"owners_count":23320300,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","cisco","codec","roomos","teleconference","telepresence","video-conferencing","webex","xapi"],"created_at":"2024-10-04T18:20:49.794Z","updated_at":"2025-07-07T02:04:00.612Z","avatar_url":"https://github.com/Aldaviva.png","language":"C#","readme":"﻿CSxAPI\n===\n\n[![NuGet](https://img.shields.io/nuget/v/CSxAPI?logo=nuget)](https://www.nuget.org/packages/csxapi) [![target version](https://img.shields.io/badge/target%20version-RoomOS%2011.27.0-%3B?logo=cisco\u0026logoColor=white\u0026color=informational)](https://www.cisco.com/c/en/us/support/collaboration-endpoints/spark-room-kit-series/products-command-reference-list.html)\n\nCSxAPI is a strongly-typed API client library for **Cisco xAPI**. It is similar to the official [jsxapi](https://www.npmjs.com/package/jsxapi) implementation, but for .NET instead of JavaScript. xAPI is an API exposed by [Cisco video conferencing devices](https://www.cisco.com/c/en/us/products/collaboration-endpoints/collaboration-room-endpoints/index.html), also known as Collaboration Endpoints, Webex Rooms, Cisco devices, room systems, TelePresence, and codecs.\n\nThis library can send and receive xCommands, xConfigurations, xStatuses, and xEvents over a WebSocket connection, which is available in Cisco software versions ≥ CE 9.7, and is enabled by default in versions ≥ RoomOS 10.8.\n\n\u003c!-- MarkdownTOC autolink=\"true\" bracket=\"round\" autoanchor=\"false\" levels=\"1,2,3\" bullets=\"1.,-\" --\u003e\n\n1. [Requirements](#requirements)\n1. [Installation](#installation)\n1. [API documentation](#api-documentation)\n1. [Connection](#connection)\n1. [Operations](#operations)\n    - [Commands](#commands)\n    - [Configurations](#configurations)\n    - [Statuses](#statuses)\n    - [Events](#events)\n1. [Error handling](#error-handling)\n1. [Testing](#testing)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n![Room Kit](https://raw.githubusercontent.com/Aldaviva/CSxAPI/master/.github/images/readme-header.jpg)\n\n## Requirements\n- [.NET 6 or later](https://dotnet.microsoft.com/en-us/download/dotnet)\n- [Cisco endpoint](https://www.cisco.com/c/en/us/products/collaboration-endpoints/collaboration-room-endpoints/index.html)\n    - *Targeted endpoint software version:* see the \"target version\" badge at the top of this document\n        - Each CSxAPI library release targets exactly one endpoint software version, ideally the latest on-premises version\n        - Both earlier and later software versions should also work, as long as the API didn't introduce any breaking changes from the target version\n        - This library makes no additional attempt at backwards compatibility other than that afforded by xAPI, which is very backwards compatible on its own\n    - *Minimum endpoint software version:* CE 9.7 (April 2019) or RoomOS 10.3 (June 2021)\n    - *Hardware:* Room, Board, Desk, SX, DX, and MX series are compatible\n        - Tested on a [Room Kit](https://www.cisco.com/c/en/us/products/collateral/collaboration-endpoints/spark-room-kit-series/datasheet-c78-738729.html) and a [Room Kit Plus PTZ 4K](https://www.cisco.com/c/en/us/products/collateral/collaboration-endpoints/webex-room-series/webex-room-kit-ptz-ds.html)\n        - xAPI over WebSocket does not exist on C, CTS, E, EX, IX, MXP, or T series endpoints, therefore they are not compatible\n    - *Configuration:* WebSocket protocol must be enabled\n        - Enabled by default in endpoint software versions ≥ RoomOS 10.8\n        - Enable by running `xConfiguration NetworkServices Websocket: FollowHTTPService` through SSH, Telnet, or an RS-232 serial connection (XACLI); the web admin site; or the XML HTTP API (TXAS)\n        - `/Configuration/NetworkServices/HTTP/Mode` must not be `Off`\n    - *Addressing:* you must know the endpoint's IP address, FQDN, or other hostname\n    - *Authentication:* you need the username and password of an active user that can log in to the endpoint\n        - If the endpoint is registered to [Webex](https://admin.webex.com/devices/search) and has no local users, you must create a new local user through Local Device Controls\n    - *Network:* open route from your client to TCP port 443 on the endpoint without WebSocket blocking\n\n## Installation\nThe [**`CSxAPI`**](https://www.nuget.org/packages/csxapi) package is available on NuGet Gallery.\n\n```ps1\ndotnet add package CSxAPI\n```\n\n## API documentation\nFor xAPI documentation, refer to the [API Reference Guide PDF](https://www.cisco.com/c/en/us/support/collaboration-endpoints/spark-room-kit-series/products-command-reference-list.html) or [xAPI documentation website](https://roomos.cisco.com/xapi) for the endpoint software version that this CSxAPI release targets.\n\n## Connection\n\nConstruct a new `CSxAPIClient` instance for each Cisco endpoint you want to connect to.\n\n```cs\nusing CSxAPI;\n\nawait using XAPI xAPI = new CSxAPIClient(hostname: \"192.168.1.100\", username: \"admin\", password: \"password123!\");\n\nawait xAPI.Connect();\n```\n\nTo disconnect, `CSxAPIClient` instances must be disposed with `await using`, `using`, or `.Dispose()`.\n\n#### Options\n\nYou don't have to pass any of these options, but they're here if you need them.\n\n```cs\nnew CSxAPIClient(hostname, username, password) {\n    AllowSelfSignedTls = false,\n    AutoReconnect = true,\n    ConsoleTracing = false\n};\n```\n\n- **`AllowSelfSignedTls`:** set to `true` if connections to WebSocket servers with self-signed or invalid TLS certificates should be allowed, or `false` (default) to require valid certificates that chain to trusted CAs.\n    - If you want a valid TLS certificate for your Cisco endpoint, you may consider using [Let's Encrypt](https://letsencrypt.org) with [CertifyTheWeb](https://certifytheweb.com) and [Aldaviva/CiscoEndpointCertificateDeployer](https://github.com/Aldaviva/CiscoEndpointCertificateDeployer).\n- **`AutoReconnect`:** set to `false` to disable [automatic reconnections](#reconnections) when the WebSocket is lost\n- **`ConsoleTracing`:** set to `true` to print all JSON-RPC requests and responses sent and received over the WebSocket connection to the console.\n\n## Operations\n\n### Commands\n\nYou can call `xCommand` methods, passing arguments and receiving a dictionary response.\n\n```cs\nIDictionary\u003cstring, object\u003e result = await xapi.Command.Dial(number: \"10990@bjn.vc\");\nConsole.WriteLine($\"Dialed call {result[\"CallId\"]} (conference {result[\"ConferenceId\"]})\");\n```\n\n### Configurations\n\nYou can read, write, and listen for changes to the value of `xConfiguration` options.\n\n#### Get\n```cs\nstring name = await xapi.Configuration.SystemUnit.Name();\n```\n\n#### Set\n```cs\nawait xapi.Configuration.SystemUnit.Name(\"Whisper Blade\");\n```\n\n#### Notify\n```cs\nxapi.Configuration.SystemUnit.NameChanged += newName =\u003e Console.WriteLine($\"System name changed to {newName}\");\n```\n\n### Statuses\n\nYou can read the current value of `xStatus` states and get notified when they change.\n\n#### Get\n```cs\nTimeSpan uptime = TimeSpan.FromSeconds(await xapi.Status.SystemUnit.Uptime());\nConsole.WriteLine($\"Endpoint has been up for {uptime.Days:N0} day(s), {uptime.Hours:N0} hour(s), {uptime.Minutes:N0} minute(s), and {uptime.Seconds:N0} second(s).\");\n```\n\n#### Notify\n```cs\nxapi.Status.Call.N.StatusChanged += callStatus =\u003e {\n    if (callStatus == StatusCallNStatus.Connected) {\n        Console.WriteLine(\"Call connected\");\n    }\n};\n```\n\n### Events\n\nIn addition to [changes to Configuration](#notify) and [Status](#notify-1) values, you can also listen for an `xEvent` being emitted.\n\n```cs\nxapi.Event.UserInterface.Message.TextInput.Response += response =\u003e {\n    if (response.FeedbackId == \"my expected feedback ID\") {\n        Console.WriteLine($\"User entered {response.Text} into the TextInput dialog\");\n    }\n};\n```\n\n## Error handling\n\nAll exceptions thrown by this library inherit from the `XapiException` superclass. Exceptions that are the fault of the client (like illegal arguments) inherit from the `ClientException` subclass. Exceptions that are caused by network issues (like timeouts) inherit from the `NetworkException` subclass.\n\n#### Disconnections\nThe `CSxAPIClient` class exposes the `bool IsConnected` property, which is `true` when the WebSocket is connected and `false` otherwise.\n\nTo receive notifications when it is disconnected, subscribe to the `IsConnectedChanged` event. Its `isConnected` argument will be `false` if the endpoint just disconnected, or `true` if it just [reconnected](#reconnections). The `disconnectionDetails` will contain the underlying reason behind the disconnection if the endpoint just disconnected, otherwise it will be `null` if the endpoint just reconnected. This event is fired when the first call to `Connect()` succeeds after constructing the `CSxAPIClient` instance, but not when the instance is disposed.\n\nIf you send a request when the client is disconnected from the WebSocket server and [auto-reconnecting](#reconnections) is disabled, it will throw a `DisconnectedException` instead of retrying the request.\n\n#### Reconnections\nThe WebSocket connection between this library and the endpoint can disconnect, for example, if an ethernet cable is unplugged, or if the endpoint reboots. When this happens, CSxAPI will try to automatically reconnect.\n\nIf it succeeds, it will fire the `IsConnectedChanged` event with `isConnected` set to `true`, calls to xCommands, xConfigurations, and xStatuses will succeed again, and any xFeedback events to which you previously subscribed will be able to be received again. Any commands that were sent while the endpoint was reconnecting will automatically wait for the connection is reestablished, retry, and return the new result to the original caller.\n\nTo disable automatic reconnections, set the `AutoReconnect` property to `false` on the `CSxAPIClient`. In this case, any commands that are sent while the endpoint is disconnected will throw a `DisconnectedException` instead of being retried.\n\n#### Not authenticated\nIf you connect with the wrong username or password, `Connect()` will throw an `AuthenticationException`.\n\nIt will also throw this same exception if you supply a hostname for a different server, because the response HTTP status code will not be 101 (`Switching Protocols`). Authentication failures to Cisco endpoint WebSocket server return 403 `Forbidden`, but any old HTTP server could also return 403 (or 401, or 404, or any number of other status codes) if you set the hostname wrong. The question of whether that hostname corresponds to a Cisco endpoint for which you're not authorized is ultimately unanswerable and unimportant.\n\n#### Command not found\nIf you try to call an xCommand, xConfiguration, or xStatus on an endpoint that does not support it, the method call will asynchronously throw a `CommandNotFoundException`.\n\nFor example, `xCommand Cameras Background Clear` only applies to Desk series endpoints. If you try to call it on a different endpoint, such as a Room Kit, it will throw that exception.\n\n#### Illegal arguments\nIf you try to call an xCommand or xConfiguration on an endpoint and pass an argument that is invalid, the method will asynchronously throw an `IllegalArgumentException`.\n\nFor example, `xCommand Dial` requires a `Number` argument. If you pass the empty string, instead of a valid dial string like a SIP URI, it will throw that exception.\n\n#### Network errors\nAll other exceptions caused by network issues are subclasses of `NetworkException`:\n- `ConnectionRefusedException`\n- `DisconnectedException`\n- `InvalidCertificateException`\n- `NoRouteToHostException`\n- `TimeOutException`\n- `UnknownHostException`\n\n## Testing\nIf you want to automate testing of code that depends on CSxAPI, you can easily mock out CSxAPI because it is based on interfaces like `XAPI`.\n\nFor example, using the best-in-class .NET testing libraries [FakeItEasy](https://fakeiteasy.github.io/docs/) for mocking and [Fluent Assertions](https://fluentassertions.com/introduction) for assertions, it's simple to verify this [sample code under test](https://github.com/Aldaviva/CSxAPI/blob/master/Tests/SampleUnitTest.cs) that dials and hangs up a call.\n\n```cs\nusing CSxAPI;\nusing FakeItEasy;\nusing FluentAssertions;\nusing Xunit;\n\npublic class SampleUnitTest {\n\n    private readonly XAPI xapi = A.Fake\u003cXAPI\u003e(); // mocked CSxAPIClient\n\n    [Fact]\n    public async Task DialAndHangUp() {\n        // Arrange\n        A.CallTo(() =\u003e xapi.Command.Dial(A\u003cstring\u003e._, null, null, null, null, null, null, null))\n            .Returns(new Dictionary\u003cstring, object\u003e { [\"CallId\"] = 3, [\"ConferenceId\"] = 2 });\n\n        // Act\n        IDictionary\u003cstring, object\u003e actual = await xapi.Command.Dial(\"10990@bjn.vc\");\n        await xapi.Command.Call.Disconnect((int?) actual[\"CallId\"]);\n\n        // Assert\n        actual[\"CallId\"].Should().Be(3);\n        actual[\"ConferenceId\"].Should().Be(2);\n\n        A.CallTo(() =\u003e xapi.Command.Dial(\"10990@bjn.vc\", null, null, null, null, null, null, null))\n            .MustHaveHappened();\n        A.CallTo(() =\u003e xapi.Command.Call.Disconnect(3)).MustHaveHappened();\n    }\n\n}\n```\n","funding_links":["https://paypal.me/aldaviva"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faldaviva%2Fcsxapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faldaviva%2Fcsxapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faldaviva%2Fcsxapi/lists"}