Skip to content

Authorization

Every API request carries an access token in the Authorization header:

Authorization: Bearer {access_token}

Credentials

Contact us to get a client ID and client secret. Your client is given the scopes it needs when it is set up. Keep the secret out of source repositories and anything that runs on your users' devices.

Scopes

Scope Allows
api/signatures The Signing API: signing documents in your own flow.
portal/read Reading signing processes and webhook subscriptions in the Portal API.
portal/write Creating and changing signing processes and webhook subscriptions.

Each scope covers only what it says: portal/write doesn't include reading. An app that creates signing processes and also reads their status or downloads their documents needs both portal/read and portal/write.

Getting a token

POST /api/v1/auth/token, with a form-encoded body (application/x-www-form-urlencoded):

Field Description
client_id Your client ID.
client_secret Your client secret.
scope The scopes you need, separated by spaces.
import requests

API = "https://api.esigna.is/api/v1"

def get_token(client_id: str, client_secret: str) -> dict:
    r = requests.post(f"{API}/auth/token", data={
        "client_id": client_id,
        "client_secret": client_secret,
        "scope": "portal/read portal/write",
    })
    r.raise_for_status()
    return r.json()
1
2
3
4
5
curl https://api.esigna.is/api/v1/auth/token \
  --request POST \
  --data-urlencode "client_id=$CLIENT_ID" \
  --data-urlencode "client_secret=$CLIENT_SECRET" \
  --data-urlencode 'scope=portal/read portal/write'

Response

{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600
}

expires_in is how many seconds the token is valid for. Reuse the token until shortly before then, and get a new one when it runs out; don't request a token for every call.

Errors

Status When
400 from /auth/token The credentials or scopes were refused. The body says why, for example {"error": "invalid_client"}.
401 Unauthorized The token is missing, expired or not valid, or your client is not set up for this API yet.
403 Forbidden The token is valid but doesn't have the scope the endpoint needs.