Creating a document

To create a document/send a document for signature

Creating documents differs slightly from other mutations because it involves uploading a file. First, we need to write the mutation:

mutation CreateDocumentMutation(
  $document: DocumentInput!, # Definition of the $document variable
  $signers: [SignerInput!]!, # $signers and $file, with its respective
  $file: Upload!             # types. (The "!" indicate that are
) {                          # mandatory parameters)      
  createDocument(
    document: $document,     # Pass the variable values to the mutation parameters
    signers: $signers,       # 
    file: $file,             #
    organization_id: 123,    # OPTIONAL: Creates in other user organizations, otherwise uses the current one
    folder_id: "a1b2c3"      # OPtIONAL: Creates archived in a folder
  ) {
    id
    name
    refusable
    sortable
    created_at
    signatures {
      public_id
      name
      email
      created_at
      action { name }
      link { short_link }
      user { id name email }
    }
  }
}

Next, we need the values of the variables defined in the mutation in a JSON:

/*
 Below, a signer will receive the signature link by email when the "email" field is provided, for a signer added with "name", the "link" attribute will be returned in the document with the signature link.
When using "phone", there are two possible delivery methods defined by the "delivery_method" attribute:
"DELIVERY_METHOD_WHATSAPP" to send via WhatsApp and "DELIVERY_METHOD_SMS" to send via SMS.
*/

{
  "document": {
    "name": "Marketing contract"
  },
  "signers": [{
    "email": "[email protected]",
    "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"
  }]
}

Notice that no value has been provided for the $file variable? That's because since the file is being uploaded, the request needs to be sent as multipart/form-data, so the file must be handled a bit differently. You can do this directly in Altair:

Creating documents on Sandbox

Our API also supports sending test documents, which do not consume document credits, making integration easier for those who have not yet acquired a plan with unlimited documents. To learn how to do this, visit our sandbox page.

More options:

// IMPORTANT:
// - If you copy this JSON, remove the comments before using it
// - Some of the attributes below will not work without a corporate plan
// - Some of the attributes below will consume additional verification credits

{
  "document": {
    "name": "Marketing contract",
    "message": "Custom message sent to the signer's email",
    "reminder": "WEEKLY", // Weekly signature reminder. DAILY to daily reminder
    "sortable": true, // Signers sign on the array order "signers"
    "footer": "BOTTOM", // Adds footer. Also accepts the values LEFT and RIGHT
    "refusable": true, // Allows document rejection
    "qualified": true, // Enables qualified signature using certificates
    "scrolling_required": true, // Only allows document signing if the signer has scrolled through the entire page
    "stop_on_rejected": true, // Prevents others from signing when rejected
    "new_signature_style": true, // Enables new signature fields
    "show_audit_page": false, // Prevents creating the last audit page in documents with "new_signature_style": true
    "ignore_cpf": true, // Removes the requirement to fill in CPF to sign and removes any reference to CPF in the platform interface
    "ignore_birthdate": true // Removes the requirement to fill in the date of birth and removes any reference to the date of birth in the platform interface
    "email_template_id": 1234, // Uses a specific email template by its ID
    "deadline_at": "2023-11-24T02:59:59.999Z", // Blocks signatures after date
    "cc": [
      // Sends emails when the document is signed by all signers
      { "email": "[email protected]" },
      { "email": "[email protected]" }
    ],
    "expiration": {
      // Sends a reminder "days_before" days before the document’s due date specified in "notify_at"
      "days_before": 7,
      "notify_at": "20/01/2026"
    },
    "configs": {
      "notification_finished": true, // Sends an email notifying all signers that the document has been signed by all parties
      "notification_signed": true, // Sends an email to the signer notifying that they signed the document
      "signature_appearance": "ELETRONIC", // Forces the signature appearance, can be: DRAW, HANDWRITING, ELECTRONIC, IMAGE
      "keep_metadata": true, // Keeps PDF metadata in qualified signature
      "lock_user_data": true // Keeps outdated user data, showing the information used at the time of signing
    },
    "locale": {
      "country": "BR", // Any country in ISO3166 format, if not provided, defaults to BR
// IMPORTANT The creation of non-Brazilian documents has the following points:
// - Signers with SMS delivery method are not supported. In these cases,
// the request returns the error: sms_delivery_not_allowed_on_foreign_documents;
// - The fields new_signature_style and ignore_cpf are set to true;
// - CPF elements placed on the document pages are ignored;
// - Additional verifications from SERPRO and via SMS are ignored.
      "language": "pt-BR", // Can be: pt-BR or en-US, if not provided, defaults to pt-BR
      "timezone": "America/Sao_Paulo", // DateTimeZone with all time zones, if not provided, defaults to America/Sao_Paulo
// A complete list can be found at: https://www.php.net/manual/en/datetimezone.listidentifiers.php
      "date_format": "DD_MM_YYYY", // Enum, can be: DD_MM_YYYY or MM_DD_YYYY, if not provided, defaults to DD_MM_YYYY
    } 
  },
  "signers": [{
    "email": "[email protected]", // Envia email
    "action": "SIGN", // Sign
    "configs": { "cpf": "12345678900" }, // Validates the cpf of the signer
    "security_verifications": [
      // Require SMS verification ("verify_phone" is optional):
      { "type": "SMS", "verify_phone": "+5554999999999" },
      // Require photo ID (Manual approval)
      { "type": "MANUAL" }
    ],
    //Positions signature fields:
    "positions": [{"x": "5.0", "y": "90.0", "z": 1, "element": "SIGNATURE"}]
  }, {
    "name": "Ronaldo Fuzinato", // Receives signature links to send
    "action": "SIGN_AS_A_WITNESS", // Sign as a witness
    // Require photo ID (Photo ID)
    "security_verifications": [{ "type": "UPLOAD" }],
    // Position fields for name of the signer
    "positions": [{"x": "75.0", "y": "90.0", "z": 1, "element": "NAME"}]
  }, {
    "email": "[email protected]", // Send email
    "action": "APPROVE", // Approve
    // Require photo ID (Document, selfie, and liveness check)
    "security_verifications": [{ "type": "LIVE" }],
    // Positions initials fields
    "positions": [{"x": "25.0", "y": "90.0", "z": 1, "element": "INITIALS"}]
  }, {
    "phone": "+5521999999999",
    "delivery_method": "DELIVERY_METHOD_SMS", // Send SMS to "phone"
    "action": "RECOGNIZE", // Acknowledge
    // Demand Photo ID (SERPRO biometrics):
    "security_verifications": [{ "type": "PF_FACIAL" }],
    // Position fields of signature date:
    "positions": [{"x": "55.0", "y": "90.0", "z": 1, "element": "DATE"}]
  }, {
    "phone": "+5521999999998",
    "delivery_method": "DELIVERY_METHOD_WHATSAPP", // Sends whatsapp to "phone"
    "action": "SIGN", // Sign
    // Position CPF fields:
    "positions": [{"x": "55.0", "y": "90.0", "z": 1, "element": "CPF"}]
  }]
}

Positioning signature fields "positions"

As shown in the example above, to add signature fields when creating the document, you need to include the "positions" attribute.

{
  ...
  "signers": [
    {
      ...
      "positions": [
        { "x": "100.0", "y": "100.0", "z": 1, "element": "SIGNATURE" }
      ]
    }
  ]
}

The “x” value represents the horizontal position, ranging from 0% to 100%. The “y” value represents the vertical position, also ranging from 0% to 100%. The “z” value indicates the page number, starting at 1.

O "element" It's the type of signature "SIGNATURE": Signature "NAME": Signer's name "INITIALS": Initials "DATE": Signature date "CPF": Signer CPF

To know what positions to pass for x and y, you can create a sample document in the Autentique dashboard and retrieve the positions by fetching the document using "positions":

query {
  document(id: "DOCUMENT_ID") {
    id
    signatures {
      public_id
      positions {
        element
        x
        y
        z
      }
    }
  }
}
Require SMS verification and/or photo document verification "security_verifications"

To require signers to verify via SMS and/or photo document, you need to add the "security_verifications" attribute to the signer for whom these verifications should be required. Remember to check in the dashboard for the cost of additional verification credits needed.

{
  ...
  "signers": [
    {
      ...
      "security_verifications": [
        { "type": "SMS", "verify_phone": "+5554999999999" },
        { "type": "MANUAL" }
      ]
    }
  ]
}

The "type" is the type of verification:

  • "SMS": SMS validation ("verify_phone" is optional and requires a specified phone number)

  • "MANUAL": Require a photo document (manual approval)

  • "UPLOAD": Require a photo document (photo document)

  • "LIVE": Require a photo document (document, selfie, and proof of life)

  • "PF_FACIAL": Require a photo document (SERPRO biometric verification)

While it's possible to have multiple verifications for the same signer, you can only choose one of the following options per signer: MANUAL, UPLOAD, LIVE, and PF_FACIAL.

Create a document from a template

There is no way in the API to directly use the panel templates to create documents. However, you can achieve something similar through your code:

  1. Create a fixed HTML template on your machine, marking the places with variables to be replaced by values. (e.g., "I, $NomeSignatario$, accept this contract")

  2. Programmatically duplicate this HTML and in the duplicate, replace the variable fields with the actual values. (e.g., $NomeSignatario$ → Jorge Silva)

  3. Send this HTML file with the replaced values to our API through the createDocument mutation, just like it works for other types of files.

Example of document creation with NodeJS

If you use Postman, you can generate these examples from the Postman collection provided here in the documentation.

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": "Test contract"},"signers": [{"email": "[email protected]","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 API_TOKEN',
    ...data.getHeaders()
  },
  data : data
};
axios(config)
  .then(function(response) { console.log(JSON.stringify(response.data)); })
  .catch(function(error) { console.log(error); });

For this example, just replace the API token, the signer's email, and the file path.

Example of document creation with PHP

If you use Postman, you can generate these examples from the Postman collection provided here in the documentation documentation.

<?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": "[email protected]","action": "SIGN"}],"file":null}}','map' => '{"file": ["variables.file"]}','file'=> new CURLFILE('/path/to/file')),
  CURLOPT_HTTPHEADER => array('Authorization: Bearer API_TOKEN'),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;

In this example, you just need to replace the API token, the signer's email, and the file path.

Example of document creation with Python3

If you use Postman, you can generate these examples from the Postman collection provided here in the documentation documentation.

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": "Test contract"},"signers": [{"email": "[email protected]","action": "SIGN"}],"file":null}}',
  'map': '{"file": ["variables.file"]}'
}
files = [
  ('file',open('/path/to/file.pdf','rb'))
]
headers = {
  'Authorization': 'Bearer API_TOKEN'
}

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

In this example, you just need to replace the API token, the signer's email, and the file path.

Example of document creation with C#

If you use Postman, you can generate these examples from the Postman collection provided here in the documentation documentation.

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

request.AddHeader("Authorization", "Bearer API_TOKEN");
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\": \"[email protected]\",\"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);

In this example, you just need to replace the API token, the signer's email, and the file path.

You can check what each of these parameters means directly in the full GraphQL API documentation, in the Docs menu of Altair. If you're not sure how to do that, check out our tutorial on Using Altair.

Para importar e usar no Postman

Last updated

Was this helpful?