Manual QI Sign
Os webhooks da QI Tech não devem ser mapeadas de forma restrita. Campos adicionais podem ser incluídos aos payloads dos webhooks retornados em nossas APIs.
Introdução
Bem vindo à API de Assinaturas da QiTech! Esta API dá acesso ao serviço de assinatura eletrônica de documentos!
Problemas?
Caso tenha algum problema entre em contato com o nosso suporte (suporte@qitech.com.br) e nós responderemos o mais rápido possível.
Ambientes
Possuímos dois ambientes para os nossos clientes. A URL base das APIs são:
- Produção -
https://api.sign.qitech.com.br/
- Sandbox -
https://api.sandbox.sign.qitech.com.br/
Somente HTTPS
Por questão de segurança, toda a comunicação com as APIs da QI Tech devem ser realizadas utilizando a comunicação HTTPS. Para garantir que, por desatenção ou qualquer outro motivo, não ocorram chamadas HTTP, este servidor somente disponibiliza a porta 443 com comunicação TLS 1.2. Chamadas realizadas utilizando outros protocolos serão automaticamente negadas.
Autenticação
Para autenticar uma chamada, utilize o código seguinte:
# No shell, você somente precisa adicionar o header adequado em cada requisição
curl "api_endpoint_here"
-H "Authorization: EXAMPLE_API_KEY"
Substitua a API key 'EXAMPLE_API_KEY' com a sua chave adquirida com o nosso suporte.
Utilizamos uma API Key para permitir acesso a nossa API. Ela provavelmente já foi enviada por e-mail para você. Caso você ainda não tenha recebido a sua chave, envie um e-mail para suporte@qitech.com.br.
Nossa API espera receber a API Key em todas as requisições ao nosso servidor em um header como o abaixo:
Authorization: EXAMPLE_API_KEY
Envelopes são os objetos que contêm os documentos a serem assinados eletronicamente. Eles são criados a partir de um ou mais arquivos e podem ser enviados para assinatura por e-mail, SMS ou WhatsApp. Para criar um envelope, você deve enviar um arquivo ou um conjunto de arquivos para a API. O envelope será criado e você receberá um identificador único para ele.
Criando um Envelope
Para criar um Envelope, realize uma chamada POST
para o endpoint /sign/envelope
com os dados do(s) assinante(s).
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"
}
]
}'
Definição do Objeto Envelope
Todas as trocas de informação de um envelope utilizam a seguinte definição para este objeto. Em alguns casos, para facilitar a implementação e diminuir o fluxo de dados entre as partes, algumas informações poderão ser omitidas.
Nome | Tipo | Descrição |
---|---|---|
id | string | Identificador único do envelope. É essencial que este número seja único |
subject | string | Título do envelope. Aparece no assunto do email. |
expiration_date | string | Data de expiração do envelope no formato YYYY-MM-DD . |
signers | list | Lista de objetos do tipo Signer que descreve os assinantes do envelope. |
Definição do Objeto Signer
Nome | tipo | descrição |
---|---|---|
id | string | Identificador da transação do assinante. É essencial que este número seja único por envelope |
string | Endereço de e-mail do assinante. | |
name | string | Nome completo do assinante. |
birthdate | string | Data de nascimento do assinante no formato YYYY-MM-DD . |
document_number | string | Número do documento do assinante. |
phone | object | Objeto que descreve o telefone do assinante. |
phone.international_dial_code | string | Código do país do telefone do assinante. |
phone.area_code | string | Código de área do telefone do assinante. |
phone.number | string | Número do telefone do assinante. |
document_submission_method | enum | Método de envio dos documentos para assinatura. Métodos disponíveis: _email, sms e whatsapp _ |
authentication_submission_method | enum | Método de envio do token de autenticação para assinatura. Métodos disponíveis: _email, sms e whatsapp _ |
- Campo email e phone podem ser enviados juntos ou separados, mas ao menos um deles deve ser enviado.
- Todos os campos são obrigatórios.
Resposta da criação do envelope
Após o sucesso na criação do envelope, a resposta será um JSON contendo o id e status do envelope, conforme o exemplo ao lado:
Resposta exemplo
{
"id": "814e7ed3-4080-4cae-a853-8e12812817ea",
"status": "created"
}
Adicionando documentos de identificação ao assinante
Para adicionar documentos de identificação ao assinante, realize uma chamada POST
para o endpoint /sign/envelope/\{envelope_id\}/signer/\{signer_id\}/personal_document
para cada documento a ser adicionado. O arquivo deve ser enviado no corpo da requisição seguindo o seguinte formato:
{
"document_b64": "Q5YACgAAAABDlgAbAAAAAEOWAC0AAAAAQ5YAPwAAAABDlgdN...",
"template": "cnh_front",
"file_type": "jpeg"
}
Templates disponíveis
Para cada tipo de documento de identificação, é necessário informar o template correspondente. Os templates disponíveis são:
Template | Descrição |
---|---|
cnh_front | Carteira Nacional de Habilitação brasileira frente (Lado da foto). |
cnh_back | Carteira Nacional de Habilitação brasileira frente (Lado da assinatura). |
rg_front | Carteira de Identidade brasileira frente (Lado da foto). |
rg_back | Carteira de Identidade brasileira verso (Lado dos dados). |
Descrição dos Atributos de Envio
Atributo | Descrição |
---|---|
document_b64 | Documento de identificação codificado em base64. |
template | Declara o template que deve ser aplicado para análise da imagem. |
file_type | Identifica o formato do arquivo enviado, jpeg . Caso não seja enviado, o valor jpeg é assumido. |
- O tamanho máximo do documento de identificação deve ser de 10 MB
- Todos os campos são obrigatórios exceto o
file_type
.
Resposta da adição de documentos de identificação
Após o sucesso na adição de documentos de identificação, a resposta será um JSON contendo o created_at
conforme o exemplo ao lado:
Resposta exemplo
{
"created_at": "2023-01-01T00:00:00.000Z"
}
Coleta do documento de identificação
Caso não seja enviado um documento de identificação do assinante, o mesmo será solicitado para realizar a coleta no momento da assinatura.
Adicionando documentos ao envelope
Para adicionar documentos para assinatura a um envelope, realize uma chamada POST
para o endpoint /sign/envelope/\{envelope_id\}/document
para cada documento a ser adicionado. O arquivo deve ser enviado no corpo da requisição seguindo o seguinte formato:
{
"id": "3dfc5526-ee47-4b63-ad97-ddaf5b1c9110",
"document_b64": "Q5YACgAAAABDlgAbAAAAAEOWAC0AAAAAQ5YAPwAAAABDlgdN...",
"name": "Laudo de vistoria de entrada",
"document_type": "pdf"
}
- O tamanho máximo do documento deve ser de 10 MB
Definição do Objeto Document
nome | tipo | descrição |
---|---|---|
id | string | Identificador do documento. É essencial que este número seja único dentro do envelope Opcional Caso não seja informado, geraremos uma GUID no padrão UUID4 de 36 caracteres. |
document_b64 | string | Documento codificado em base64. |
name | string | Nome do documento. |
document_type | enum | Tipo do documento. Tipo disponível: pdf |
Resposta da adição de documentos ao envelope
Após o sucesso na adição de documentos ao envelope, a resposta será um JSON contendo o identificador do documento e a data de criação, conforme o exemplo abaixo:
Resposta exemplo
{
"id": "3dfc5526-ee47-4b63-ad97-ddaf5b1c9110",
"created_at": "2023-01-01T00:00:00.000Z"
}
Enviando o envelope para assinatura
Para enviar o envelope para assinatura, realize uma chamada PATCH
para o 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": "submitted"
}'
Resposta do envio do envelope para assinatura
Após o sucesso no envio do envelope para assinatura, a resposta será um JSON contendo o status do envelope, conforme o exemplo abaixo:
Resposta exemplo
{
"status": "submitted"
}
Após o envio do envelope para assinatura, os assinantes receberão um e-mail ou uma mensagem com o link para assinar os documentos.
Ao acessar o link o assinante deverá preencher o CPF, assinar o documento e realizar o fluxo de validação facial e/ou documental a depender do fluxo do parceiro. Após a assinatura, o assinante será redirecionado para a página de sucesso.
Consultando os dados do envelope
Para verificar os dados do envelope, como status e assinantes, realize uma chamada GET para o endpoint /sign/envelope/\{envelope_id\}
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\} \
-H "Authorization: EXAMPLE_API_KEY"
Caso a requisição seja bem sucedida, a resposta será um JSON contendo o status do envelope e informações sobre os assinantes, conforme a exemplo abaixo:
Resposta exemplo
{
"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"
}
]
}
]
}
- O status do envelope pode ser
created
,submitted
,completed
,canceled
ouexpired
.
enumeradores | descrição |
---|---|
created | Envelope criado |
submitted | Envelope enviado para assinatura |
completed | Quando todas as assinaturas do envelope foram concluídas com sucesso |
canceled | Envelope cancelado por solicitação do parceiro |
expired | Envelope expirado por tempo de assinatura |
nome | tipo | descrição |
---|---|---|
id | string | Identificador único do envelope. |
status | string | Status do envelope. |
expiration_date | string | Data de expiração do envelope. |
signers | Signer | Lista de objetos do tipo Signer que descreve os assinantes do envelope. |
documents | Document | Lista de objetos do tipo Document que descreve os documentos do envelope. |
Webhook
Ao final da assinatura por todos os assinantes e geração do dossiê, será disparada uma chamada por meio de Webhook. Para tanto, é necessário, por meio da equipe do suporte (suporte@qitech.com.br), configurar um endereço do endpoint por onde vamos notificar as atualizações e também uma signature_key que será utilizada para assinar a requisição.
O cliente pode, apesar de não recomendável, também utilizar a técnica de polling. Neste caso, basta não configurar o endpoint de webhook e utilizar os endpoints de recuperação de cadastro para proceder com o polling.
Assinatura
Exemplo de cálculo de assinatura em Python
hmac_obj = hmac.new(signature_key.encode('utf-8'), (endpoint + method + payload).encode('utf-8'), hashlib.sha1)
return hmac_obj.hexdigest()
Para garantir que a requisição recebida no endpoint do webhook parte dos nossos servidores, uma assinatura HMAC é enviada no Header Signature, semelhante ao processo de autenticação.
Após realizar o cálculo do valor esperado da assinatura do lado do servidor, é necessário comparar a assinatura calculada com a enviada. Caso as assinaturas sejam compatíveis, isso significa que a requisição partiu dos nossos servidores e que é confiável.
Exemplo de chamada webhook:
{
"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
}
}
]
}
nome | tipo | descrição |
---|---|---|
id | string | Identificador único do envelope. |
status | string | Status do envelope. |
signer.id | string | Identificador único do assinante. |
signer.biometry.face_validation_available | boolean | Indica se o rosto foi encontrado e validado. |
signer.biometry.fraud_base_flag | boolean | Indica se o rosto do assinante foi encontrado na base de fraude. |
signer.biometry.face_validation_score | integer | Indica o score da validação facial. |
signer.liveness.result | string | Indica o resultado da validação de liveness. Valores possíveis live ou spoof |
signer.document.face_match_score | integer | Indica o score da validação de face match. |
Baixando os dossiês assinados
Caso todos os assinantes tenham assinado todos os documentos do envelope, o status do envelope será completed
e um dossiê para cada documento, com as assinaturas e dados dos assinantes estará disponível para download. Para isso, realize uma chamada GET
para o endpoint /sign/envelope/\{envelope_id\}/report
curl -X GET \
https://api.sign.qitech.com.br/sign/envelope/\{envelope_id\}/report \
-H "Authorization: EXAMPLE_API_KEY"
Caso a requisição seja bem sucedida, a resposta será um JSON contendo o id e status do envelope, além de uma lista com id do documento e a url do dossiê gerado, conforme o exemplo abaixo:
Resposta exemplo
{
"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"
}
]
}
- O link do relatório para cada documento terá validade de 24 horas.
- O status dos relatórios para o envelope pode ser
available
ouunavailable
. - A propriedade
documents_reports
contem a lista dos documentos do envelope, identificados pelo id do documento e o link do seu relatório.
Baixando o dossiê por documento assinado
Caso todos os assinantes tenham assinado todos os documentos do envelope, o status do envelope será completed
e um dossiê para cada documento assinado, com as assinaturas e dados dos assinantes estará disponível para download. Para isso, realize uma chamada GET
para o 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"
Caso a requisição seja bem sucedida, a resposta será um JSON contendo id, status, url e o base64 do dossiê do documento, conforme o exemplo abaixo:
Resposta exemplo
{
"id": "5b930d3d-3713-4c42-85d5-f8e9e44e30ce",
"status": "available",
"document_report_url": "https://qisign-dossiers.com/7bcf5868-784a-4356-85fb-dd72fd53cd4a.pdf",
"document_report": "vAsXDdsaGUsdIMIGxhIG1GU=..."
}
- O link para o relatório do documento terá validade de 24 horas.
- O status para o relatório do documento pode ser
available
ouunavailable
. - A propriedade
document_report
é o relatório do documento em PDF codificado em base64.
Baixando as fotos do rosto dos assinantes
É possível recuperar as imagens do rosto dos assinantes. Para isso basta realizar um chamada GET
para o 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"
Caso a requisição seja bem sucedida, a resposta será um JSON contendo a imagem codificada em base64, conforme o exemplo abaixo:
Resposta exemplo
{
"face_image_url": "https://qisign-face-image.com/4fd09dab-6f3e-4ff5-bfed-6f7debfcde71.jpeg"
}
Cancelando um envelope
Para cancelar um envelope, realize uma chamada PATCH
para o 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"
}'
Caso a requisição seja bem sucedida, a resposta será um JSON contendo o status do envelope, conforme o exemplo abaixo:
Resposta exemplo
{
"status": "canceled"
}
Baixando as fotos do documento dos assinantes
É possível recuperar as imagens do documento dos assinantes. Para isso basta realizar um chamada GET
para o 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"
Caso a requisição seja bem sucedida, a resposta será um JSON contendo a imagem codificada em base64, conforme o exemplo abaixo:
Resposta exemplo
{
"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"
}
Consultando o status de um assinante
Para verificar o status de um assinante, realize uma chamada GET para o 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"
Caso a requisição seja bem sucedida, a resposta será um JSON contendo o status do assinante, conforme a exemplo abaixo:
Resposta exemplo
{
"name": "John Sample",
"email": "johnsample@test.com",
"status": "signed",
"signed_at": "2023-03-21T15:30:00.000Z"
}
nome | tipo | descrição |
---|---|---|
name | string | Nome do assinante. |
string | E-mail do assinante. | |
status | string | Status da assinatura assinante. |
signed_at | string | Data e hora da última assinatura no formato YYYY-MM-DDTHH:MM:SS.000Z . |
Status HTTP
A API de assinatura utilizam a seguinte padronização nos status HTTP de retorno, de acordo com o RFC 7231:
Status HTTP | Significado | Descrição |
---|---|---|
400 | Bad Request | A requisição enviada possui algum erro de formatação. Na maioria dos casos, retornamos no corpo da mensagem uma explicação de onde está o erro. |
401 | Unauthorized | Houve algum problema na autenticação, verifique se a API Key está correta e no header correto, de acordo com a seção Autenticação. |
403 | Forbidden | O endpoint acessado é de uso interno e não está disponível para esta API Key. |
404 | Not Found | O dado requisitado não foi encontrado usando a chave utilizada. Este status também é retornado quando um endpoint inválido é requisitado. |
405 | Method Not Allowed | O método HTTP utilizado não se aplica ao endpoint utilizado. |
406 | Not Acceptable | Os dados enviados no corpo da requisição são inválidos. Em geral, isso significa que os dados enviados não são um JSON válido. |
409 | Conflict | O id da requisição corresponde a um id já processado anteriormente. Este status é retornado no caso de requisições duplicadas enviadas ao servidor. |
500 | Internal Server Error | Tivemos um problema para processar esta requisição, ao encontrarmos esse erro nossos especialistas são automaticamente notificados e iniciam a análise e solução imediatamente. |
503 | Service Unavailable | Você se deparou com uma indisponibilidade, planejada ou não, de infraestrutura dos nossos servidores. |