Skip to main content

Manual QI Sign

Attention!

QI Tech webhooks should not be mapped strictly. Additional fields may be included in the webhook payloads returned by our APIs.

Introduction

Welcome to the QiTech Signatures API! This API provides access to the electronic document signature service.

Problems?

If you encounter any issues, please contact our support team (suporte@qitech.com.br), and we will respond as quickly as possible.

Environments

We provide two environments for our clients. The base API URLs are:

  • Production - https://api.sign.qitech.com.br/
  • Sandbox - https://api.sandbox.sign.qitech.com.br/

HTTPS Only

For security reasons, all communication with QI Tech APIs must be conducted via HTTPS. To prevent HTTP calls—whether due to oversight or other reasons—this server only provides port 443 with TLS 1.2 communication. Calls made using other protocols will be automatically denied.

Authentication

To authenticate a request, use the following code:

# In the shell, you only need to add the appropriate header to each request
curl "api_endpoint_here"
-H "Authorization: EXAMPLE_API_KEY"

Replace the API key 'EXAMPLE_API_KEY' with your key acquired from our support.

We use an API Key to allow access to our API. It has likely already been sent to you via email. If you haven't received your key yet, send an email to suporte@qitech.com.br.

Our API expects to receive the API Key in all requests to our server in a header like the one below:

Authorization: EXAMPLE_API_KEY

Envelopes are the objects containing documents to be electronically signed. They are created from one or more files and can be sent for signature via email, SMS, or WhatsApp. To create an envelope, you must send a file or a set of files to the API. The envelope will be created, and you will receive a unique identifier for it.

Creating an Envelope

To create an Envelope, make a POST call to the /sign/envelope endpoint with the signer(s) data..

curl -X POST \
https://api.sign.qitech.com.br/sign/envelope \
-H 'Content-Type: application/json' \
-H "Authorization: EXAMPLE_API_KEY" \
-d '{
"id": "814e7ed3-4080-4cae-a853-8e12812817ea",
"subject": "CCB QiTech",
"expiration_date": "2023-09-20",
"signers": [
{
"id": "1",
"name": "John Sample",
"email": "johnsample@test.com",
"birthdate": "1992-09-15",
"document_number": "111.111.111-11",
"phone": {
"international_dial_code": "55",
"area_code": "11",
"number": "988878722"
},
"document_submission_method": "email",
"authentication_submission_method": "sms"
}
]
}'

Envelope Object Definition

All information exchanges for an envelope use the following definition for this object. In some cases, to facilitate implementation and reduce data flow between parties, some information may be omitted.

NameTypeDescription
idstringUnique identifier for the envelope.
It is essential that this number is unique
subjectstringEnvelope title. Appears in the email subject.
expiration_datestringEnvelope expiration date in YYYY-MM-DD format.
signerslistList of Signer-type objects describing the envelope's signers.

Signer Object Definition

NameTypeDescription
idstringSigner transaction identifier.
It is essential that this number is unique per envelope
emailstringSigner's email address.
namestringSigner's full name.
birthdatestringSigner's birthdate in YYYY-MM-DD format.
document_numberstringSigner's document number.
phoneobjectObject describing the signer's phone..
phone.international_dial_codestringCountry code for the signer's phone.
phone.area_codestringArea code for the signer's phone.
phone.numberstringSigner's phone number.
document_submission_methodenumMethod for sending documents for signature.
Available methods: _email, sms e whatsapp _
authentication_submission_methodenumMethod for sending the authentication token for signature.
Available methods: _email, sms e whatsapp _
  • The email and phone fields can be sent together or separately, but at least one must be provided.
  • All fields are mandatory.

Envelope Creation Response

After successful envelope creation, the response will be a JSON containing the envelope's id and status, as shown in the example:

Example response

{
"id": "814e7ed3-4080-4cae-a853-8e12812817ea",
"status": "created"
}

Adding Identification Documents to the Signer

To add identification documents to a signer, make a POST call to the /sign/envelope/\{envelope_id\}/signer/\{signer_id\}/personal_document endpoint for each document to be added. The file must be sent in the request body following this format:

{
"document_b64": "Q5YACgAAAABDlgAbAAAAAEOWAC0AAAAAQ5YAPwAAAABDlgdN...",
"template": "cnh_front",
"file_type": "jpeg"
}

Available Templates

For each type of identification document, the corresponding template must be informed. The available templates are:

TemplateDescription
cnh_frontBrazilian National Driver's License (CNH) front (photo side).
cnh_backBrazilian National Driver's License (CNH) back (signature side).
rg_frontBrazilian ID Card (RG) front (photo side).
rg_backBrazilian ID Card (RG) back (data side).

Submission Attribute Description

AttributeDescription
document_b64Base64 encoded identification document.
templateDeclares the template to be applied for image analysis.
file_typeIdentifies the format of the sent file, jpeg. If not sent, jpeg is assumed.
  • The maximum size for the identification document is 10 MB
  • All fields are mandatory except for file_type.

Identification Document Addition Response

After successfully adding identification documents, the response will be a JSON containing the created_at timestamp, as shown in the example:

Example response

{
"created_at": "2023-01-01T00:00:00.000Z"
}

Identification Document Collection

If an identification document is not sent for the signer, it will be requested for collection at the time of signature.

Adding Documents to the Envelope

To add documents for signature to an envelope, make a POST call to the /sign/envelope/\{envelope_id\}/document endpoint for each document to be added. The file must be sent in the request body following this format:

{
"id": "3dfc5526-ee47-4b63-ad97-ddaf5b1c9110",
"document_b64": "Q5YACgAAAABDlgAbAAAAAEOWAC0AAAAAQ5YAPwAAAABDlgdN...",
"name": "Laudo de vistoria de entrada",
"document_type": "pdf"
}
  • The maximum document size is 10 MB

Document Object Definition

NameTypeDescription
idstringDocument identifier.
It is essential that this number is unique within the envelope
Optional CIf not provided, we will generate a 36-character UUID4 standard GUID.
document_b64stringDocumento codificado em base64.
NamestringDocument name.
document_typeenumDocument type.
Available type: pdf

Document Addition Response

After successfully adding documents to the envelope, the response will be a JSON containing the document identifier and the creation date, as shown in the example below:

Example response

{
"id": "3dfc5526-ee47-4b63-ad97-ddaf5b1c9110",
"created_at": "2023-01-01T00:00:00.000Z"
}

Sending the Envelope for Signature

To send the envelope for signature, make a PATCH call to the /sign/envelope/\{envelope_id\} endpoint.


curl -X PATCH \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\} \
-H "Authorization: EXAMPLE_API_KEY" \
-d '{
"status": "submitted"
}'


Envelope Submission Response

After successfully sending the envelope for signature, the response will be a JSON containing the envelope status, as shown in the example below:

Example response

{
"status": "submitted"
}

After sending the envelope for signature, signers will receive an email or a message with the link to sign the documents.

Upon accessing the link, the signer must fill in their CPF, sign the document, and undergo the facial and/or document validation flow depending on the partner's workflow. After signing, the signer will be redirected to the success page.

Querying Envelope Data

To check envelope data, such as status and signers, make a GET call to the /sign/envelope/\{envelope_id\} endpoint.


curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\} \
-H "Authorization: EXAMPLE_API_KEY"

If the request is successful, the response will be a JSON containing the envelope status and information about the signers, as shown in the example below:

Example response

{
"id": "814e7ed3-4080-4cae-a853-8e12812817ea",
"subject": "Laudo de vistoria de entrada",
"expiration_date": "2023-09-20T02:59:59Z",
"status": "completed",
"signers": [
{
"id": "1",
"name": "John Sample",
"email": "johnsample@test.com",
"birthdate": "1992-09-15",
"document_number": "111.111.111-11",
"phone": {
"international_dial_code": "55",
"area_code": "11",
"number": "988878722"
},
"document_submission_method": "email",
"authentication_submission_method": "email",
"status": "signed",
"signed_at": "2023-03-21T15:30:00.000Z",
"signature_url": "https://sign.qitech.com.br/s/s2S33dD",
"documents": [
{
"id": "8d3c3f1a-1a1a-1a1a-1a1a-1a1a1a1a1a1a",
"name": "Laudo de vistoria de entrada",
"document_type": "pdf"
}
]
}
]
}
  • The envelope status can be created, submitted, completed, canceled ou expired.
EnumeratorsDescription
createdEnvelope created
submittedEnvelope sent for signature
completedWhen all signatures for the envelope have been successfully completed
canceledEnvelope canceled at the partner's request
expiredEnvelope expired due to signature time limit
NameTypeDescription
idstringUnique identifier for the envelope.
statusstringEnvelope status.
expiration_datestringEnvelope expiration date.
signersSignerList of Signer-type objects describing the envelope's signers.
documentsDocumentList of Document-type objects describing the envelope's documents.

Webhook

When all signers finish signing and the dossier is generated, a Webhook call will be triggered. To enable this, it is necessary to configure—via the support team (suporte@qitech.com.br)—an endpoint address where we will notify updates, as well as a signature_key that will be used to sign the request.

Clients may also—though it is not recommended—use the polling technique. In this case, simply do not configure the webhook endpoint and use the registration recovery endpoints to proceed with polling.

Signature

Example of signature calculation in Python

    hmac_obj = hmac.new(signature_key.encode('utf-8'), (endpoint + method + payload).encode('utf-8'), hashlib.sha1)
return hmac_obj.hexdigest()

To ensure that the request received at the webhook endpoint originates from our servers, an HMAC signature is sent in the Signature Header, similar to the authentication process.

After calculating the expected signature value on the server side, you must compare the calculated signature with the sent one. If the signatures match, it means the request originated from our servers and is trustworthy.

Example webhook call:

{
"id": "479f8e5a-75e1-4a33-9d75-e0083e3c8e9c",
"status": "completed",
"webhook_type": "envelope_completed",
"signers": [
{
"id": "c15392dd-7859-4eae-a2b6-bf0f760a6d9b",
"biometry": {
"face_validation_available": true,
"fraud_base_flag": false,
"face_validation_score": 90
},
"liveness": {
"result": "live"
},
"document": {
"face_match_score": 85
}
}
]
}
NameTypeDescription
idstringUnique identifier for the envelope.
statusstringEnvelope status.
signer.idstringUnique identifier for the signer.
signer.biometry.face_validation_availablebooleanIndicates if the face was found and validated.
signer.biometry.fraud_base_flagbooleanIndicates if the signer's face was found in the fraud database.
signer.biometry.face_validation_scoreintegerIndicates the facial validation score.
signer.liveness.resultstringIndicates the result of the liveness validation. Possible values: live or spoof
signer.document.face_match_scoreintegerIndicates the face match validation score.

Downloading Signed Dossiers

If all signers have signed all documents in the envelope, the envelope status will be completed, and a dossier for each document, with signatures and signer data, will be available for download. To do this, make a GET call to the /sign/envelope/\{envelope_id\}/report endpoint.

  curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/report \
-H "Authorization: EXAMPLE_API_KEY"

If the request is successful, the response will be a JSON containing the envelope id and status, plus a list with the document id and the generated dossier URL, as shown in the example below:

Example response

{
"id": "479f8e5a-75e1-4a33-9d75-e0083e3c8e9c",
"status": "available",
"documents_reports": [
{
"id": "a50ef632-842e-4622-8075-684b8c83a99e",
"url": "https://qisign-dossiers.com/06abda52-5bd1-46a1-8fa2-f616ba44b395.pdf"
}
]
}
  • The report link for each document will be valid for 24 hours.
  • The status of reports for the envelope can be available or unavailable.
  • The property documents_reports contains the list of envelope documents, identified by document id and their report link.

Downloading Dossier by Signed Document

If all signers have signed all documents in the envelope, the envelope status will be completed and a dossier for each signed document, with signatures and signer data, will be available for download. To do this, make a GET to the endpoint /sign/envelope/\{envelope_id\}/document/{document_id}/report

  curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/document/{document_id}/report \
-H "Authorization: EXAMPLE_API_KEY"

If the request is successful, the response will be a JSON containing the id, status, url, and the base64 of the document dossier, as shown in the example below:

Example response

{
"id": "5b930d3d-3713-4c42-85d5-f8e9e44e30ce",
"status": "available",
"document_report_url": "https://qisign-dossiers.com/7bcf5868-784a-4356-85fb-dd72fd53cd4a.pdf",
"document_report": "vAsXDdsaGUsdIMIGxhIG1GU=..."
}
  • The link for the document report will be valid for 24 hours.
  • The status for the document report can be available or unavailable.
  • The property document_report is the document report in PDF format encoded in base64.

Downloading Signer Face Photos

It is possible to retrieve images of the signers' faces. To do this, simply make a GET call to the endpoint /sign/envelope/\{envelope_id\}/signer/\{signer_id\}/face

  curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/signer/\{signer_id\}/face \
-H "Authorization: EXAMPLE_API_KEY"

If the request is successful, the response will be a JSON containing the base64 encoded image, as shown in the example below:

Example response

{
"face_image_url": "https://qisign-face-image.com/4fd09dab-6f3e-4ff5-bfed-6f7debfcde71.jpeg"
}

Canceling an Envelope

To cancel an envelope, make a PATCH call to the endpoint /sign/envelope/\{envelope_id\}


curl -X PATCH \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\} \
-H "Authorization: EXAMPLE_API_KEY" \
-d '{
"status": "canceled"
}'


If the request is successful, the response will be a JSON containing the envelope status, as shown in the example below:

Example response

{
"status": "canceled"
}

Downloading Signer Document Photos

It is possible to retrieve images of the signers' documents. To do this, simply make a GET call to the endpoint /sign/envelope/\{envelope_id\}/signer/\{signer_id\}/personal_document

  curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/signer/\{signer_id\}/personal_document \
-H "Authorization: EXAMPLE_API_KEY"

If the request is successful, the response will be a JSON containing the base64 encoded image, as shown in the example below:

Example response

{
"document_front_url": "https://qisign-personal-documents.com/bee17d70-b029-41e2-b76b-86f64a8f9213.jpeg",
"document_back_url": "https://qisign-personal-documents.com/faf38378-daa2-47b2-9d87-0bbc1f7c744c.jpeg"
}

Checking Signer Status

To check a signer's status, make a GET call to the endpoint /sign/envelope/\{envelope_id\}/signer/\{signer_id\}


curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/signer/\{signer_id\} \
-H "Authorization: EXAMPLE_API_KEY"

If the request is successful, the response will be a JSON containing the signer's status, as shown in the example below:

Example response

{
"name": "John Sample",
"email": "johnsample@test.com",
"status": "signed",
"signed_at": "2023-03-21T15:30:00.000Z"
}
NameTypeDescription
namestringSigner's name.
emailstringSigner's email.
statusstringSigner's signature status.
signed_atstringDate and time of the last signature in YYYY-MM-DDTHH:MM:SS.000Z format.

HTTP Status Codes

A API de assinatura utilizam a seguinte padronização nos status HTTP de retorno, de acordo com o RFC 7231:

Status HTTPSignificadoDescrição
400Bad RequestThe sent request has a formatting error. In most cases, we return an explanation of where the error is in the message body.
401UnauthorizedThere was an issue with authentication; verify if the API Key is correct and in the proper header, as per the Authentication.
403ForbiddenThe accessed endpoint is for internal use and is not available for this API Key.
404Not FoundThe requested data was not found using the provided key. This status is also returned when an invalid endpoint is requested.
405Method Not AllowedThe HTTP method used does not apply to the used endpoint.
406Not AcceptableThe data sent in the request body is invalid. Generally, this means the data sent is not valid JSON.
409ConflictThe request ID corresponds to an ID already processed. This status is returned for duplicate requests sent to the server.
500Internal Server ErrorWe encountered an issue processing this request; when this error occurs, our specialists are automatically notified and immediately begin analysis and resolution.
503Service UnavailableYou have encountered an infrastructure unavailability—planned or unplanned—of our servers.