This article provides an overview of the SendSafely Windows Client library, which is written in C-Sharp (.NET). The walk-through below includes most common SendSafely use cases, like creating a SendSafely package, sending a single file to a recipient, assigning SMS authentication, setting package life (expiration), and downloading files.
This article also covers working with Workspace packages, Contact Groups, and Dropzone recipients. The example code will refer to the following core API classes, which can be found in the Windows Client API source code repository. Complete documentation for the Windows Client API can be found here.
- SendSafely.ClientAPI
Main class that includes all of the methods used to interface with SendSafely - SendSafely.PackageInformation
Class that is used to hold all metadata associated with a package. This object is used as the return value for several API methods and is populated with package specific properties depending on the package being manipulated. - SendSafely.ISendSafelyProgress
Callback interface that you must implement to receive progress updates as each file is being encrypted, signed and uploaded. - SendSafely.Recipient
Class that is used to hold metadata associated with a recipient. This object is used as the return value when adding a package recipient and includes the unique recipient id associated with the recipient, previous SMS phone numbers provided by the user for this recipient, a flags indicating whether this recipient requires approval, and a list of package approvers (if approval is required). - SendSafely.Exceptions
Namespace that includes numerous specific exception classes thrown by the plug-in.
Example Code
The code examples below assume that your program has been designed to accept following inputs, either from a configuration source or the user/process invoking the program:
- API Key & API Secret
- Full Path to the Local File to Send
- Recipient Email Address
- Recipient Mobile Phone Number
Initializing the API
The first step required to use the API is to initialize a new instance of the API using a specific set of credentials. These credentials (your API Key and API Secret) will be used by all operations invoked through the instance.
It is best practice to operate on the premise that each instance of the API you create be associated with a single set of credentials. If more than one set of credentials will be used, you should create a new API object instance each time you switch credentials.
//Initialize the API ClientAPI ssApi = new ClientAPI(); ssApi.InitialSetup("https://demo.sendsafely.com", "INSERT_API_KEY_HERE", " INSERT_API_SECRET_HERE "); //Verify that the API credentials are valid String userEmail = ssApi.VerifyCredentials(); Console.WriteLine("Connected to SendSafely as user " + userEmail);
Note that in the example above, the API credentials are verified using the VerifyCredentials method, which returns the email address associated with the SendSafely user associated with the API key. Calling the InitialSetup method alone does not connect to SendSafely, so calling VerifyCredentials is an optional step that can be used to verify you are using a valid API Key and API Secret.
Creating a Package
Once the API instance has been initialized with credentials, you can use the instance to issue commands to SendSafely that create, edit, or delete packages as the user that created the API key. The example below shows how to create new empty package. Note that the CreatePackage method returns a PackageInformation object that includes metadata about the new package, most notably the unique Package Id, which can be used to reference the package on subsequent API operations.
//Create a new empty package PackageInformation pkgInfo = ssApi.CreatePackage(); Console.WriteLine("Created new empty package with Package ID" + pkgInfo.PackageId);
The PackageInformation object returned by the CreatePackage operation includes two critical properties that are needed for subsequent API calls: the PackageId and client KeyCode.
- The Package ID is the primary identifier used to reference the package for all subsequent API operations that manipulate or query this package.
- The Client KeyCode is the value used to derive the portion of the package encryption key that is generated client-side by the API. This value is needed when adding new files to the package. The KeyCode is never submitted to the SendSafely server, and consequently cannot be obtained again once you load a different package or discard the instance of the API that was used to create it.
Adding Recipients
Once a package has been created, you will need to add one or more recipients. Each recipient for a given package must have a unique email address. Note that the AddRecipient method returns a Recipient object that includes properties with available metadata about the recipient. The metadata returned includes a unique RecipientID, a list of previous SMS phone numbers provided by the user for this recipient, a flag indicating whether this recipient requires approval, and a list of package approvers if approval is required.
//Add a new recipient to the package Recipient newRecipient = ssApi.AddRecipient(pkgInfo.PackageId, "user@example.com"); Console.WriteLine("Added new recipient (Id# " + newRecipient.RecipientId + ")");
After a recipient has been added, you have the option of providing their mobile phone number in order to require SMS authentication for access to package. This step is optional, and must include both a phone number and Country Code to indicate the country in which the phone number. The API includes an enum that contains each valid country code supported for SMS authentication (SendSafelyAPI.CountryCodes).
//Add an SMS number for the new recipient ssApi.AddRecipientPhonenumber(pkgInfo.PackageId, newRecipient.RecipientId, "212-555-1212", CountryCodes.CountryCode.US); Console.WriteLine("Added SMS number for Recipient Id# " + newRecipient.RecipientId + ")");
Adding Files
One of the main benefits of using the SendSafely Client API is that it alleviates the need to deal with the complex process of encrypting and uploading files to the SendSafely server. The SendSafely API automatically handles the task of generating an encryption key, encrypting the file with OpenPGP, segmenting large files for upload, and uploading to the server.
Because this step can take a comparatively larger amount of time than other API operations (which generally require a single request/response to the server) the API defines a callback interface that you must implement to monitor the progress of each file as it is being encrypted, signed and uploaded. The callback interface is extremely simple, and what it does to report feedback is left up to you as the developer. In our example below, the callback is implemented as a simple class that prints status updates to the console as they are received by the API.
//Callback class that implements the ISendSafelyProgress interface class ProgressCallback : ISendSafelyProgress { //The UpdateProgress method is a mandatory method that must be defined // by classes that implement ISendSafelyProgress. This method can do // anything you want, or nothing at all. public void UpdateProgress(string prefix, double progress) { Console.WriteLine(prefix + " " + progress + "%"); } }
Once you have defined your callback class, you can pass a new instance of the class to the EncryptAndUpload file method as shown below. Note that when you call the EncryptAndUploadFile method, you should also pass in the KeyCode that was generated by the API when the package was created. Note that the EncryptAndUploadFile method returns a new File object that includes properties with available metadata about the file.
//Add a local file to the package File addedFile = ssApi.EncryptAndUploadFile(pkgInfo.PackageId, pkgInfo.KeyCode, "c:\\myfile.txt", new ProgressCallback()); Console.WriteLine("File was added with Id# " + addedFile.FileId);
Finalizing or Deleting a Package
Once you have added at least one file and one recipient, the package can be finalized, indicating that its preparation is complete and there are no more files or recipients to be added. The FinalizePackage method is the last method that should be called, and it returns the full hyperlink that can be provided to recipients in order to access the package.
//Finalize the package so we can send the link to our recipient String packageLink = ssApi.FinalizePackage(pkgInfo.PackageId); Console.WriteLine("Package was finalized. The package can be downloaded from the following URL: " + packageLink);
Keep in mind that there is a limit of 5 incomplete packages at any time for each user. Incomplete package are packages that have at least one file or one recipient, but have not been finalized. If you wish to discard a package that has not been finalized, you can do so using the DeleteTempPackage method.
//Delete the temp package if we are going to bail and not finalize ssApi.DeleteTempPackage(pkgInfo.PackageId); Console.WriteLine("Temp package " + packageLink + " was deleted.");
Downloading Files
The API can also be used to download files that someone sent to you. Our API offers a few methods making receiving data as easy as possible. Most of the time you will receive a SendSafely link from someone. The API offers a method of extracting a Package object from the link.
String myLink = "https://www.sendsafely.com/receive/?thread=AAAA-BBBB&packageCode=ABC#keyCode=123"; PackageInformation pkg = ssApi.GetPackageInformationFromLink(myLink);
The API also offers a method to extract SendSafely links from a String of text. This is helpful if you want to list all links found in an email or a Zendesk Ticket. Use the following helper function to obtain a list of all SendSafely links found in the text:
List<String> links = ssApi.ParseLinksFromText(myEmail);
Once you have the PackageInformation object, you can download any file contained in the package.
PackageInformation pkg = ssApi.GetPackageInformationFromLink(myLink); // Download all files found in the package foreach(File file in pkg.Files) { FileInfo newFile = ssApi.DownloadFile(pkg.PackageId, file.FileId, pkg.KeyCode); Console.WriteLn("Downloaded File with name: " + newFile.Name + " Length: " + newFile.Length); }
Similar to when uploading files you can implement the ISendSafelyProgress interface to receive feedback on how the download of the file is going. To do so, simply add your progress interface as a parameter to the downloadFile function.
FileInfo newFile = ssApi.DownloadFile(pkg.PackageId, file.FileId, pkg.KeyCode, new ProgressCallback());
Workspace Packages
A Workspace is a type of package that supports file collaboration features, such as directories and subdirectories, file versioning, role-based access control, and activity logging. The example below shows the basic operations for working with Workspaces, including creating a new Workspace, assigning a unique name to the Workspace, creating a subdirectory, uploading a file to that subdirectory, adding a recipient (referred to as a collaborator in Workspace parlance), and generating the secure link required for accessing the Workspace.
// Create a new empty Workspace package. Note the isWorkspace flag is true. // Note the isWorkspace flag is true to specify the package is a Workspace package. PackageInformation pkgInfo = ssApi.CreatePackage(true); Console.WriteLine("Created new empty package with Package ID" + pkgInfo.PackageId); //Assign a unique name to the workspace sendsafely.updatePackageDescriptor(pkgInfo.PackageId, "MyExampleWorkspace"); //Create directory String rootDirectoryId = pkg.RootDirectoryId; Directory directory = ssApi.CreateDirectory(packageId, rootDirectoryId, directoryName); //Create subdirectory inside previously created parent directory String directoryId = directory.DirectoryId; Directory subDirectory = ssApi.CreateDirectory(packageId, directoryId, "ExampleSubDirectory"); //Upload a file to a directory String fileToUpload = "/tmp/myfile.txt""; File addedFile = ssApi.EncryptAndUploadFile(pkgInfo.PackageId, pkgInfo.KeyCode, fileToUpload, new ProgressCallback()); //Adding a recipient (referred to as a collaborator in Workspace parlance) ssApi.AddRecipient(pkgInfo.PackageId, "user@example.com"); //Generate the secure Link ssApi.GetPackageLink(pkgInfo.PackageId, pkgInfo.KeyCode);
Workspace Roles and Activity Log
Each created Workspace is completely isolated, and within that Workspace access is managed with a role-based access control model. When adding a new collaborator to a Workspace (i.e. refer to the call to addRecipient in the code example above), that user defaults to the Viewer role. The following code example shows updating that recipient to the Contributor role.
// Update recipient (i.e. Workspace collaborator) to Contributor role
ssApi.UpdateRecipientRole(packageId, recipient.getRecipientId(), "CONTRIBUTOR");
The following roles are supported for Workspace packages:
- VIEWER - Allows the user view the most recent version of each file and folder.
- CONTRIBUTOR - Allows the user to view, create, update, and delete files and folders.
- MANAGER - Allows the user to manage Workspace contents and Collaborators and view the Activity Log.
- OWNER - Allows all the same rights as the Manager role, however user is also the owner of the Workspace package, and subsequently can transfer ownership to another user.
The following code example shows the Owner role being assigned to a recipient. Note that SendSafely will send an email to the recipient notifying that user of the transfer of ownership. Once ownership has been successfully transferred, the current user will retain Manager rights.
// Transfer Workspace ownership from current user to target recipient
ssApi.UpdateRecipientRole(packageId, recipient.getRecipientId(), "OWNER");
The Workspaces Activity Log provides a history of activity within the current Workspace. The SendSafely Client API supports retrieving 10 Activity Log records at a time. The following code example shows how to retrieve the Activity Log for a Workspace package.
// Retrieve the eleventh Activity Log record, up to the twentieth
// The rowIndex method argument permits paging through the Activity Log ten records at a time
ssApi.GetActivityLog(pkgInfo.getPackageId(), 11);
Contact Groups
Contact Groups allow the user to manage lists of recipients. A Contact Group is added as a recipient on a package and all members of that Contact Group will have access to the package. The following example walks through the common Contact Group management operations available with the SendSafely Client API.
//Create a contact group. String contactGroupId = ssApi.CreateContactGroup("Contact Group Name"); //Add a user (by email) to the contact group. String userId = ssApi.AddUserToContactGroup(contactGroupId, "user@example.com"); //Assign a contact group of recipients to a package. ssApi.AddContactGroupToPackage(pkgInfo.getPackageId(), contactGroupId); //Remove a contact group from a package. ssApi.RemoveContactGroupFromPackage(pkgInfo.getPackageId(), contactGroupId); //Remove a user from a contact group ssApi.RemoveUserFromContactGroup(contactGroupId, userId); //Delete a contact group ssApi.DeleteContactGroup(contactGroupId);
Enterprise Contact Groups
For SendSafely enterprise customers, Contact Groups can also be defined at the organization level and made available for use by all users within the company. To create and manage an Enterprise Contact Group, the current API user must be a SendSafely Enterprise Administrator. The following code example shows the method call needed to create an Enterprise Contact Group. All subsequent management operations are the same as that for a user Contact Group.
//Create an enterprise contact group by setting isEnterpriseGroup to true
String contactGroupId = ssApi.CreateContactGroup("Enterprise Contact Group Name", true);
Dropzone Recipient Management
The SendSafely Dropzone provides file upload capabilities in a hosted or custom web form and pre-designation of a list of recipients who can access the uploaded files. For users who have Dropzone enabled, the SendSafely Client API provides several methods for managing Dropzone recipients
//Add a Dropzone Recipient ssApi.AddDropzoneRecipient("user@example.com"); //Get Dropzone Recipients List recipients = ssApi.GetDropzoneRecipients(); //Remove Dropzone Recipient ssApi.RemoveDropzoneRecipient("user@example.com");
Based on this article, you should now be able to integrate the SendSafely Windows Client API into your own application. A fully functional console application that implements the code examples shown above can be found in the Windows Client API source code project.