Skip to content

[Question] Unable to create an envelope using DocuSign, API PARTNER_AUTHENTICATION_FAILED #191

Open
@ebram96

Description

@ebram96

I'm trying to send an envelope created from a template in my account. But, I'm always getting the response:

HTTP Unauthorized 401
{"errorCode":"PARTNER_AUTHENTICATION_FAILED","message":"The specified Integrator Key was not found or is disabled. An Integrator key was not specified."}

Here is my code:

from docusign_esign import TemplateRole, EnvelopesApi, RecipientViewRequest, EnvelopeDefinition, ApiClient


def create_api_client(base_path, access_token):
    """Create api client and construct API headers"""
    api_client = ApiClient()
    api_client.host = base_path
    api_client.set_default_header(header_name="Authorization", header_value=f"Bearer {access_token}")

    return api_client


class Eg001Controller:
    @staticmethod
    def get_args():
        """Get request and session arguments"""
        # More data validation would be a good idea here
        # Strip anything other than characters listed
        # 1. Parse request arguments
        signer_email = "[email protected]"
        signer_name = "Some Random Guy"
        envelope_args = {
            "signer_email": signer_email,
            "signer_name": signer_name,
            "signer_client_id": "SOME_UNIQUE_VALUE",
            "ds_return_url": "http://localhost:5000/ds/callback",
        }
        args = {
            "account_id": {"API_CLIENT_ID"},  # My "API Account ID"
            "base_path": "demo.docusign.net/restapi",
            "access_token": "{ACCESS_TOKEN_GENERATED_BY_THE_EXAMPLE_CODE_LAUNCHER}",
            "envelope_args": envelope_args
        }
        return args

    @classmethod
    def worker(cls, args):
        """
        1. Create the envelope request object
        2. Send the envelope
        3. Create the Recipient View request object
        4. Obtain the recipient_view_url for the embedded signing
        """
        envelope_args = args["envelope_args"]
        # 1. Create the envelope request object
        envelope_definition = cls.make_envelope(envelope_args)

        # 2. call Envelopes::create API method
        # Exceptions will be caught by the calling function
        print("creating client..")
        api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])

        print("creating envelope..")
        envelope_api = EnvelopesApi(api_client)
        # It fails in the next line!
        results = envelope_api.create_envelope(account_id=args["account_id"], envelope_definition=envelope_definition)

        envelope_id = results.envelope_id
        print(f"Created envelope ID: {envelope_id}")

        # 3. Create the Recipient View request object
        recipient_view_request = RecipientViewRequest(
            authentication_method="None",
            client_user_id=envelope_args["signer_client_id"],
            recipient_id="1",
            return_url=envelope_args["ds_return_url"],
            user_name=envelope_args["signer_name"],
            email=envelope_args["signer_email"]
        )
        # 4. Obtain the recipient_view_url for the embedded signing
        # Exceptions will be caught by the calling function
        results = envelope_api.create_recipient_view(
            account_id=args["account_id"],
            envelope_id=envelope_id,
            recipient_view_request=recipient_view_request
        )

        return {"envelope_id": envelope_id, "redirect_url": results.url}

    @classmethod
    def make_envelope(cls, args):
        """
        Creates envelope
        args -- parameters for the envelope:
        signer_email, signer_name, signer_client_id
        returns an envelope definition
        """
        print("creating envelope definition..")
        # Create the envelope definition
        envelope_definition = EnvelopeDefinition(
            status="sent",  # requests that the envelope be created and sent.
            template_id="{TEMPLATE_ID}"
        )
        # Create template role elements to connect the signer and cc recipients
        # to the template
        signer = TemplateRole(
            email="[email protected]",
            name="Some Random Guy",
            role_name='Signer',
            client_user_id="SOME_UNIQUE_VALUE"
        )

        # Add the TemplateRole objects to the envelope object
        envelope_definition.template_roles = [signer]
        return envelope_definition


Eg001Controller.worker(Eg001Controller.get_args())

Most of the code is duplicated from this example.

Notes:

  • I thought there might be a problem in generating the access token, so, I used the same token generated when I run their code launcher. There shouldn't be any problem with the token.
  • I also get the same response if I generate the token manually with this code: (I'm using JWT auth)
    def jwt_auth():
        """JSON Web Token authorization"""
        api_client = ApiClient()
        api_client.set_base_path(BASE_PATH)
    
        # try:
        ds_app = api_client.request_jwt_user_token(
            client_id=INTEGRATION_KEY,
            user_id=USER_ID,
            oauth_host_name=AUTH_SERVER,
            private_key_bytes=PRIVATE_KEY.encode("ascii").decode("utf-8"),
            expires_in=3600,  # Not configurable/extensible.
            scopes=SCOPES
        )
    
        return ds_app
  • Their code launcher is able to complete embedded signing successfully with my account!
  • When I add X-DocuSign-Authentication header that contains my account username & password, it works. But, certainly I want to be able to use just the token, not my login credentials!
  • Why adding X-DocuSign-Authentication makes it work ??

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions