Create a signature request
Uploads a PDF, places signer-owned signature/text fields on it using normalized (0–1) coordinates, and returns one hosted signing link per signer. Requests support one to ten parallel signers. Every field must name its signer key when more than one signer is present. Completed artifacts are certificate-sealed after hardening is enabled. Each signer can receive the request by SMS or WhatsApp, or use the returned signing link.
curl --request POST \
--url https://api.example.com/v4/signatures \
--header 'Content-Type: application/json' \
--header 'x-meetergo-api-user-id: <api-key>' \
--data '
{
"name": "Order confirmation",
"file": "JVBERi0xLjcKJ...",
"fields": [
{
"name": "signature",
"areas": [
{
"x": 0.1,
"y": 0.8,
"w": 0.3,
"h": 0.08,
"page": 1
}
],
"signerKey": "customer",
"type": "signature"
}
],
"signers": [
{
"key": "customer",
"email": "john.doe@example.com",
"name": "John Doe",
"role": "First Party",
"deliveryChannel": "sms",
"phone": "+491723099442"
}
],
"expiresAt": "2026-12-31T23:59:59.000Z",
"language": "de",
"completedRedirectUrl": "https://app.example.com/contracts/123/signed",
"requireOtp": true,
"sendSignedCopyToSigners": true,
"automaticReminders": true,
"whatsappTemplateName": "signature_invitation",
"whatsappTemplateLanguage": "de"
}
'import requests
url = "https://api.example.com/v4/signatures"
payload = {
"name": "Order confirmation",
"file": "JVBERi0xLjcKJ...",
"fields": [
{
"name": "signature",
"areas": [
{
"x": 0.1,
"y": 0.8,
"w": 0.3,
"h": 0.08,
"page": 1
}
],
"signerKey": "customer",
"type": "signature"
}
],
"signers": [
{
"key": "customer",
"email": "john.doe@example.com",
"name": "John Doe",
"role": "First Party",
"deliveryChannel": "sms",
"phone": "+491723099442"
}
],
"expiresAt": "2026-12-31T23:59:59.000Z",
"language": "de",
"completedRedirectUrl": "https://app.example.com/contracts/123/signed",
"requireOtp": True,
"sendSignedCopyToSigners": True,
"automaticReminders": True,
"whatsappTemplateName": "signature_invitation",
"whatsappTemplateLanguage": "de"
}
headers = {
"x-meetergo-api-user-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-meetergo-api-user-id': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Order confirmation',
file: 'JVBERi0xLjcKJ...',
fields: [
{
name: 'signature',
areas: [{x: 0.1, y: 0.8, w: 0.3, h: 0.08, page: 1}],
signerKey: 'customer',
type: 'signature'
}
],
signers: [
{
key: 'customer',
email: 'john.doe@example.com',
name: 'John Doe',
role: 'First Party',
deliveryChannel: 'sms',
phone: '+491723099442'
}
],
expiresAt: '2026-12-31T23:59:59.000Z',
language: 'de',
completedRedirectUrl: 'https://app.example.com/contracts/123/signed',
requireOtp: true,
sendSignedCopyToSigners: true,
automaticReminders: true,
whatsappTemplateName: 'signature_invitation',
whatsappTemplateLanguage: 'de'
})
};
fetch('https://api.example.com/v4/signatures', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v4/signatures",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Order confirmation',
'file' => 'JVBERi0xLjcKJ...',
'fields' => [
[
'name' => 'signature',
'areas' => [
[
'x' => 0.1,
'y' => 0.8,
'w' => 0.3,
'h' => 0.08,
'page' => 1
]
],
'signerKey' => 'customer',
'type' => 'signature'
]
],
'signers' => [
[
'key' => 'customer',
'email' => 'john.doe@example.com',
'name' => 'John Doe',
'role' => 'First Party',
'deliveryChannel' => 'sms',
'phone' => '+491723099442'
]
],
'expiresAt' => '2026-12-31T23:59:59.000Z',
'language' => 'de',
'completedRedirectUrl' => 'https://app.example.com/contracts/123/signed',
'requireOtp' => true,
'sendSignedCopyToSigners' => true,
'automaticReminders' => true,
'whatsappTemplateName' => 'signature_invitation',
'whatsappTemplateLanguage' => 'de'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-meetergo-api-user-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v4/signatures"
payload := strings.NewReader("{\n \"name\": \"Order confirmation\",\n \"file\": \"JVBERi0xLjcKJ...\",\n \"fields\": [\n {\n \"name\": \"signature\",\n \"areas\": [\n {\n \"x\": 0.1,\n \"y\": 0.8,\n \"w\": 0.3,\n \"h\": 0.08,\n \"page\": 1\n }\n ],\n \"signerKey\": \"customer\",\n \"type\": \"signature\"\n }\n ],\n \"signers\": [\n {\n \"key\": \"customer\",\n \"email\": \"john.doe@example.com\",\n \"name\": \"John Doe\",\n \"role\": \"First Party\",\n \"deliveryChannel\": \"sms\",\n \"phone\": \"+491723099442\"\n }\n ],\n \"expiresAt\": \"2026-12-31T23:59:59.000Z\",\n \"language\": \"de\",\n \"completedRedirectUrl\": \"https://app.example.com/contracts/123/signed\",\n \"requireOtp\": true,\n \"sendSignedCopyToSigners\": true,\n \"automaticReminders\": true,\n \"whatsappTemplateName\": \"signature_invitation\",\n \"whatsappTemplateLanguage\": \"de\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-meetergo-api-user-id", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v4/signatures")
.header("x-meetergo-api-user-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Order confirmation\",\n \"file\": \"JVBERi0xLjcKJ...\",\n \"fields\": [\n {\n \"name\": \"signature\",\n \"areas\": [\n {\n \"x\": 0.1,\n \"y\": 0.8,\n \"w\": 0.3,\n \"h\": 0.08,\n \"page\": 1\n }\n ],\n \"signerKey\": \"customer\",\n \"type\": \"signature\"\n }\n ],\n \"signers\": [\n {\n \"key\": \"customer\",\n \"email\": \"john.doe@example.com\",\n \"name\": \"John Doe\",\n \"role\": \"First Party\",\n \"deliveryChannel\": \"sms\",\n \"phone\": \"+491723099442\"\n }\n ],\n \"expiresAt\": \"2026-12-31T23:59:59.000Z\",\n \"language\": \"de\",\n \"completedRedirectUrl\": \"https://app.example.com/contracts/123/signed\",\n \"requireOtp\": true,\n \"sendSignedCopyToSigners\": true,\n \"automaticReminders\": true,\n \"whatsappTemplateName\": \"signature_invitation\",\n \"whatsappTemplateLanguage\": \"de\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v4/signatures")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-meetergo-api-user-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Order confirmation\",\n \"file\": \"JVBERi0xLjcKJ...\",\n \"fields\": [\n {\n \"name\": \"signature\",\n \"areas\": [\n {\n \"x\": 0.1,\n \"y\": 0.8,\n \"w\": 0.3,\n \"h\": 0.08,\n \"page\": 1\n }\n ],\n \"signerKey\": \"customer\",\n \"type\": \"signature\"\n }\n ],\n \"signers\": [\n {\n \"key\": \"customer\",\n \"email\": \"john.doe@example.com\",\n \"name\": \"John Doe\",\n \"role\": \"First Party\",\n \"deliveryChannel\": \"sms\",\n \"phone\": \"+491723099442\"\n }\n ],\n \"expiresAt\": \"2026-12-31T23:59:59.000Z\",\n \"language\": \"de\",\n \"completedRedirectUrl\": \"https://app.example.com/contracts/123/signed\",\n \"requireOtp\": true,\n \"sendSignedCopyToSigners\": true,\n \"automaticReminders\": true,\n \"whatsappTemplateName\": \"signature_invitation\",\n \"whatsappTemplateLanguage\": \"de\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"name": "<string>",
"schemaVersion": 123,
"revision": 123,
"status": "pending",
"signers": [
{
"id": "<string>",
"status": "pending",
"signingUrl": "https://cal.meetergo.com/s/V1StGXR8_Z5jdHi6B-myT",
"email": "<string>",
"name": "<string>",
"role": "<string>",
"key": "<string>",
"invitationDelivery": {
"channel": "email",
"status": "pending",
"phone": "<string>",
"templateName": "<string>",
"templateLanguage": "<string>",
"sentAt": "<string>",
"failureCode": "<string>"
},
"openedAt": "2023-11-07T05:31:56Z",
"completedAt": "2023-11-07T05:31:56Z"
}
],
"automaticReminders": true,
"createdAt": "2023-11-07T05:31:56Z",
"signedDocumentUrl": "<string>",
"completedAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z"
}{
"statusCode": 400,
"message": [
"limit must not be greater than 100"
],
"error": "BadRequestException"
}{
"statusCode": 400,
"message": [
"limit must not be greater than 100"
],
"error": "BadRequestException"
}{
"statusCode": 400,
"message": [
"limit must not be greater than 100"
],
"error": "BadRequestException"
}Authorizations
User ID to act on behalf of. Platform API Keys only (required with an API Key unless the endpoint states otherwise). Requests authenticated with a Personal Access Token are rejected if this header names another user.
Body
Document / submission name.
200"Order confirmation"
The source PDF, base64-encoded (max 20 MB decoded).
"JVBERi0xLjcKJ..."
Fields to place on the document. Areas use normalized (0–1) coordinates with a top-left origin and 1-indexed pages — the same model as DocuSeal.
1Show child attributes
Show child attributes
One to ten parallel signers.
1 - 10 elementsShow child attributes
Show child attributes
ISO-8601 timestamp after which signing links stop working.
"2026-12-31T23:59:59.000Z"
Signing-page language. Supported: "en", "de". Defaults to English.
en, de "de"
URL the signer is sent to after completing (DocuSeal completed_redirect_url).
"https://app.example.com/contracts/123/signed"
Require email OTP verification. This expresses the FES intent and requires the Suite plan or above.
true
Email every signer the finished document when the request completes. Defaults to true. Set false when you distribute the signed document yourself.
true
Send unfinished signers a reminder every three days, up to three reminders.
true
Approved WhatsApp template name used by signers whose delivery channel is WhatsApp.
200"signature_invitation"
Language code of the selected WhatsApp template.
35"de"
Response
Signature request created with its signer links.
Signature request id.
Document name.
Persisted envelope schema version.
Current request revision.
Overall status.
pending, in_progress, finalizing, finalization_failed, completed, cancelled The signers and their signing links.
Show child attributes
Show child attributes
Whether automatic reminders are enabled.
Creation time.
Time-limited download URL for the signed (audit-paged, cryptographically signed) PDF. Present once status is "completed".
When all signers completed.
When signing links expire (null = never).
curl --request POST \
--url https://api.example.com/v4/signatures \
--header 'Content-Type: application/json' \
--header 'x-meetergo-api-user-id: <api-key>' \
--data '
{
"name": "Order confirmation",
"file": "JVBERi0xLjcKJ...",
"fields": [
{
"name": "signature",
"areas": [
{
"x": 0.1,
"y": 0.8,
"w": 0.3,
"h": 0.08,
"page": 1
}
],
"signerKey": "customer",
"type": "signature"
}
],
"signers": [
{
"key": "customer",
"email": "john.doe@example.com",
"name": "John Doe",
"role": "First Party",
"deliveryChannel": "sms",
"phone": "+491723099442"
}
],
"expiresAt": "2026-12-31T23:59:59.000Z",
"language": "de",
"completedRedirectUrl": "https://app.example.com/contracts/123/signed",
"requireOtp": true,
"sendSignedCopyToSigners": true,
"automaticReminders": true,
"whatsappTemplateName": "signature_invitation",
"whatsappTemplateLanguage": "de"
}
'import requests
url = "https://api.example.com/v4/signatures"
payload = {
"name": "Order confirmation",
"file": "JVBERi0xLjcKJ...",
"fields": [
{
"name": "signature",
"areas": [
{
"x": 0.1,
"y": 0.8,
"w": 0.3,
"h": 0.08,
"page": 1
}
],
"signerKey": "customer",
"type": "signature"
}
],
"signers": [
{
"key": "customer",
"email": "john.doe@example.com",
"name": "John Doe",
"role": "First Party",
"deliveryChannel": "sms",
"phone": "+491723099442"
}
],
"expiresAt": "2026-12-31T23:59:59.000Z",
"language": "de",
"completedRedirectUrl": "https://app.example.com/contracts/123/signed",
"requireOtp": True,
"sendSignedCopyToSigners": True,
"automaticReminders": True,
"whatsappTemplateName": "signature_invitation",
"whatsappTemplateLanguage": "de"
}
headers = {
"x-meetergo-api-user-id": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-meetergo-api-user-id': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Order confirmation',
file: 'JVBERi0xLjcKJ...',
fields: [
{
name: 'signature',
areas: [{x: 0.1, y: 0.8, w: 0.3, h: 0.08, page: 1}],
signerKey: 'customer',
type: 'signature'
}
],
signers: [
{
key: 'customer',
email: 'john.doe@example.com',
name: 'John Doe',
role: 'First Party',
deliveryChannel: 'sms',
phone: '+491723099442'
}
],
expiresAt: '2026-12-31T23:59:59.000Z',
language: 'de',
completedRedirectUrl: 'https://app.example.com/contracts/123/signed',
requireOtp: true,
sendSignedCopyToSigners: true,
automaticReminders: true,
whatsappTemplateName: 'signature_invitation',
whatsappTemplateLanguage: 'de'
})
};
fetch('https://api.example.com/v4/signatures', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v4/signatures",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Order confirmation',
'file' => 'JVBERi0xLjcKJ...',
'fields' => [
[
'name' => 'signature',
'areas' => [
[
'x' => 0.1,
'y' => 0.8,
'w' => 0.3,
'h' => 0.08,
'page' => 1
]
],
'signerKey' => 'customer',
'type' => 'signature'
]
],
'signers' => [
[
'key' => 'customer',
'email' => 'john.doe@example.com',
'name' => 'John Doe',
'role' => 'First Party',
'deliveryChannel' => 'sms',
'phone' => '+491723099442'
]
],
'expiresAt' => '2026-12-31T23:59:59.000Z',
'language' => 'de',
'completedRedirectUrl' => 'https://app.example.com/contracts/123/signed',
'requireOtp' => true,
'sendSignedCopyToSigners' => true,
'automaticReminders' => true,
'whatsappTemplateName' => 'signature_invitation',
'whatsappTemplateLanguage' => 'de'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-meetergo-api-user-id: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v4/signatures"
payload := strings.NewReader("{\n \"name\": \"Order confirmation\",\n \"file\": \"JVBERi0xLjcKJ...\",\n \"fields\": [\n {\n \"name\": \"signature\",\n \"areas\": [\n {\n \"x\": 0.1,\n \"y\": 0.8,\n \"w\": 0.3,\n \"h\": 0.08,\n \"page\": 1\n }\n ],\n \"signerKey\": \"customer\",\n \"type\": \"signature\"\n }\n ],\n \"signers\": [\n {\n \"key\": \"customer\",\n \"email\": \"john.doe@example.com\",\n \"name\": \"John Doe\",\n \"role\": \"First Party\",\n \"deliveryChannel\": \"sms\",\n \"phone\": \"+491723099442\"\n }\n ],\n \"expiresAt\": \"2026-12-31T23:59:59.000Z\",\n \"language\": \"de\",\n \"completedRedirectUrl\": \"https://app.example.com/contracts/123/signed\",\n \"requireOtp\": true,\n \"sendSignedCopyToSigners\": true,\n \"automaticReminders\": true,\n \"whatsappTemplateName\": \"signature_invitation\",\n \"whatsappTemplateLanguage\": \"de\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-meetergo-api-user-id", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v4/signatures")
.header("x-meetergo-api-user-id", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Order confirmation\",\n \"file\": \"JVBERi0xLjcKJ...\",\n \"fields\": [\n {\n \"name\": \"signature\",\n \"areas\": [\n {\n \"x\": 0.1,\n \"y\": 0.8,\n \"w\": 0.3,\n \"h\": 0.08,\n \"page\": 1\n }\n ],\n \"signerKey\": \"customer\",\n \"type\": \"signature\"\n }\n ],\n \"signers\": [\n {\n \"key\": \"customer\",\n \"email\": \"john.doe@example.com\",\n \"name\": \"John Doe\",\n \"role\": \"First Party\",\n \"deliveryChannel\": \"sms\",\n \"phone\": \"+491723099442\"\n }\n ],\n \"expiresAt\": \"2026-12-31T23:59:59.000Z\",\n \"language\": \"de\",\n \"completedRedirectUrl\": \"https://app.example.com/contracts/123/signed\",\n \"requireOtp\": true,\n \"sendSignedCopyToSigners\": true,\n \"automaticReminders\": true,\n \"whatsappTemplateName\": \"signature_invitation\",\n \"whatsappTemplateLanguage\": \"de\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v4/signatures")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-meetergo-api-user-id"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Order confirmation\",\n \"file\": \"JVBERi0xLjcKJ...\",\n \"fields\": [\n {\n \"name\": \"signature\",\n \"areas\": [\n {\n \"x\": 0.1,\n \"y\": 0.8,\n \"w\": 0.3,\n \"h\": 0.08,\n \"page\": 1\n }\n ],\n \"signerKey\": \"customer\",\n \"type\": \"signature\"\n }\n ],\n \"signers\": [\n {\n \"key\": \"customer\",\n \"email\": \"john.doe@example.com\",\n \"name\": \"John Doe\",\n \"role\": \"First Party\",\n \"deliveryChannel\": \"sms\",\n \"phone\": \"+491723099442\"\n }\n ],\n \"expiresAt\": \"2026-12-31T23:59:59.000Z\",\n \"language\": \"de\",\n \"completedRedirectUrl\": \"https://app.example.com/contracts/123/signed\",\n \"requireOtp\": true,\n \"sendSignedCopyToSigners\": true,\n \"automaticReminders\": true,\n \"whatsappTemplateName\": \"signature_invitation\",\n \"whatsappTemplateLanguage\": \"de\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"name": "<string>",
"schemaVersion": 123,
"revision": 123,
"status": "pending",
"signers": [
{
"id": "<string>",
"status": "pending",
"signingUrl": "https://cal.meetergo.com/s/V1StGXR8_Z5jdHi6B-myT",
"email": "<string>",
"name": "<string>",
"role": "<string>",
"key": "<string>",
"invitationDelivery": {
"channel": "email",
"status": "pending",
"phone": "<string>",
"templateName": "<string>",
"templateLanguage": "<string>",
"sentAt": "<string>",
"failureCode": "<string>"
},
"openedAt": "2023-11-07T05:31:56Z",
"completedAt": "2023-11-07T05:31:56Z"
}
],
"automaticReminders": true,
"createdAt": "2023-11-07T05:31:56Z",
"signedDocumentUrl": "<string>",
"completedAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z"
}{
"statusCode": 400,
"message": [
"limit must not be greater than 100"
],
"error": "BadRequestException"
}{
"statusCode": 400,
"message": [
"limit must not be greater than 100"
],
"error": "BadRequestException"
}{
"statusCode": 400,
"message": [
"limit must not be greater than 100"
],
"error": "BadRequestException"
}