2

Okay I have limited understanding of working with API's

Im trying to get to grips with Adobe Sign API and hit a dead end, on there test page i have enterd this and it works

enter image description here

But i have no idea on how then do that in C#

I have tried the following, but know its missing the OAuth stuff and I'm just not sure what to try next. by the way foo.GetAgreementCreationInfo() just gets the string that is in the screen shot, I just moved it out cus it was big and ugly

var foo = new Models();
var client = new RestClient("https://api.na1.echosign.com/api/rest/v5");
// client.Authenticator = new HttpBasicAuthenticator(username, password);
var request = new RestRequest("agreements/{AgreementCreationInfo}", Method.POST);
request.AddParameter("name", "value"); // adds to POST or URL querystring based on Method
request.AddUrlSegment("AgreementCreationInfo",                     foo.GetAgreementCreationInfo()); // replaces matching token in request.Resource
IRestResponse response = client.Execute(request);
var content = response.Content; // raw content as string
Ashley Kilgour
  • 881
  • 1
  • 10
  • 25

2 Answers2

5

You are misinterpreting the API documentation. The Access-Token parameter needed in your API is clearly an HTTP header, while the AgreementCreationInfo is simply the request body in JSON format. There is no URI segment, so rewrite your code as follows:

var foo = new Models();
//populate foo
var client = new RestClient("https://api.na1.echosign.com/api/rest/v5");
var request = new RestRequest("agreements", Method.POST);
request.AddHeader("Access-Token", "access_token_here!");
// request.AddHeader("x-api-user", "userid:jondoe"); //if you want to add the second header
request.AddParameter("application/json", foo.GetAgreementCreationInfo(), ParameterType.RequestBody);

IRestResponse response = client.Execute(request);
var content = response.Content;

Please also be aware that in RESTSharp you do not need to manually serialize your body into JSON at all. If you create a strongly typed object (or just an anonymous object could be enough) that has the same structure of your final JSON, RESTSharp will serialize it for you.

For a better approach I strongly suggest you to replace this line:

request.AddParameter("application/json", foo.GetAgreementCreationInfo(), ParameterType.RequestBody);

With those:

request.RequestFormat = DataFormat.Json;
request.AddBody(foo);

Assuming your foo object is of type Models and has the following structure along with its properties:

public class Models
{
    public DocumentCreationInfo documentCreationInfo { get; set; }
}

public class DocumentCreationInfo
{
    public List<FileInfo> fileInfos { get; set; }
    public string name { get; set; }
    public List<RecipientSetInfo> recipientSetInfos { get; set; }
    public string signatureType { get; set; }
    public string signatureFlow { get; set; }
}

public class FileInfo
{
    public string transientDocumentId { get; set; }
}

public class RecipientSetInfo
{
    public List<RecipientSetMemberInfo> recipientSetMemberInfos { get; set; }
    public string recipientSetRole { get; set; }
}

public class RecipientSetMemberInfo
{
    public string email { get; set; }
    public string fax { get; set; }
}
Federico Dipuma
  • 15,660
  • 3
  • 39
  • 52
  • Cheers for that, It works fine. I knew I was wrong just couldn't get there. I was going to change to the object passed in, but I had a big JSON string and wasnt going to change it to an object till it got the most basic way working. I create the classes using Edit>Paste Special> Json to Class – Ashley Kilgour May 13 '16 at 09:34
  • Yes, that's the right thing to do. I'm glad this was helpful. – Federico Dipuma May 13 '16 at 11:46
  • 1
    How do I obtain Access-Token? Haven't they disabled it in favor of Oath? Do all users need to have Adobe account? – Toolkit Aug 12 '16 at 10:43
  • Under your API settings in your account. It's called an Integration Key. Create an Integration Key and this key will be used when passing as the value for the token [link]https://secure.na2.echosign.com/public/docs/restapi/v6 and then you can use `request.AddHeader("Authorization", "Bearer [YourIntegrationKey]");` @Toolkit – moto_geek Feb 25 '19 at 04:02
  • 1
    Under your API settings in your account. It's called an Integration Key. Create an Integration Key and this key will be used when passing as the value for the token [https://secure.na2.echosign.com/public/docs/restapi/v6] and then you can use `request.AddHeader("Authorization", "Bearer [YourIntegrationKey]");` You will be able to achieve a seamless integration so a user of your system does not need an Adobe account. But keep in mind, it will send on behalf of the account owner and participant will utilize email address for the workflow. @Toolkit – moto_geek Feb 25 '19 at 04:07
  • I dont think Integration Key works anymore. I can't find it anywhere in the UI. All they allow is OAuth 2 w/ Authorization Grant Flow as far as i can tell. – Stevers Jan 07 '21 at 19:56
2

Link to AdobeSign Repository:

ADOBE SIGN SDK C# SHARP API Ver. 6

Adobe Sign API integrators - this is kind of hidden away in AdobeSigns GIT repositories. The link to all the generated SWAGGER classes (models/methods) for C# and REST client integrated C# project in a GIT project you can compile and use right inside your project as a project reference or compiled DLL. This project has been updated to use version 6 of the API. This was a huge time saver for me. I have provided a quick example below on how to use it. I hope this helps others save time as well.

Note you might have to switch out BasePath in the configuration.cs so you can retrieve the initial Adobe URI "BaseURI" call if you get 404 error.

Change BasePath = "http://localhost/api/rest/v6";

To:

BasePath = "https://api.echosign.com/api/rest/v6";

//include namespaces: 
using IO.Swagger.Api;
using IO.Swagger.model.agreements;
using IO.Swagger.model.baseUris;
using IO.Swagger.model.transientDocuments;
using System.IO;

Then this quick minimal demonstrates BaseUri, Upload PDF a.k.a. Transient Document, then Create Agreement (Example 1 Basic Signer Minimal Options)

        string transientDocumentId = "";
        string adobesignDocKey = "";
        string baseURI = "";
        var apiInstanceBase = new BaseUrisApi();
        var authorization = "Bearer " + apiKey;   //Example as Integration Key, see adobesign docs For OAuth.

        try
        {
            //___________________GET BASEURI ADOBE SIGN_________________________

            BaseUriInfo resultBase = apiInstanceBase.GetBaseUris(authorization);
            baseURI = resultBase.ApiAccessPoint; //return base uri

            //___________________UPLOAD YOUR PDF THEN REF ADOBE SIGN_________________________

            var apiInstanceFileUpload = new TransientDocumentsApi(baseURI + "api/rest/v6/");
            TransientDocumentResponse resultTransientID = apiInstanceFileUpload.CreateTransientDocument(authorization, File.OpenRead([ENTER YOUR LOCAL FILE PATH]), null, null, _filename, null);

            if (!String.IsNullOrEmpty(resultTransientID.TransientDocumentId))
            {
                transientDocumentId = resultTransientID.TransientDocumentId; //returns the transient doc id to use below as reference                    
            }

            var apiInstance = new AgreementsApi(baseURI + "api/rest/v6/");

            //___________________CREATE ADOBE SIGN_________________________

            var agreementId = "";  // string | The agreement identifier, as returned by the agreement creation API or retrieved from the API to fetch agreements.

            var agreementInfo = new AgreementCreationInfo();                

            //transientDocument, libraryDocument or a URL (note the full namespace/conflicts with System.IO
            List<IO.Swagger.model.agreements.FileInfo> useFile = new List<IO.Swagger.model.agreements.FileInfo>();
            useFile.Add(new IO.Swagger.model.agreements.FileInfo { TransientDocumentId = transientDocumentId });
            agreementInfo.FileInfos = useFile;

            //Add Email To Send To:
            List<ParticipantSetMemberInfo> partSigners = new List<ParticipantSetMemberInfo>();
            partSigners.Add( new ParticipantSetMemberInfo { Email = "[ENTER VALID EMAIL SIGNER]", SecurityOption=null });

            //Add Signer To Participant
            List<ParticipantSetInfo> partSetInfo = new List<ParticipantSetInfo>();
            partSetInfo.Add(new ParticipantSetInfo { Name = "signer1", MemberInfos = partSigners, Role = ParticipantSetInfo.RoleEnum.SIGNER, Order=1, Label="" });
            agreementInfo.ParticipantSetsInfo = partSetInfo;

            agreementInfo.SignatureType = AgreementCreationInfo.SignatureTypeEnum.ESIGN;
            agreementInfo.Name = "Example Esign For API";

            agreementInfo.Message = "Some sample Message To Use Signing";

            agreementInfo.State = AgreementCreationInfo.StateEnum.INPROCESS;

            AgreementCreationResponse result = apiInstance.CreateAgreement(authorization, agreementInfo, null, null);
            adobesignDocKey = result.Id; //returns the document Id to reference later to get status/info on GET                
        }
        catch (Exception ex) 
        {
            //Capture and write errors to debug or display to user 
            System.Diagnostics.Debug.Write(ex.Message.ToString());
        }
moto_geek
  • 370
  • 4
  • 11
  • Is this still working for you? No matter what endpoint i try to invoke i get a 404. I can verify my access token works properly using Postman, but this C# project is frustratingly painful to work with. – Stevers Jan 07 '21 at 19:54
  • The method I use is passing the token as "Bearer " as string.. and then I ended up tweaking the Uri somewhere in the Git Project as mentioned above. I had similar problem of the GIT project finding the Uri. a.k.a web address of API end point. sorry can't reference code line, but I do recall finding the problem by doing a Run/Debug to find where the Uri is assigned. I've been using the above GIT project for the last 2 years successfully with no modifications yet. – moto_geek Mar 22 '21 at 16:26