> For the complete documentation index, see [llms.txt](https://docs.autentique.com.br/api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.autentique.com.br/api/2/mutations/criando-um-documento.md).

# Criando um Documento

A criação de documentos difere um pouco das outras *mutations* por ter o **upload de um arquivo**. Primeiramente, vamos precisar escrever a *mutation:*

<pre class="language-graphql"><code class="lang-graphql"><strong>mutation CreateDocumentMutation(
</strong>  $document: DocumentInput!, # Definição das variáveis $document,
  $signers: [SignerInput!]!, # $signers e $file, com seus respectivos
  $file: Upload!             # tipos. (Os "!" indicam que são
<strong>) {                          # parâmetros obrigatórios)      
</strong>  createDocument(
    document: $document,     # Passa para os parâmetros da mutation o 
    signers: $signers,       # valor das variáveis.
    file: $file,             #
    organization_id: 123,    # OPCIONAL: Cria em outras organizações do usuário, senão usa a atual
    folder_id: "a1b2c3"      # OPCIONAL: Cria arquivado em uma pasta
  ) {
    id
    name
    refusable
    sortable
    created_at
    signatures {
      public_id
      name
      email
      created_at
      action { name }
      link { short_link }
      user { id name email }
    }
  }
}
</code></pre>

{% hint style="info" %}
O tamanho máximo do documento é de 5MB no plano gratuito e 20MB no plano profissional!
{% endhint %}

\
Após, precisamos dos valores das variáveis definidas na *mutation* em um JSON:

```json
/*
  Abaixo, um signatário receberá o link de assinatura por email,
  por ter sido passado o "email" e, para o que passou "name",
  será retornado o atributo "link" no documento com o link de
  assinatura.
  Quando usado "phone", existirão duas possíveis formas de envio,
  especificadas no uso do atributo "delivery_method". Este atributo
  possui as opções "DELIVERY_METHOD_WHATSAPP" para enviar por Whatsapp
  e "DELIVERY_METHOD_SMS" para enviar por SMS.
*/

{
  "document": {
    "name": "Contrato de marketing"
  },
  "signers": [{
    "email": "troque-esse-email-que-e-publico@example.com",
    "action": "SIGN"
  }, {
    "name": "Ronaldo Fuzinato",
    "action": "SIGN"
  }, {
    "phone": "+5554999999999",
    "delivery_method": "DELIVERY_METHOD_WHATSAPP",
    "action": "SIGN"
  }, {
    "phone": "+5554999999998",
    "delivery_method": "DELIVERY_METHOD_SMS",
    "action": "SIGN"
  },
  
  
/*
 Também há como gerar links de assinatura vinculado a um numero de celular 
 ou para um email. Assim o link gerado só pode ser assinado pelo endereço associado.
*/  
  {
    "name": "João Maria",
    "phone": "+5554999999998",
    "delivery_method": "DELIVERY_METHOD_LINK",
    "action": "SIGN"
  },{
    "name": "Maria João",
    "email": "troque-esse-email-que-e-publico@example.com",
    "delivery_method": "DELIVERY_METHOD_LINK",
    "action": "SIGN"
  }
  
  ]
}
```

Percebeu que não foi colocado nenhum valor para a variável *$file*? Pois é, como é realizado o *upload* desse arquivo, a requisição precisa ser enviada como *multipart/form-data*, dessa forma o arquivo precisa ser um pouco diferente. Você pode fazer isso direto no [Altair](https://altair.autentique.com.br):

![](/files/-LzJ8_DMjvVWNNW2rfQ3)

{% hint style="warning" %}
Caso você esteja em dúvida de como funciona o envio do documento para usar na sua integração, este repositório fornece mais informações e exemplos de como fazer o upload: <https://github.com/jaydenseric/graphql-multipart-request-spec>
{% endhint %}

### Criando documento em Sandbox

Nossa API também suporta o envio de documento de teste, que não consomem créditos de documentos, assim facilitando a integração para quem ainda não adquiriu um plano com documentos ilimitados. Para saber como faz acesse nossa [página de sandbox](/api/2/integracao/sandbox-testes.md).

### Mais opções

```json
// IMPORTANTE:
// - Se você copiar esse JSON, remova os comentários antes de usar
// - Alguns dos atributos abaixo não irão funcionar sem possuir um plano corporativo
// - Alguns dos atributos abaixo irão consumir créditos de verificação adicional

{
  "document": {
    "name": "Contrato de marketing",
    "message": "Mensagem customizada enviada para os emails dos signatários",
    "reminder": "WEEKLY", // Lembrete de assinatura semanal. DAILY para diário
    "whatsapp_template": "STANDARD", //Seleciona o template de WhatsApp. Aceita também os valores FORMAL, CASUAL e DIRECT 
    "sortable": true, // Signatários assinam na ordem do array "signers"
    "footer": "BOTTOM", // Adiciona rodapé. Aceita também os valores LEFT e RIGHT
    "refusable": true, // Permite recusa do documento
    "qualified": true, // Ativa assinatura qualificada, usando certificados
    "scrolling_required": true, // Só permite a assinatura do documento caso o signatário tiver rolado toda a página
    "stop_on_rejected": true, // Impede que outras pessoas assinem quando recusado
    "new_signature_style": true, // Ativa novos campos de assinatura
    "show_audit_page": false, // Evita criar a última página de auditoria em documentos com "new_signature_style": true
    "ignore_cpf": true, // Remove obrigatoriedade de preencher CPF para assinar e removere qualquer referência a CPF na interface da plataforma
    "ignore_birthdate": true // Remove obrigatoriedade de preencher a data de nascimento e remove qualquer referencia da data de nascimento na interface da plataforma 
    "email_template_id": 1234, // Usa modelo de email específico, pelo ID do mesmo
    "deadline_at": "2023-11-24T02:59:59.999Z", // Bloqueia assinaturas após data
    "reply_to": "troque-esse-email-que-e-publico@example.com", //Define o endereço de e-mail para o qual as respostas devem ser enviadas.
    "cc": [
      // Envia emails quando o documento for assinado por todos os signatários
      { "email": "email-cc-1@example.com" },
      { "email": "email-cc-2@example.com" }
    ],
    "expiration": {
      // Envia um lembrete em uma quantidade de dias "days_before antes do
      // vencimento do documento informada no "notify_at"
      "days_before": 7,
      "notify_at": "20/01/2026"
    },
    "configs": {
      "notification_finished": true, // Envia um email notificando todos os signatários que o documento foi assinado por todas as partes
      "notification_signed": true, // Envia um email ao signatário notificando que ele assinou o documento
      "signature_appearance": "ELETRONIC", // Força a aparência da assinatura, pode ser: DRAW, HANDWRITING, ELETRONIC, IMAGE
      "keep_metadata": true, // Mantém os metadados do PDF em assinatura qualificada
      "lock_user_data": true, // Mantém os dados do usuário desatualizados, mostrando os que foram usados ao assinar
      "pdfa": true // Mantem a versão e o tipo do PDF/A anexado. 
      // Quanto "pdfa" ativo, modifica o parâmetro new_signature_style para true.
      // Obs.: Não converte um documento para PDF/A.
    },
    "locale": {
      "country": "BR", // Qualquer país no formato ISO3166, se não informado, assume-se `BR`
      // *IMPORTANTE* A criação de documentos não brasileiros possui os seguintes pontos: 
      // - Signatários com método de envio SMS não são suportados. Nesses casos, 
      // a requisição retorna o erro: `sms_delivery_not_allowed_on_foreign_documents`;
      // - Os campos `new_signature_style` e `ignore_cpf` são marcados como `true`;
      // - Elementos de CPF posicionados nas páginas do documento são ignorados;
      // - Verificações adicionais do SERPRO e via SMS são ignoradas.
      "language": "pt-BR", // Pode ser: `pt-BR` ou `en-US`, se não informado, assume-se `pt-BR`
      "timezone": "America/Sao_Paulo", // DateTimeZone com todas as timezones, se não informado, assume-se `America/Sao_Paulo`
      // Uma lista completa pode ser encontrada em: https://www.php.net/manual/en/datetimezone.listidentifiers.php
      "date_format": "DD_MM_YYYY", // Enum, pode ser: DD_MM_YYYY ou MM_DD_YYYY, se não informado, assume-se `DD_MM_YYYY`
    } 
  },
  "signers": [{
    "email": "troque-esse-email-que-e-publico@example.com", // Envia email
    "action": "SIGN", // Assinar
    "configs": { "cpf": "12345678900" }, // Valida o CPF do signatário
    "security_verifications": [
      // Exigir validação por SMS ("verify_phone" é opcional):
      { "type": "SMS", "verify_phone": "+5554999999999" },
      // Exigir documento com foto (Aprovação manual):
      { "type": "MANUAL" }
    ],
    // Posiciona campos de assinatura:
    "positions": [{"x": "5.0", "y": "90.0", "z": 1, "element": "SIGNATURE"}]
  }, {
    "name": "Ronaldo Fuzinato", // Recebe link de assinatura para enviar
    "action": "SIGN_AS_A_WITNESS", // Assinar como testemunha
    // Exigir documento com foto (Documento com foto):
    "security_verifications": [{ "type": "UPLOAD" }],
    // Posiciona campos para nome do signatário:
    "positions": [{"x": "75.0", "y": "90.0", "z": 1, "element": "NAME"}]
  }, {
    "email": "troque-esse-email-que-e-publico-2@example.com", // Envia email
    "action": "APPROVE", // Aprovar
    // Exigir documento com foto (Documento, selfie e prova de vida):
    "security_verifications": [{ "type": "LIVE" }],
    // Posiciona campos de rúbrica:
    "positions": [{"x": "25.0", "y": "90.0", "z": 1, "element": "INITIALS"}]
  }, {
    "phone": "+5521999999999",
    "delivery_method": "DELIVERY_METHOD_SMS", // Envia SMS para "phone"
    "action": "RECOGNIZE", // Reconhecer
    // Exigir documento com foto (Biometria SERPRO):
    "security_verifications": [{ "type": "PF_FACIAL" }],
    // Posiciona campos de data de assinatura:
    "positions": [{"x": "55.0", "y": "90.0", "z": 1, "element": "DATE"}]
  }, {
    "phone": "+5521999999998",
    "delivery_method": "DELIVERY_METHOD_WHATSAPP", // Envia Whatsapp para "phone"
    "action": "SIGN", // Assinar
    // Posiciona campos de CPF:
    "positions": [{"x": "55.0", "y": "90.0", "z": 1, "element": "CPF"}]
  }]
}
```

### &#x20;Validações adicionais

Você pode implementar validações adicionais em seus documentos. Estas configurações devem ser inseridas na lista `security_verifications` do objeto do signatário, utilizando o campo `type` para definir a modalidade de desafio desejada. Além dos tipos, campos como `verify_phone` e `cpf` auxiliam na entrega dos códigos de segurança e na identificação precisa da parte.

| Campo / Tipo de Verificação     | Como funciona                                                                                                                                                                                                                               |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `verify_phone`                  | O signatário precisará validar um número de celular através de um código enviado por SMS. Você pode preencher o número ou deixar em branco para que o próprio signatário informe                                                            |
| `cpf`                           | Configuração que garante que apenas o signatário com o CPF especificado possa assinar o documento. Se definido, o sistema obriga o preenchimento ou validação desse dado na conta do signatário.                                            |
| `MANUAL`                        | O signatário anexará um documento de identificação com foto, e tirará uma selfie. Você ou algum membro da sua organização poderão aprovar ou rejeitar os documentos e selfie enviados.                                                      |
| `UPLOAD`                        | O signatário precisará anexar frente e verso de um documento de identificação com foto, com seu smartphone ou computador.                                                                                                                   |
| `LIVE`                          | O signatário precisará anexar um documento de identificação com foto, tirar uma selfie com seu smartphone e realizar uma prova de vida. A foto do documento será automaticamente comparada com a selfie para verificar o grau de semelhança |
| `PF_FACIAL`                     | O signatário tira uma selfie que é validada pelo SERPRO, comparando-a com as fotos de registro do governo brasileiro vinculadas ao CPF informado                                                                                            |
| `BIOMETRIC_AND_TEXT_EXTRACTION` | O signatário precisará fotografar um documento de identificação e tirar uma selfie, a foto do documento será comparada com a selfie para determinar o grau de semelhança.                                                                   |
| `LIVENESS_AND_TEXT_EXTRACTION`  | O signatário precisará realizar uma prova de vida e fotografar um documento de identificação com foto. As informações do documento serão extraídas automaticamente e comparadas para verificar o grau de semelhança.                        |

<details>

<summary>Posicionar campos de assinatura "positions"</summary>

Como mostrado no exemplo acima, para adicionar campos de assinatura ao criar o documento você precisa adicionar o atributo "positions".

```json
{
  ...
  "signers": [
    {
      ...
      "positions": [
        { "x": "100.0", "y": "100.0", "z": 1, "angle": 0, "scale": 1.0, "element": "SIGNATURE" }
      ]
    }
  ]
}
```

O `"x"` é posição horizontal de 0 a 100%\
﻿O `"y"` é posição vertical de 0 a 100%\
﻿O `"z"` é o número da página começando no 1\
O `"angle"` é a rotação aplicada ao elemento, de 0 a 360 graus.\
O `"scale"` é o tamanho do elemento, de 0.5 a 4.0, padrão é 1.0.

﻿O `"element"` é o tipo de assinatura:\
﻿`"SIGNATURE"`: Assinatura\
`"NAME"`: Nome do signatário\
`"INITIALS"`: Rúbrica\
`"DATE"`: Data de assinatura\
`"CPF"`: CPF do signatário

Pra saber quais posições passar no x e y, você pode criar um documento de exemplo no painel do Autentique e buscar as posições ao resgatar o documento usando "positions":

```graphql
query {
  document(id: "ID_DO_DOCUMENTO") {
    id
    signatures {
      public_id
      positions {
        element
        x
        y
        z
      }
    }
  }
}
```

</details>

<details>

<summary>Exigir verificação por SMS e/ou documento com foto "security_verifications"</summary>

Para exigir dos signatários a verificação por SMS e/ou documento com foto, é preciso adicionar o atributo `"security_verifications"` no signatário que você deseja que essas verificações sejam necessárias. Lembrando que você deve consultar no painel o custo de créditos de verificação adicionais necessários.

```json
{
  ...
  "signers": [
    {
      ...
      "security_verifications": [
        { "type": "SMS", "verify_phone": "+5554999999999" },
        { "type": "MANUAL" }
      ]﻿
    },
    {
      ...
      "security_verifications": [
        { "type": "BIOMETRIC_AND_TEXT_EXTRACTION" }
      ]﻿
    },
    {
      ...
      "security_verifications": [
        { "type": "BIOMETRIC_AND_TEXT_EXTRACTION", "fallback_behavior": "DISABLE_FALLBACK" }
      ]﻿
    }
  ]﻿
}
```

\
﻿O `"type"` é o tipo de verificação:\
﻿`"SMS"`: Validação por SMS (`"verify_phone"` é opcional e exige celular especificado)\
`"MANUAL"`: Exigir documento com foto (Aprovação manual)\
`"UPLOAD"`: Exigir documento com foto (Documento com foto)\
`"LIVE"`: Exigir documento com foto (Documento, selfie e prova de vida)\
`"PF_FACIAL"`: Exigir documento com foto (Biometria SERPRO)\
"`BIOMETRIC_AND_TEXT_EXTRACTION"`: Exigir documento com foto (Documento com foto e facematch)

Apesar de ser possível ter múltiplas verificações para o mesmo signatário, dentre as seguintes opções somente é possível escolher uma delas por signatário: `MANUAL`, `UPLOAD`, `LIVE` e `PF_FACIAL`.

Quando utilizar os tipos `UPLOAD`, `LIVE`, `PF_FACIAL` e `BIOMETRIC_AND_TEXT_EXTRACTION` , há o comportamento padrão de serem alterados para `MANUAL` quando o signatário exceder a quantidade máxima de tentativas no processo de validação documental.\
Para desativar esse comportamento é necessário utilizar o parâmetro `fallback_behavior`, que acusará falha no documento e o rejeitará automaticamente.&#x20;

</details>

<details>

<summary>Criar documento a partir de modelo</summary>

Não há uma forma na API de você conseguir usar os modelos do painel para criar documentos, porém você consegue fazer algo parecido à partir do seu código:

1. Criar um modelo fixo em HTML na máquina, demarcando os lugares com variáveis para substituir por valores. (Ex: "Eu, $NomeSignatario$ aceito esse contrato")
2. Por código, duplicar esse HTML e nessa duplicata, substituir os campos de variáveis pelos valores reais. ( Ex: $NomeSignatario$ => Jorge Silva )﻿
3. Enviar esse arquivo HTML com os valores substituídos para a nossa API, através da mutation *createDocument*, igual como já funciona para outros tipos de arquivos

</details>

<details>

<summary>Exemplo de criação de documento com NodeJS</summary>

Se você usa o Postman, você pode gerar esses exemplos à partir da collection para o Postman disponibilizada aqui na [documentação](/api/2/master.md).

```javascript
var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('operations', '{"query":"mutation CreateDocumentMutation($document: DocumentInput!, $signers: [SignerInput!]!, $file: Upload!) {createDocument(document: $document, signers: $signers, file: $file) {id name refusable sortable created_at signatures { public_id name email created_at action { name } link { short_link } user { id name email }}}}", "variables":{"document": {"name": "Contrato de teste"},"signers": [{"email": "troque-esse-email-que-e-publico@example.com","action": "SIGN"}],"file":null}}');
data.append('map', '{"file": ["variables.file"]}');
data.append('file', fs.createReadStream('/path/to/file'));
var config = {
  method: 'post',
  url: 'https://api.autentique.com.br/v2/graphql',
  headers: {
    'Authorization': 'Bearer TOKEN_DE_API',
    ...data.getHeaders()
  },
  data : data
};
axios(config)
  .then(function(response) { console.log(JSON.stringify(response.data)); })
  .catch(function(error) { console.log(error); });
```

Desse exemplo é só substituir o **token de API**, **email do signatário** e **caminho para o arquivo**.

</details>

<details>

<summary>Exemplo de criação de documento com PHP</summary>

Se você usa o Postman, você pode gerar esses exemplos à partir da collection para o Postman disponibilizada aqui na [documentação](/api/2/master.md).

```php
<?php

$curl = curl_init();
curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.autentique.com.br/v2/graphql',
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array('operations' => '{"query":"mutation CreateDocumentMutation($document: DocumentInput!, $signers: [SignerInput!]!, $file: Upload!) {createDocument(document: $document, signers: $signers, file: $file) {id name refusable sortable created_at signatures { public_id name email created_at action { name } link { short_link } user { id name email }}}}", "variables":{"document": {"name": "Contrato de teste"},"signers": [{"email": "troque-esse-email-que-e-publico@example.com","action": "SIGN"}],"file":null}}','map' => '{"file": ["variables.file"]}','file'=> new CURLFILE('/path/to/file')),
  CURLOPT_HTTPHEADER => array('Authorization: Bearer TOKEN_DE_API'),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
```

Desse exemplo é só substituir o **token de API**, **email do signatário** e **caminho para o arquivo**.

</details>

<details>

<summary>Exemplo de criação de documento com Python3</summary>

Se você usa o Postman, você pode gerar esses exemplos à partir da collection para o Postman disponibilizada aqui na [documentação](/api/2/master.md).

```python
import requests

url = "https://api.autentique.com.br/v2/graphql"
payload = {
  'operations': '{"query":"mutation CreateDocumentMutation($document: DocumentInput!, $signers: [SignerInput!]!, $file: Upload!) {createDocument(document: $document, signers: $signers, file: $file) {id name refusable sortable created_at signatures { public_id name email created_at action { name } link { short_link } user { id name email }}}}", "variables":{"document": {"name": "Contrato de teste"},"signers": [{"email": "troque-esse-email-que-e-publico@example.com","action": "SIGN"}],"file":null}}',
  'map': '{"file": ["variables.file"]}'
}
files = [
  ('file',open('/path/to/file.pdf','rb'))
]
headers = {
  'Authorization': 'Bearer TOKEN_DE_API'
}

response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
```

Desse exemplo é só substituir o **token de API**, **email do signatário** e **caminho para o arquivo**.

</details>

<details>

<summary>Exemplo de criação de documento com C#</summary>

Se você usa o Postman, você pode gerar esses exemplos à partir da collection para o Postman disponibilizada aqui na [documentação](/api/2/master.md).

```csharp
var client = new RestClient("https://api.autentique.com.br/v2/graphql");
var request = new RestRequest(Method.POST);

request.AddHeader("Authorization", "Bearer TOKEN_DE_API");
request.AddParameter("operations", "{\"query\":\"mutation CreateDocumentMutation($document: DocumentInput!, $signers: [SignerInput!]!, $file: Upload!) {createDocument(document: $document, signers: $signers, file: $file) {id name refusable sortable created_at signatures { public_id name email created_at action { name } link { short_link } user { id name email }}}}\", \"variables\":{\"document\": {\"name\": \"Contrato de teste\"},\"signers\": [{\"email\": \"troque-esse-email-que-e-publico@example.com\",\"action\": \"SIGN\"}],\"file\":null}}");
request.AddParameter("map", "{\"file\": [\"variables.file\"]}");
request.AddFile("file", "/path/to/file");
IRestResponse response = client.Execute(request);

Console.WriteLine(response.Content);
```

Desse exemplo é só substituir o **token de API**, **email do signatário** e **caminho para o arquivo**.

</details>

{% hint style="info" %}
Você pode conferir o que é cada um desses parâmetros direto na documentação completa da API GraphQL, no menu Docs do [Altair](https://altair.autentique.com.br). Se você não sabe como fazer isso, confira o nosso tutorial em [Usando o Altair](/api/2/integracao/altair.md).
{% endhint %}

{% file src="/files/-M03o9cE5QB3vLoPUlzJ" %}
Para importar e usar no Postman
{% endfile %}
